diff --git a/backend/app_sdk/app_base.py b/backend/app_sdk/app_base.py index ff341920..a5e52921 100644 --- a/backend/app_sdk/app_base.py +++ b/backend/app_sdk/app_base.py @@ -327,13 +327,36 @@ class AppBase: print("BEFORE VARIABLES!") if len(baseresult) == 0: - print("Variables: %s" % execution_data["workflow"]["workflow_variables"]) - for variable in execution_data["workflow"]["workflow_variables"]: - variablename = variable["name"].replace(" ", "_", -1).lower() + try: + print("WF Variables: %s" % execution_data["workflow"]["workflow_variables"]) + for variable in execution_data["workflow"]["workflow_variables"]: + variablename = variable["name"].replace(" ", "_", -1).lower() - if variablename.lower() == actionname_lower: - baseresult = variable["value"] - break + if variablename.lower() == actionname_lower: + baseresult = variable["value"] + break + except KeyError as e: + print("KeyError wf variables: %s" % e) + pass + except TypeError as e: + print("TypeError wf variables: %s" % e) + pass + + print("BEFORE EXECUTION VAR") + if len(baseresult) == 0: + try: + print("Execution Variables: %s" % execution_data["execution_variables"]) + for variable in execution_data["execution_variables"]: + variablename = variable["name"].replace(" ", "_", -1).lower() + if variablename.lower() == actionname_lower: + baseresult = variable["value"] + break + except KeyError as e: + print("KeyError exec variables: %s" % e) + pass + except TypeError as e: + print("TypeError exec variables: %s" % e) + pass except KeyError as error: print(f"KeyError in JSON: {error}") @@ -421,10 +444,33 @@ class AppBase: if parameter["variant"] == "WORKFLOW_VARIABLE": - for item in fullexecution["workflow"]["workflow_variables"]: - if parameter["action_field"] == item["name"]: - parameter["value"] = item["value"] - break + print("Handling workflow variable") + found = False + try: + for item in fullexecution["workflow"]["workflow_variables"]: + if parameter["action_field"] == item["name"]: + found = True + parameter["value"] = item["value"] + break + except KeyError as e: + print("KeyError WF variable 1: %s" % e) + pass + except TypeError as e: + print("TypeError WF variables 1: %s" % e) + pass + + if not found: + try: + for item in fullexecution["execution_variables"]: + if parameter["action_field"] == item["name"]: + parameter["value"] = item["value"] + break + except KeyError as e: + print("KeyError WF variable 2: %s" % e) + pass + except TypeError as e: + print("TypeError WF variables 2: %s" % e) + pass elif parameter["variant"] == "ACTION_RESULT": # FIXME - calculate value based on action_field and $if prominent diff --git a/backend/go-app/docker.go b/backend/go-app/docker.go index 4aaab56f..c42348bc 100644 --- a/backend/go-app/docker.go +++ b/backend/go-app/docker.go @@ -191,13 +191,14 @@ func buildImageMemory(fs billy.Filesystem, tags []string, dockerfileFolder strin ) //log.Printf("IMAGERESPONSE: %#v", imageBuildResponse.Body) + defer imageBuildResponse.Body.Close() + _, newerr := io.Copy(os.Stdout, imageBuildResponse.Body) + if newerr != nil { + log.Printf("Failed reading Docker build STDOUT: %s", newerr) + } + if err != nil { // Read the STDOUT from the build process - defer imageBuildResponse.Body.Close() - _, newerr := io.Copy(os.Stdout, imageBuildResponse.Body) - if newerr != nil { - log.Printf("Failed reading Docker build STDOUT: %s", newerr) - } return err } diff --git a/backend/go-app/main.go b/backend/go-app/main.go index d719b4c9..cf54d043 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -2148,7 +2148,7 @@ func getApikey(ctx context.Context, apikey string) (User, error) { var users []User _, err := dbclient.GetAll(ctx, q, &users) if err != nil { - log.Printf("Error getting users apikey: %s", err) + log.Printf("Error getting users apikey (getapikey): %s", err) return User{}, err } @@ -5969,7 +5969,7 @@ func runInit(ctx context.Context) { var users []User _, err = dbclient.GetAll(ctx, q, &users) if err != nil { - log.Printf("Error getting users apikey: %s", err) + log.Printf("Error getting users apikey (runinit): %s", err) } else { if len(users) == 0 { log.Printf("No active users found - setting ALL to active") @@ -6030,6 +6030,7 @@ func runInit(ctx context.Context) { } else { log.Printf("Setting up %d schedule(s)", len(schedules)) for _, schedule := range schedules { + //log.Printf("Schedule: %#v", schedule) job := func() { request := &http.Request{ Method: "POST", diff --git a/backend/go-app/walkoff.go b/backend/go-app/walkoff.go index 14fd6336..2499c225 100644 --- a/backend/go-app/walkoff.go +++ b/backend/go-app/walkoff.go @@ -138,8 +138,7 @@ type WorkflowAppAction struct { ID string `json:"id" datastore:"id"` Name string `json:"name" datastore:"name"` Value string `json:"value" datastore:"value"` - } `json:"execution_variables" datastore:"execution_variables"` - + } `json:"execution_variable" datastore:"execution_variables"` Returns struct { Description string `json:"description" datastore:"returns" yaml:"description,omitempty"` ID string `json:"id" datastore:"id" yaml:"id,omitempty"` @@ -149,41 +148,53 @@ type WorkflowAppAction struct { // FIXME: Generate a callback authentication ID? type WorkflowExecution struct { - Type string `json:"type" datastore:"type"` - Status string `json:"status" datastore:"status"` - Start string `json:"start" datastore:"start"` - ExecutionArgument string `json:"execution_argument" datastore:"execution_argument"` - ExecutionId string `json:"execution_id" datastore:"execution_id"` - WorkflowId string `json:"workflow_id" datastore:"workflow_id"` - LastNode string `json:"last_node" datastore:"last_node"` - Authorization string `json:"authorization" datastore:"authorization"` - Result string `json:"result" datastore:"result,noindex"` - StartedAt int64 `json:"started_at" datastore:"started_at"` - CompletedAt int64 `json:"completed_at" datastore:"completed_at"` - ProjectId string `json:"project_id" datastore:"project_id"` - Locations []string `json:"locations" datastore:"locations"` - Workflow Workflow `json:"workflow" datastore:"workflow,noindex"` - Results []ActionResult `json:"results" datastore:"results,noindex"` + Type string `json:"type" datastore:"type"` + Status string `json:"status" datastore:"status"` + Start string `json:"start" datastore:"start"` + ExecutionArgument string `json:"execution_argument" datastore:"execution_argument"` + ExecutionId string `json:"execution_id" datastore:"execution_id"` + WorkflowId string `json:"workflow_id" datastore:"workflow_id"` + LastNode string `json:"last_node" datastore:"last_node"` + Authorization string `json:"authorization" datastore:"authorization"` + Result string `json:"result" datastore:"result,noindex"` + StartedAt int64 `json:"started_at" datastore:"started_at"` + CompletedAt int64 `json:"completed_at" datastore:"completed_at"` + ProjectId string `json:"project_id" datastore:"project_id"` + Locations []string `json:"locations" datastore:"locations"` + Workflow Workflow `json:"workflow" datastore:"workflow,noindex"` + Results []ActionResult `json:"results" datastore:"results,noindex"` + ExecutionVariables []struct { + Description string `json:"description" datastore:"description"` + ID string `json:"id" datastore:"id"` + Name string `json:"name" datastore:"name"` + Value string `json:"value" datastore:"value"` + } `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"` } // Added environment for location to execute type Action struct { - AppName string `json:"app_name" datastore:"app_name"` - AppVersion string `json:"app_version" datastore:"app_version"` - AppID string `json:"app_id" datastore:"app_id"` - Errors []string `json:"errors" datastore:"errors"` - ID string `json:"id" datastore:"id"` - IsValid bool `json:"is_valid" datastore:"is_valid"` - IsStartNode bool `json:"isStartNode" datastore:"isStartNode"` - Sharing bool `json:"sharing" datastore:"sharing"` - PrivateID string `json:"private_id" datastore:"private_id"` - Label string `json:"label" datastore:"label"` - SmallImage string `json:"small_image" datastore:"small_image,noindex" required:false yaml:"small_image"` - LargeImage string `json:"large_image" datastore:"large_image,noindex" yaml:"large_image" required:false` - Environment string `json:"environment" datastore:"environment"` - Name string `json:"name" datastore:"name"` - Parameters []WorkflowAppActionParameter `json:"parameters" datastore: "parameters,noindex"` - Position struct { + AppName string `json:"app_name" datastore:"app_name"` + AppVersion string `json:"app_version" datastore:"app_version"` + AppID string `json:"app_id" datastore:"app_id"` + Errors []string `json:"errors" datastore:"errors"` + ID string `json:"id" datastore:"id"` + IsValid bool `json:"is_valid" datastore:"is_valid"` + IsStartNode bool `json:"isStartNode" datastore:"isStartNode"` + Sharing bool `json:"sharing" datastore:"sharing"` + PrivateID string `json:"private_id" datastore:"private_id"` + Label string `json:"label" datastore:"label"` + SmallImage string `json:"small_image" datastore:"small_image,noindex" required:false yaml:"small_image"` + LargeImage string `json:"large_image" datastore:"large_image,noindex" yaml:"large_image" required:false` + Environment string `json:"environment" datastore:"environment"` + Name string `json:"name" datastore:"name"` + Parameters []WorkflowAppActionParameter `json:"parameters" datastore: "parameters,noindex"` + ExecutionVariable struct { + Description string `json:"description" datastore:"description"` + ID string `json:"id" datastore:"id"` + Name string `json:"name" datastore:"name"` + Value string `json:"value" datastore:"value"` + } `json:"execution_variable,omitempty" datastore:"execution_variable,omitempty"` + Position struct { X float64 `json:"x" datastore:"x"` Y float64 `json:"y" datastore:"y"` } `json:"position"` @@ -265,7 +276,7 @@ type Workflow struct { ID string `json:"id" datastore:"id"` Name string `json:"name" datastore:"name"` Value string `json:"value" datastore:"value"` - } `json:"execution_variables" datastore:"execution_variables"` + } `json:"execution_variables,omitempty" datastore:"execution_variables,omitempty"` } type ActionResult struct { @@ -796,13 +807,20 @@ func handleWorkflowQueue(resp http.ResponseWriter, request *http.Request) { } if found { - // FIXME - this is broken, but why - //if workflowExecution.Results[outerindex].Status == actionResult.Status { - // log.Printf("Status of %s is already %s", actionResult.Action.ID, actionResult.Status) - // resp.WriteHeader(401) - // resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Status of %s is already %s"}`, actionResult.Action.ID, actionResult.Status))) - // return - //} + // If result exists and execution variable exists, update execution value + //log.Printf("Exec var backend: %s", workflowExecution.Results[outerindex].Action.ExecutionVariable.Name) + actionVarName := workflowExecution.Results[outerindex].Action.ExecutionVariable.Name + // Finds potential execution arguments + if len(actionVarName) > 0 { + log.Printf("EXECUTION VARIABLE LOCAL: %s", actionVarName) + for index, execvar := range workflowExecution.ExecutionVariables { + if execvar.Name == actionVarName { + // Sets the value for the variable + workflowExecution.ExecutionVariables[index].Value = actionResult.Result + break + } + } + } log.Printf("Updating %s in %s from %s to %s", actionResult.Action.ID, workflowExecution.ExecutionId, workflowExecution.Results[outerindex].Status, actionResult.Status) workflowExecution.Results[outerindex] = actionResult @@ -1013,6 +1031,7 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) { if len(newActions) == 0 { log.Printf("APPENDING NEW APP FOR NEW WORKFLOW") + // Adds the Testing app if it's a new workflow workflowapps, err := getAllWorkflowApps(ctx) if err == nil { for _, item := range workflowapps { @@ -1046,7 +1065,7 @@ func setNewWorkflow(resp http.ResponseWriter, request *http.Request) { } } } else { - log.Printf("Has actions already?") + log.Printf("Has %d actions already", len(newActions)) } workflow.Actions = newActions @@ -1412,6 +1431,8 @@ func saveWorkflow(resp http.ResponseWriter, request *http.Request) { "0ca8887e-b4af-4e3e-887c-87e9d3bc3d3e", } + log.Printf("%s Action execution var: %s", action.Label, action.ExecutionVariable.Name) + builtin := false for _, id := range reservedApps { if id == action.AppID { @@ -1935,6 +1956,8 @@ func handleExecution(id string, workflow Workflow, request *http.Request) (Workf // Status for the entire workflow. workflowExecution.Status = "EXECUTING" } + + workflowExecution.ExecutionVariables = workflow.ExecutionVariables // Local authorization for this single workflow used in workers. // FIXME: Used for cloud @@ -2095,7 +2118,6 @@ func executeWorkflow(resp http.ResponseWriter, request *http.Request) { } func stopSchedule(resp http.ResponseWriter, request *http.Request) { - log.Printf("Delete?") cors := handleCors(resp, request) if cors { return @@ -2262,20 +2284,19 @@ func stopScheduleGCP(resp http.ResponseWriter, request *http.Request) { func deleteSchedule(ctx context.Context, id string) error { log.Printf("Should stop schedule %s!", id) - //newscheduler "github.com/carlescere/scheduler" - log.Printf("Schedules: %#v", scheduledJobs) - if value, exists := scheduledJobs[id]; exists { - log.Printf("STOP THIS ONE: %s", value) - // Looks like this does the trick? Hurr - value.Lock() - err := DeleteKey(ctx, "schedules", id) - if err != nil { - log.Printf("Failed to delete schedule: %s", err) - return err - } + err := DeleteKey(ctx, "schedules", id) + if err != nil { + log.Printf("Failed to delete schedule: %s", err) + return err } else { - // FIXME - allow it to kind of stop anyway? - return errors.New("Can't find the schedule.") + if value, exists := scheduledJobs[id]; exists { + log.Printf("STOP THIS ONE: %s", value) + // Looks like this does the trick? Hurr + value.Lock() + } else { + // FIXME - allow it to kind of stop anyway? + return errors.New("Can't find the schedule.") + } } return nil @@ -2717,7 +2738,7 @@ func deleteUser(resp http.ResponseWriter, request *http.Request) { var users []User _, err := dbclient.GetAll(ctx, q, &users) if err != nil { - log.Printf("Error getting users apikey: %s", err) + log.Printf("Error getting users apikey (deleteuser): %s", err) resp.WriteHeader(401) resp.Write([]byte(`{"success": false, "reason": "Failed getting users for verification"}`)) return diff --git a/docker-compose.yml b/docker-compose.yml index ba3a495b..288063bb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: frontend: - build: ./frontend + #build: ./frontend image: frikky/shuffle:frontend container_name: shuffle-frontend hostname: shuffle-frontend @@ -14,7 +14,7 @@ services: depends_on: - backend backend: - build: ./backend + #build: ./backend image: frikky/shuffle:backend container_name: shuffle-backend hostname: ${BACKEND_HOSTNAME} diff --git a/frontend/src/Admin.js b/frontend/src/Admin.js index 8e25f77f..06f14f64 100644 --- a/frontend/src/Admin.js +++ b/frontend/src/Admin.js @@ -43,7 +43,7 @@ const Admin = (props) => { console.log("INPUT: ", data) // Just use this one? - const url = globalUrl+'/api/v1/workflows/'+data["workflow_id datastore:"]+"/schedule/"+data.id + const url = globalUrl+'/api/v1/workflows/'+data["workflow_id"]+"/schedule/"+data.id console.log("URL: ", url) fetch(url, { method: 'DELETE', @@ -54,6 +54,7 @@ const Admin = (props) => { }) .then(response => response.json().then(responseJson => { + console.log("RESP: ", responseJson) if (responseJson["success"] === false) { alert.error("Failed stopping schedule") } else { diff --git a/frontend/src/AngularWorkflow.js b/frontend/src/AngularWorkflow.js index 61c2428c..c7eb31a1 100644 --- a/frontend/src/AngularWorkflow.js +++ b/frontend/src/AngularWorkflow.js @@ -112,6 +112,7 @@ const AngularWorkflow = (props) => { const [appAuthentication, setAppAuthentication] = React.useState({}); const [variablesModalOpen, setVariablesModalOpen] = React.useState(false); + const [executionVariablesModalOpen, setExecutionVariablesModalOpen] = React.useState(false); const [authenticationModalOpen, setAuthenticationModalOpen] = React.useState(false); const [conditionsModalOpen, setConditionsModalOpen] = React.useState(false); const [newVariableName, setNewVariableName] = React.useState(""); @@ -791,7 +792,6 @@ const AngularWorkflow = (props) => { const onNodeSelect = (event) => { const data = event.target.data() - console.log("NODE: ", data) setLastSaved(false) //console.log(data) @@ -1412,22 +1412,6 @@ const AngularWorkflow = (props) => { const [open, setOpen] = React.useState(false); const [anchorEl, setAnchorEl] = React.useState(null); - if (workflow.workflow_variables === undefined || workflow.workflow_variables === null || workflow.workflow_variables.length === 0) { - return ( -