diff --git a/internal/system/system.go b/internal/system/system.go index f4a58dd..83fe96d 100644 --- a/internal/system/system.go +++ b/internal/system/system.go @@ -425,3 +425,94 @@ func CopyFile(src string, dest string) error { return nil } +func CheckUpdates() { + fmt.Println("Checking for Edgebox System Updates.") + + // Configure the service and start it + cmd := exec.Command("sh", "/home/system/components/updater/run.sh", "--check") + stdout, err := cmd.StdoutPipe() + if err != nil { + panic(err) + } + scanner := bufio.NewScanner(stdout) + err = cmd.Start() + if err != nil { + panic(err) + } + for scanner.Scan() { + // fmt.Println(scanner.Text()) + text := scanner.Text() + fmt.Println(text) + } + if scanner.Err() != nil { + cmd.Process.Kill() + cmd.Wait() + fmt.Println("Error running updates check.") + utils.WriteOption("SYSTEM_UPDATES", "[]") + return + } + + // Read targets.env file into JSON list structure + targets := []string{} + targetsFile, err := os.Open("/home/system/components/updater/targets.env") + if err != nil { + fmt.Println("No targets.env file found. Skipping.") + utils.WriteOption("SYSTEM_UPDATES", "[]") + return + } + defer targetsFile.Close() + scanner = bufio.NewScanner(targetsFile) + for scanner.Scan() { + text := scanner.Text() + // text line should look like: {"target": "", "version": ""} + target := strings.Split(text, "=") + newText := "{\"target\": \"" + strings.Replace(target[0], "_VERSION", "", -1) + "\", \"version\": \"" + target[1] + "\"}" + targets = append(targets, newText) + } + if scanner.Err() != nil { + fmt.Println("Error reading update targets file.") + utils.WriteOption("SYSTEM_UPDATES", "[]") + return + } + + // convert targets to string + targetsString := strings.Join(targets, ",") + targetsString = "[" + targetsString + "]" + + fmt.Println(targetsString) + + // Write option with targets + utils.WriteOption("SYSTEM_UPDATES", targetsString) +} + +func ApplyUpdates() { + fmt.Println("Applying Edgebox System Updates.") + + utils.WriteOption("UPDATING_SYSTEM", "true") + + // Configure the service and start it + cmd := exec.Command("sh", "/home/system/components/updater/run.sh", "--update") + stdout, err := cmd.StdoutPipe() + if err != nil { + panic(err) + } + scanner := bufio.NewScanner(stdout) + err = cmd.Start() + if err != nil { + panic(err) + } + for scanner.Scan() { + fmt.Println(scanner.Text()) + text := scanner.Text() + fmt.Println(text) + } + if scanner.Err() != nil { + cmd.Process.Kill() + cmd.Wait() + panic(scanner.Err()) + } + + // If the system did not yet restart, set updating system to false + utils.WriteOption("UPDATING_SYSTEM", "false") +} + diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 5e0b3cc..4474cae 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -146,6 +146,33 @@ func GetNextTask() Task { } +// GetExecutingTasks : Performs a MySQL query over the device's Edgebox API to obtain all tasks that are currently executing +func GetExecutingTasks() []Task { + // Will try to connect to API database, which should be running locally under WS. + db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) + if err != nil { + panic(err.Error()) + } + results, err := db.Query("SELECT id, task, args, status, result, created, updated FROM task WHERE status = 1;") + if err != nil { + panic(err.Error()) + } + + var tasks []Task + for results.Next() { + // for each row, scan the result into our task composite object + var task Task + err = results.Scan(&task.ID, &task.Task, &task.Args, &task.Status, &task.Result, &task.Created, &task.Updated) + if err != nil { + panic(err.Error()) // proper error handling instead of panic in your app + } + tasks = append(tasks, task) + } + results.Close() + db.Close() + return tasks +} + // ExecuteTask : Performs execution of the given task, updating the task status as it goes, and publishing the task result func ExecuteTask(task Task) Task { @@ -387,6 +414,25 @@ func ExecuteTask(task Task) Task { taskResult := taskDisablePublicDashboard() task.Result = sql.NullString{String: taskResult, Valid: true} + case "check_updates": + log.Println("Checking for updates...") + taskResult := taskCheckSystemUpdates() + task.Result = sql.NullString{String: taskResult, Valid: true} + + case "apply_updates": + + log.Println("Updating Edgebox System...") + is_updating := utils.ReadOption("UPDATING_SYSTEM") + if is_updating == "true" { + log.Println("Edgebox update was running... Probably system restarted. Finishing update...") + utils.WriteOption("UPDATING_SYSTEM", "false") + task.Result = sql.NullString{String: "{result: true}", Valid: true} + } else { + log.Println("Updating Edgebox System...") + taskResult := taskUpdateSystem() + task.Result = sql.NullString{String: taskResult, Valid: true} + } + } } @@ -407,6 +453,7 @@ func ExecuteTask(task Task) Task { if err != nil { log.Fatal(err.Error()) } + } else { fmt.Println("Error executing task with result: " + task.Result.String) _, err = statement.Exec(STATUS_ERROR, "Error", formatedDatetime, strconv.Itoa(task.ID)) // Execute SQL Statement with Error info @@ -460,6 +507,9 @@ func ExecuteSchedules(tick int) { taskStartWs() log.Println(taskGetEdgeApps()) taskUpdateSystemLoggerServices() + taskRecoverFromUpdate() + taskCheckSystemUpdates() + } if tick%5 == 0 { @@ -506,6 +556,7 @@ func ExecuteSchedules(tick int) { if tick%3600 == 0 { // Executing every 3600 ticks (1 hour) + taskCheckSystemUpdates() } if tick%86400 == 0 { @@ -1230,6 +1281,38 @@ func taskDisablePublicDashboard() string { return "{result: false}" } +func taskCheckSystemUpdates() string { + fmt.Println("Executing taskCheckSystemUpdates") + system.CheckUpdates() + return "{result: true}" +} + +func taskUpdateSystem() string { + fmt.Println("Executing taskUpdateSystem") + system.ApplyUpdates() + return "{result: true}" +} + +func taskRecoverFromUpdate() string { + fmt.Println("Executing taskRecoverFromUpdate") + executing_tasks := GetExecutingTasks() + // Filter out the task with task value "update_system" + filteredTasks := []Task{} + for _, task := range executing_tasks { + if task.Task != "update_system" { + filteredTasks = append(filteredTasks, task) + } + } + + // If tasks is not empty, Get the last task + if len(filteredTasks) > 0 { + lastTask := filteredTasks[len(filteredTasks)-1] + ExecuteTask(lastTask) + } + + return "{result: true}" +} + func taskSetReleaseVersion() string { fmt.Println("Executing taskSetReleaseVersion")