edgeboxctl/internal/tasks/tasks.go

396 lines
9.6 KiB
Go
Raw Normal View History

2021-02-13 16:06:13 +01:00
package tasks
import (
"database/sql"
"encoding/json"
2021-02-13 21:49:09 +01:00
"fmt"
2021-02-14 03:50:21 +01:00
"log"
2021-02-13 21:49:09 +01:00
"strconv"
2021-03-04 13:43:49 +01:00
"github.com/edgebox-iot/edgeboxctl/internal/diagnostics"
"github.com/edgebox-iot/edgeboxctl/internal/edgeapps"
"github.com/edgebox-iot/edgeboxctl/internal/utils"
2021-02-13 16:06:13 +01:00
_ "github.com/go-sql-driver/mysql" // Mysql Driver
_ "github.com/mattn/go-sqlite3" // SQlite Driver
)
// Task : Struct for Task type
type Task struct {
ID int `json:"id"`
Task string `json:"task"`
Args string `json:"args"`
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"`
Updated string `json:"updated"`
}
type taskSetupTunnelArgs struct {
BootnodeAddress string `json:"bootnode_address"`
BootnodeToken string `json:"bootnode_token"`
AssignedAddress string `json:"assigned_address"`
NodeName string `json:"node_name"`
}
type taskStartEdgeAppArgs struct {
ID string `json:"id"`
}
2021-03-04 16:06:54 +01:00
type taskInstallEdgeAppArgs struct {
ID string `json:"id"`
}
type taskRemoveEdgeAppArgs struct {
ID string `json:"id"`
}
type taskStopEdgeAppArgs struct {
ID string `json:"id"`
}
type taskEnableOnlineArgs struct {
ID string `json:"id"`
InternetURL string `json:"internet_url"`
}
type taskDisableOnlineArgs struct {
ID string `json:"id"`
}
// GetNextTask : Performs a MySQL query over the device's Edgebox API
func GetNextTask() Task {
// Will try to connect to API database, which should be running locally under WS.
db, err := sql.Open("sqlite3", utils.GetSQLiteDbConnectionDetails())
// if there is an error opening the connection, handle it
if err != nil {
panic(err.Error())
}
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 {
panic(err.Error())
}
var task Task
for results.Next() {
// for each row, scan the result into our task composite object
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
}
}
results.Close()
db.Close()
return task
}
2021-02-13 21:49:09 +01:00
// 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("sqlite3", utils.GetSQLiteDbConnectionDetails())
2021-02-13 21:49:09 +01:00
if err != nil {
panic(err.Error())
}
statement, err := db.Prepare("UPDATE task SET status = ?, updated = ? WHERE ID = ?;") // Prepare SQL Statement
if err != nil {
log.Fatal(err.Error())
}
2021-02-13 21:49:09 +01:00
_, err = statement.Exec(1, "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement
2021-02-13 21:49:09 +01:00
if err != nil {
log.Fatal(err.Error())
2021-02-13 21:49:09 +01:00
}
if diagnostics.Version == "dev" {
2021-02-14 03:50:21 +01:00
log.Printf("Dev environemnt. Not executing tasks.")
} else {
log.Println("Task: " + task.Task)
switch task.Task {
case "setup_tunnel":
2021-02-14 03:50:21 +01:00
log.Println("Setting up bootnode connection...")
var args taskSetupTunnelArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
2021-02-14 03:50:21 +01:00
log.Printf("Error reading arguments of setup_bootnode task: %s", err)
} else {
taskResult := taskSetupTunnel(args)
2021-02-14 03:50:21 +01:00
task.Result = sql.NullString{String: taskResult, Valid: true}
}
2021-03-04 16:06:54 +01:00
case "install_edgeapp":
log.Println("Installing EdgeApp...")
var args taskInstallEdgeAppArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of install_edgeapp task: %s", err)
} else {
taskResult := taskInstallEdgeApp(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
case "remove_edgeapp":
log.Println("Removing EdgeApp...")
var args taskRemoveEdgeAppArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of remove_edgeapp task: %s", err)
} else {
taskResult := taskRemoveEdgeApp(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
case "start_edgeapp":
log.Println("Starting EdgeApp...")
var args taskStartEdgeAppArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of start_edgeapp task: %s", err)
} else {
taskResult := taskStartEdgeApp(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
case "stop_edgeapp":
log.Println("Stopping EdgeApp...")
var args taskStopEdgeAppArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of stop_edgeapp task: %s", err)
} else {
taskResult := taskStopEdgeApp(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
case "enable_online":
log.Println("Enabling online access to EdgeApp...")
var args taskEnableOnlineArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of enable_online task: %s", err)
} else {
taskResult := taskEnableOnline(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
case "disable_online":
log.Println("Disabling online access to EdgeApp...")
var args taskDisableOnlineArgs
err := json.Unmarshal([]byte(task.Args), &args)
if err != nil {
log.Printf("Error reading arguments of enable_online task: %s", err)
} else {
taskResult := taskDisableOnline(args)
task.Result = sql.NullString{String: taskResult, Valid: true}
}
}
2021-02-13 21:49:09 +01:00
}
statement, err = db.Prepare("Update task SET status = ?, result = ?, updated = ? WHERE ID = ?;") // Prepare SQL Statement
if err != nil {
log.Fatal(err.Error())
}
if err != nil {
log.Fatal(err.Error())
}
2021-02-13 21:49:09 +01:00
if task.Result.Valid {
_, 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())
}
2021-02-13 21:49:09 +01:00
} else {
_, err = statement.Exec(3, "Error", "datetime('now')", strconv.Itoa(task.ID)) // Execute SQL Statement with Error info
if err != nil {
log.Fatal(err.Error())
}
2021-02-13 21:49:09 +01:00
}
if err != nil {
panic(err.Error())
}
db.Close()
2021-02-13 21:49:09 +01:00
returnTask := task
2021-02-13 21:49:09 +01:00
return returnTask
}
// ExecuteSchedules - Run Specific tasks without input each multiple x of ticks.
func ExecuteSchedules(tick int) {
if tick == 1 {
// Executing on startup (first tick). Schedules run before tasks in the SystemIterator
log.Println(taskGetEdgeApps())
}
if tick%30 == 0 {
// Executing every 30 ticks
log.Println(taskGetEdgeApps())
}
if tick%60 == 0 {
// Every 60 ticks...
}
// Just add a schedule here if you need a custom one (every "tick hour", every "tick day", etc...)
}
func taskSetupTunnel(args taskSetupTunnelArgs) string {
fmt.Println("Executing taskSetupTunnel")
2021-02-14 03:50:21 +01:00
2021-02-15 09:55:09 +01:00
cmdargs := []string{"gen", "--name", args.NodeName, "--token", args.BootnodeToken, args.BootnodeAddress + ":8655", "--prefix", args.AssignedAddress}
utils.Exec("tinc-boot", cmdargs)
cmdargs = []string{"start", "tinc@dnet"}
utils.Exec("systemctl", cmdargs)
cmdargs = []string{"enable", "tinc@dnet"}
utils.Exec("systemctl", cmdargs)
output := "OK" // Better check / logging of command execution result.
return output
}
2021-03-04 16:06:54 +01:00
func taskInstallEdgeApp(args taskInstallEdgeAppArgs) string {
fmt.Println("Executing taskInstallEdgeApp for " + args.ID)
result := edgeapps.SetEdgeAppInstalled(args.ID)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps()
return string(resultJSON)
}
func taskRemoveEdgeApp(args taskRemoveEdgeAppArgs) string {
fmt.Println("Executing taskRemoveEdgeApp for " + args.ID)
2021-03-04 16:53:49 +01:00
// Making sure the application is stopped before setting it as removed.
edgeapps.StopEdgeApp(args.ID)
2021-03-04 16:06:54 +01:00
result := edgeapps.SetEdgeAppNotInstalled(args.ID)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps()
return string(resultJSON)
}
func taskStartEdgeApp(args taskStartEdgeAppArgs) string {
fmt.Println("Executing taskStartEdgeApp for " + args.ID)
result := edgeapps.RunEdgeApp(args.ID)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps() // This task will imediatelly update the entry in the api database.
return string(resultJSON)
}
func taskStopEdgeApp(args taskStopEdgeAppArgs) string {
fmt.Println("Executing taskStopEdgeApp for " + args.ID)
result := edgeapps.StopEdgeApp(args.ID)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps() // This task will imediatelly update the entry in the api database.
return string(resultJSON)
}
func taskEnableOnline(args taskEnableOnlineArgs) string {
fmt.Println("Executing taskEnableOnline for " + args.ID)
result := edgeapps.EnableOnline(args.ID, args.InternetURL)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps()
return string(resultJSON)
}
func taskDisableOnline(args taskDisableOnlineArgs) string {
fmt.Println("Executing taskDisableOnline for " + args.ID)
result := edgeapps.DisableOnline(args.ID)
resultJSON, _ := json.Marshal(result)
taskGetEdgeApps()
return string(resultJSON)
}
func taskGetEdgeApps() string {
fmt.Println("Executing taskGetEdgeApps")
edgeApps := edgeapps.GetEdgeApps()
edgeAppsJSON, _ := json.Marshal(edgeApps)
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())
}
_, 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)
}