From 6cb3e198f0b2d3a1219d3459b8334b3995b136c7 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Sun, 2 May 2021 08:52:32 +0000 Subject: [PATCH 1/8] Supporting connection to SQLite database --- go.mod | 1 + go.sum | 2 ++ internal/tasks/tasks.go | 20 +++++++++----------- internal/utils/utils.go | 14 ++++++++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/go.mod b/go.mod index b739f0c..93cc7cb 100644 --- a/go.mod +++ b/go.mod @@ -5,5 +5,6 @@ go 1.15 require ( github.com/go-sql-driver/mysql v1.5.0 github.com/joho/godotenv v1.3.0 + github.com/mattn/go-sqlite3 v1.14.7 // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 445db8a..23cc3fe 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= +github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 8e92617..e9895b0 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -11,6 +11,7 @@ import ( "github.com/edgebox-iot/edgeboxctl/internal/edgeapps" "github.com/edgebox-iot/edgeboxctl/internal/utils" _ "github.com/go-sql-driver/mysql" // Mysql Driver + _ "github.com/mattn/go-sqlite3" // SQlite Driver ) // Task : Struct for Task type @@ -60,7 +61,7 @@ type taskDisableOnlineArgs struct { func GetNextTask() Task { // Will try to connect to API database, which should be running locally under WS. - db, err := sql.Open("mysql", utils.GetMySQLDbConnectionDetails()) + db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) // if there is an error opening the connection, handle it if err != nil { @@ -71,7 +72,7 @@ func GetNextTask() Task { defer db.Close() // perform a db.Query insert - results, err := db.Query("SELECT * FROM tasks WHERE status = 0 ORDER BY created ASC LIMIT 1;") + results, err := db.Query("SELECT * FROM task WHERE status = 0 ORDER BY created ASC LIMIT 1;") // if there is an error inserting, handle it if err != nil { @@ -99,7 +100,7 @@ func GetNextTask() Task { // ExecuteTask : Performs execution of the given task, updating the task status as it goes, and publishing the task result func ExecuteTask(task Task) Task { - db, err := sql.Open("mysql", utils.GetMySQLDbConnectionDetails()) + db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) if err != nil { panic(err.Error()) @@ -107,7 +108,7 @@ func ExecuteTask(task Task) Task { defer db.Close() - _, err = db.Query("UPDATE tasks SET status = 1 WHERE ID = " + strconv.Itoa(task.ID)) + _, err = db.Query("UPDATE task SET status = 1 WHERE ID = " + strconv.Itoa(task.ID)) if err != nil { panic(err.Error()) @@ -144,7 +145,6 @@ func ExecuteTask(task Task) Task { case "remove_edgeapp": - log.Println("Removing EdgeApp...") var args taskRemoveEdgeAppArgs err := json.Unmarshal([]byte(task.Args), &args) @@ -208,9 +208,9 @@ func ExecuteTask(task Task) Task { } if task.Result.Valid { - db.Query("Update tasks SET status = 2, result = '" + task.Result.String + "' WHERE ID = " + strconv.Itoa(task.ID) + ";") + db.Query("Update task SET status = 2, result = '" + task.Result.String + "' WHERE ID = " + strconv.Itoa(task.ID) + ";") } else { - db.Query("Update tasks SET status = 3, result = 'Error' WHERE ID = " + strconv.Itoa(task.ID) + ";") + db.Query("Update task SET status = 3, result = 'Error' WHERE ID = " + strconv.Itoa(task.ID) + ";") } if err != nil { @@ -276,7 +276,6 @@ func taskInstallEdgeApp(args taskInstallEdgeAppArgs) string { return string(resultJSON) - } func taskRemoveEdgeApp(args taskRemoveEdgeAppArgs) string { @@ -293,7 +292,6 @@ func taskRemoveEdgeApp(args taskRemoveEdgeAppArgs) string { return string(resultJSON) - } func taskStartEdgeApp(args taskStartEdgeAppArgs) string { @@ -359,7 +357,7 @@ func taskGetEdgeApps() string { edgeApps := edgeapps.GetEdgeApps() edgeAppsJSON, _ := json.Marshal(edgeApps) - db, err := sql.Open("mysql", utils.GetMySQLDbConnectionDetails()) + db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) if err != nil { panic(err.Error()) @@ -367,7 +365,7 @@ func taskGetEdgeApps() string { defer db.Close() - _, err = db.Query("REPLACE into options (name, value) VALUES ('EDGEAPPS_LIST','" + string(edgeAppsJSON) + "');") + _, err = db.Query("REPLACE into option (name, value) VALUES ('EDGEAPPS_LIST','" + string(edgeAppsJSON) + "');") if err != nil { panic(err.Error()) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 110f891..d733cea 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -82,6 +82,20 @@ func GetMySQLDbConnectionDetails() string { } +// GetSQLiteDbConnectionDetails : Returns the necessary string as connection info for SQL.db() +func GetSQLiteDbConnectionDetails() string { + + var apiEnv map[string]string + apiEnv, err := godotenv.Read(GetPath("apiEnvFileLocation")) + + if err != nil { + log.Fatal("Error loading .env file") + } + + return apiEnv["SQLITE_DATABASE"] // Will read from api project edgebox.env file + +} + // GetPath : Returns either the hardcoded path, or a overwritten value via .env file at project root. Register paths here for seamless working code between dev and prod environments ;) func GetPath(pathKey string) string { From d97571044551ec625861c93259fc7f033c124e65 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Mon, 3 May 2021 21:02:09 +0000 Subject: [PATCH 2/8] Added initial debug message of SQLite DB location --- cmd/edgeboxctl/main.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cmd/edgeboxctl/main.go b/cmd/edgeboxctl/main.go index ba58361..c60516e 100644 --- a/cmd/edgeboxctl/main.go +++ b/cmd/edgeboxctl/main.go @@ -73,7 +73,6 @@ func main() { log.Printf("System not ready. Next try will be executed in 60 seconds") time.Sleep(defaultNotReadySleepTime) } - } @@ -93,8 +92,8 @@ func printVersion() { func printDbDetails() { fmt.Printf( - "\n\nDatabase Connection Information:\n %s\n\n", - utils.GetMySQLDbConnectionDetails(), + "\n\nSQLite Database Location:\n %s\n\n", + utils.GetSQLiteDbConnectionDetails(), ) } @@ -112,7 +111,7 @@ func isDatabaseReady() bool { func systemIterator(name *string, tick int) { log.Printf("Tick is %d", tick) - + tasks.ExecuteSchedules(tick) nextTask := tasks.GetNextTask() if nextTask.Task != "" { From f238b3fa468557363721dbb60a4a3522f1358961 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Sat, 8 May 2021 20:42:07 +0000 Subject: [PATCH 3/8] Write queries using prepared statements, better error handling --- internal/tasks/tasks.go | 57 +++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index e9895b0..8e4bfaf 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -68,10 +68,6 @@ func GetNextTask() Task { panic(err.Error()) } - // defer the close till after the main function has finished executing - defer db.Close() - - // perform a db.Query insert results, err := db.Query("SELECT * FROM task WHERE status = 0 ORDER BY created ASC LIMIT 1;") // if there is an error inserting, handle it @@ -90,8 +86,8 @@ func GetNextTask() Task { } } - // be careful deferring Queries if you are using transactions - defer results.Close() + results.Close() + db.Close() return task @@ -106,12 +102,14 @@ func ExecuteTask(task Task) Task { panic(err.Error()) } - defer db.Close() - - _, err = db.Query("UPDATE task SET status = 1 WHERE ID = " + strconv.Itoa(task.ID)) - + statement, err := db.Prepare("UPDATE task SET status = ?, updated = ? WHERE ID = ?") // Prepare SQL Statement if err != nil { - panic(err.Error()) + log.Fatal(err.Error()) + } + + _, err = statement.Exec(1, "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement + if err != nil { + log.Fatal(err.Error()) } if diagnostics.Version == "dev" { @@ -207,16 +205,33 @@ func ExecuteTask(task Task) Task { } + statement, err = db.Prepare("Update task SET status = 2, result = '" + task.Result.String + "', updated = datetime('now') WHERE ID = " + strconv.Itoa(task.ID) + ";") // Prepare SQL Statement + if err != nil { + log.Fatal(err.Error()) + } + if err != nil { + log.Fatal(err.Error()) + } + if task.Result.Valid { - db.Query("Update task SET status = 2, result = '" + task.Result.String + "' WHERE ID = " + strconv.Itoa(task.ID) + ";") + _, err = statement.Exec(2, task.Result.String, "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement with result info + if err != nil { + log.Fatal(err.Error()) + } + } else { - db.Query("Update task SET status = 3, result = 'Error' WHERE ID = " + strconv.Itoa(task.ID) + ";") + _, err = statement.Exec(3, "Error", "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement with Error info + if err != nil { + log.Fatal(err.Error()) + } } if err != nil { panic(err.Error()) } + db.Close() + returnTask := task return returnTask @@ -360,17 +375,21 @@ func taskGetEdgeApps() string { db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) if err != nil { - panic(err.Error()) + log.Fatal(err.Error()) } - defer db.Close() - - _, err = db.Query("REPLACE into option (name, value) VALUES ('EDGEAPPS_LIST','" + string(edgeAppsJSON) + "');") - + statement, err := db.Prepare("REPLACE into option (name, value, created, updated) VALUES (?, ?, ?, ?);") // Prepare SQL Statement if err != nil { - panic(err.Error()) + log.Fatal(err.Error()) } + _, err = statement.Exec("EDGEAPPS_LIST", string(edgeAppsJSON), "datetime('now')", "datetime('now')") // Execute SQL Statement + if err != nil { + log.Fatal(err.Error()) + } + + db.Close() + return string(edgeAppsJSON) } From 58b7425fc74a8ef4b23bda1efd1c669d9ce95ecc Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Sat, 8 May 2021 20:46:36 +0000 Subject: [PATCH 4/8] Fixed incorrect query prepare statement, small fixes in queries --- internal/tasks/tasks.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 8e4bfaf..22e4d91 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -102,7 +102,7 @@ func ExecuteTask(task Task) Task { panic(err.Error()) } - statement, err := db.Prepare("UPDATE task SET status = ?, updated = ? WHERE ID = ?") // Prepare SQL Statement + statement, err := db.Prepare("UPDATE task SET status = ?, updated = ? WHERE ID = ?;") // Prepare SQL Statement if err != nil { log.Fatal(err.Error()) } @@ -205,7 +205,7 @@ func ExecuteTask(task Task) Task { } - statement, err = db.Prepare("Update task SET status = 2, result = '" + task.Result.String + "', updated = datetime('now') WHERE ID = " + strconv.Itoa(task.ID) + ";") // Prepare SQL Statement + statement, err = db.Prepare("Update task SET status = ?, result = ?, updated = ? WHERE ID = ?;") // Prepare SQL Statement if err != nil { log.Fatal(err.Error()) } From 9f63ab7f03fe570b586033091d0a230110de8818 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Wed, 19 May 2021 10:43:47 +0000 Subject: [PATCH 5/8] Support for nullable Task args --- internal/tasks/tasks.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 22e4d91..6e8c4e0 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -18,7 +18,7 @@ import ( type Task struct { ID int `json:"id"` Task string `json:"task"` - Args string `json:"args"` + Args sql.NullString `json:"args"` // Database fields that can be null must use the sql.NullString type Status string `json:"status"` Result sql.NullString `json:"result"` // Database fields that can be null must use the sql.NullString type Created string `json:"created"` @@ -121,7 +121,7 @@ func ExecuteTask(task Task) Task { log.Println("Setting up bootnode connection...") var args taskSetupTunnelArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of setup_bootnode task: %s", err) } else { @@ -133,7 +133,7 @@ func ExecuteTask(task Task) Task { log.Println("Installing EdgeApp...") var args taskInstallEdgeAppArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of install_edgeapp task: %s", err) } else { @@ -145,7 +145,7 @@ func ExecuteTask(task Task) Task { log.Println("Removing EdgeApp...") var args taskRemoveEdgeAppArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of remove_edgeapp task: %s", err) } else { @@ -157,7 +157,7 @@ func ExecuteTask(task Task) Task { log.Println("Starting EdgeApp...") var args taskStartEdgeAppArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of start_edgeapp task: %s", err) } else { @@ -169,7 +169,7 @@ func ExecuteTask(task Task) Task { log.Println("Stopping EdgeApp...") var args taskStopEdgeAppArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of stop_edgeapp task: %s", err) } else { @@ -181,7 +181,7 @@ func ExecuteTask(task Task) Task { log.Println("Enabling online access to EdgeApp...") var args taskEnableOnlineArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of enable_online task: %s", err) } else { @@ -193,7 +193,7 @@ func ExecuteTask(task Task) Task { log.Println("Disabling online access to EdgeApp...") var args taskDisableOnlineArgs - err := json.Unmarshal([]byte(task.Args), &args) + err := json.Unmarshal([]byte(task.Args.String), &args) if err != nil { log.Printf("Error reading arguments of enable_online task: %s", err) } else { From 81b545f86896f0a190a47d8b6f6dc30fa5c56e9d Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Sat, 22 May 2021 13:30:23 +0000 Subject: [PATCH 6/8] Fix wrong handling of task arguments in systemIterator --- cmd/edgeboxctl/main.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/edgeboxctl/main.go b/cmd/edgeboxctl/main.go index c60516e..e8f5b22 100644 --- a/cmd/edgeboxctl/main.go +++ b/cmd/edgeboxctl/main.go @@ -115,7 +115,11 @@ func systemIterator(name *string, tick int) { tasks.ExecuteSchedules(tick) nextTask := tasks.GetNextTask() if nextTask.Task != "" { - log.Printf("Executing task %s / Args: %s", nextTask.Task, nextTask.Args) + taskArguments := "No arguments" + if nextTask.Args.Valid { + taskArguments = nextTask.Args.String + } + log.Printf("Executing task %s / Args: %s", nextTask.Task, taskArguments) tasks.ExecuteTask(nextTask) } else { log.Printf("No tasks to execute.") From 770e814b6e1519a766c312fa9c81971ab25f15b2 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Sun, 30 May 2021 11:28:42 +0000 Subject: [PATCH 7/8] Fixed Datetime column values. Added utils.GetSQLiteFormattedDateTime def --- internal/tasks/tasks.go | 15 +++++++++++---- internal/utils/utils.go | 10 ++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 6e8c4e0..d5b796a 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "strconv" + "time" "github.com/edgebox-iot/edgeboxctl/internal/diagnostics" "github.com/edgebox-iot/edgeboxctl/internal/edgeapps" @@ -107,7 +108,9 @@ func ExecuteTask(task Task) Task { log.Fatal(err.Error()) } - _, err = statement.Exec(1, "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement + formatedDatetime := utils.GetSQLiteFormattedDateTime(time.Now()) + + _, err = statement.Exec(1, formatedDatetime, strconv.Itoa(task.ID)) // Execute SQL Statement if err != nil { log.Fatal(err.Error()) } @@ -213,14 +216,16 @@ func ExecuteTask(task Task) Task { log.Fatal(err.Error()) } + formatedDatetime = utils.GetSQLiteFormattedDateTime(time.Now()) + if task.Result.Valid { - _, err = statement.Exec(2, task.Result.String, "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement with result info + _, err = statement.Exec(2, task.Result.String, formatedDatetime, strconv.Itoa(task.ID)) // Execute SQL Statement with result info if err != nil { log.Fatal(err.Error()) } } else { - _, err = statement.Exec(3, "Error", "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement with Error info + _, err = statement.Exec(3, "Error", formatedDatetime, strconv.Itoa(task.ID)) // Execute SQL Statement with Error info if err != nil { log.Fatal(err.Error()) } @@ -383,7 +388,9 @@ func taskGetEdgeApps() string { log.Fatal(err.Error()) } - _, err = statement.Exec("EDGEAPPS_LIST", string(edgeAppsJSON), "datetime('now')", "datetime('now')") // Execute SQL Statement + formatedDatetime := utils.GetSQLiteFormattedDateTime(time.Now()) + + _, err = statement.Exec("EDGEAPPS_LIST", string(edgeAppsJSON), formatedDatetime, formatedDatetime) // Execute SQL Statement if err != nil { log.Fatal(err.Error()) } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index d733cea..ce9d032 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -7,6 +7,7 @@ import ( "log" "os" "os/exec" + "time" "github.com/joho/godotenv" ) @@ -96,6 +97,15 @@ func GetSQLiteDbConnectionDetails() string { } +// GetSQLiteFormattedDateTime: Given a Time, Returns a string that is formatted ready to be inserted into an SQLite Datetime field using sql.Prepare. +func GetSQLiteFormattedDateTime(t time.Time) string { + // This date is used to indicate the layout. + const datetimeLayout = "2006-01-02 15:04:05" + formatedDatetime := t.Format(datetimeLayout) + + return formatedDatetime +} + // GetPath : Returns either the hardcoded path, or a overwritten value via .env file at project root. Register paths here for seamless working code between dev and prod environments ;) func GetPath(pathKey string) string { From df3f8fe904335bf9c2904c849529c5ff3d19b8c4 Mon Sep 17 00:00:00 2001 From: Paulo Truta Date: Mon, 31 May 2021 11:21:14 +0000 Subject: [PATCH 8/8] Added system module, GetUptimeSeconds and GetUptimeFormatted funcs, taskGetSystemUptime --- go.mod | 5 +++++ go.sum | 14 ++++++++++++++ internal/system/system.go | 23 +++++++++++++++++++++++ internal/tasks/tasks.go | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 internal/system/system.go diff --git a/go.mod b/go.mod index 93cc7cb..175fc69 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,13 @@ module github.com/edgebox-iot/edgeboxctl go 1.15 require ( + github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-sql-driver/mysql v1.5.0 github.com/joho/godotenv v1.3.0 github.com/mattn/go-sqlite3 v1.14.7 // indirect + github.com/shirou/gopsutil v3.21.4+incompatible // indirect + github.com/tklauser/go-sysconf v0.3.6 // indirect + golang.org/x/sys v0.0.0-20210531080801-fdfd190a6549 // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 23cc3fe..3fe5772 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjlRbWyNqkPsJ3Fg+tQZCbgeX1VGljbQY= +github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -15,9 +19,15 @@ github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/shirou/gopsutil v3.21.4+incompatible h1:fuHcTm5mX+wzo542cmYcV9RTGQLbnHLI5SyQ5ryTVck= +github.com/shirou/gopsutil v3.21.4+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/tklauser/go-sysconf v0.3.6 h1:oc1sJWvKkmvIxhDHeKWvZS4f6AW+YcoguSfRF2/Hmo4= +github.com/tklauser/go-sysconf v0.3.6/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= +github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= +github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= @@ -39,6 +49,10 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210531080801-fdfd190a6549 h1:OL5GcZ2XPkte3dpfuFQ9o884vrE3BZQhajdntNMruv4= +golang.org/x/sys v0.0.0-20210531080801-fdfd190a6549/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= diff --git a/internal/system/system.go b/internal/system/system.go new file mode 100644 index 0000000..f8c2610 --- /dev/null +++ b/internal/system/system.go @@ -0,0 +1,23 @@ +package system + +import ( + "fmt" + "strconv" + + "github.com/shirou/gopsutil/host" +) + +func GetUptimeInSeconds() string { + uptime, _ := host.Uptime() + + return strconv.FormatUint(uptime, 10) +} + +func GetUptimeFormatted() string { + uptime, _ := host.Uptime() + + days := uptime / (60 * 60 * 24) + hours := (uptime - (days * 60 * 60 * 24)) / (60 * 60) + minutes := ((uptime - (days * 60 * 60 * 24)) - (hours * 60 * 60)) / 60 + return fmt.Sprintf("%d days, %d hours, %d minutes", days, hours, minutes) +} diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index d5b796a..18bd238 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -10,6 +10,7 @@ import ( "github.com/edgebox-iot/edgeboxctl/internal/diagnostics" "github.com/edgebox-iot/edgeboxctl/internal/edgeapps" + "github.com/edgebox-iot/edgeboxctl/internal/system" "github.com/edgebox-iot/edgeboxctl/internal/utils" _ "github.com/go-sql-driver/mysql" // Mysql Driver _ "github.com/mattn/go-sqlite3" // SQlite Driver @@ -247,8 +248,13 @@ func ExecuteTask(task Task) Task { func ExecuteSchedules(tick int) { if tick == 1 { + // Executing on startup (first tick). Schedules run before tasks in the SystemIterator + uptime := taskGetSystemUptime() + log.Println("Uptime is " + uptime + " seconds (" + system.GetUptimeFormatted() + ")") + log.Println(taskGetEdgeApps()) + } if tick%30 == 0 { @@ -400,3 +406,32 @@ func taskGetEdgeApps() string { return string(edgeAppsJSON) } + +func taskGetSystemUptime() string { + fmt.Println("Executing taskGetSystemUptime") + + uptime := system.GetUptimeInSeconds() + + db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails()) + + if err != nil { + log.Fatal(err.Error()) + } + + statement, err := db.Prepare("REPLACE into option (name, value, created, updated) VALUES (?, ?, ?, ?);") // Prepare SQL Statement + if err != nil { + log.Fatal(err.Error()) + } + + formatedDatetime := utils.GetSQLiteFormattedDateTime(time.Now()) + + _, err = statement.Exec("SYSTEM_UPTIME", uptime, formatedDatetime, formatedDatetime) // Execute SQL Statement + if err != nil { + log.Fatal(err.Error()) + } + + db.Close() + + return uptime + +}