2021-02-13 16:06:13 +01:00
package tasks
2021-02-13 15:51:14 +01:00
import (
"database/sql"
2021-02-14 01:04:50 +01:00
"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-05-30 13:28:42 +02:00
"time"
2023-03-20 00:54:42 +01:00
"os/exec"
"strings"
"os"
"bufio"
2021-02-13 15:51:14 +01:00
2021-03-04 13:43:49 +01:00
"github.com/edgebox-iot/edgeboxctl/internal/diagnostics"
"github.com/edgebox-iot/edgeboxctl/internal/edgeapps"
2021-06-13 12:03:36 +02:00
"github.com/edgebox-iot/edgeboxctl/internal/storage"
2021-05-31 13:21:14 +02:00
"github.com/edgebox-iot/edgeboxctl/internal/system"
2021-03-04 13:43:49 +01:00
"github.com/edgebox-iot/edgeboxctl/internal/utils"
2023-03-20 00:54:42 +01:00
2021-02-13 16:06:13 +01:00
_ "github.com/go-sql-driver/mysql" // Mysql Driver
2021-05-02 10:52:32 +02:00
_ "github.com/mattn/go-sqlite3" // SQlite Driver
2021-02-13 15:51:14 +01:00
)
2021-02-13 17:04:57 +01:00
// Task : Struct for Task type
type Task struct {
ID int ` json:"id" `
Task string ` json:"task" `
2021-05-19 12:43:47 +02:00
Args sql . NullString ` json:"args" ` // Database fields that can be null must use the sql.NullString type
2021-02-13 17:04:57 +01:00
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" `
}
2021-02-14 05:22:08 +01:00
type taskSetupTunnelArgs struct {
2023-03-20 00:54:42 +01:00
DomainName string ` json:"domain_name" `
2021-02-14 01:04:50 +01:00
}
2021-02-18 23:59:14 +01:00
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" `
}
2021-02-18 23:59:14 +01:00
type taskStopEdgeAppArgs struct {
ID string ` json:"id" `
}
2021-02-20 15:26:23 +01:00
type taskEnableOnlineArgs struct {
ID string ` json:"id" `
InternetURL string ` json:"internet_url" `
}
type taskDisableOnlineArgs struct {
ID string ` json:"id" `
}
2022-02-06 15:37:50 +01:00
type taskEnablePublicDashboardArgs struct {
InternetURL string ` json:"internet_url" `
}
2023-05-29 21:52:27 +02:00
type taskSetupBackupsArgs struct {
Service string ` json:"service" `
AccessKeyID string ` json:"access_key_id" `
SecretAccessKey string ` json:"secret_access_key" `
RepositoryName string ` json:"repository_name" `
RepositoryPassword string ` json:"repository_password" `
}
2023-03-20 00:54:42 +01:00
2021-06-17 21:48:15 +02:00
const STATUS_CREATED int = 0
const STATUS_EXECUTING int = 1
const STATUS_FINISHED int = 2
const STATUS_ERROR int = 3
2021-02-13 17:04:57 +01:00
// GetNextTask : Performs a MySQL query over the device's Edgebox API
func GetNextTask ( ) Task {
2021-02-13 15:51:14 +01:00
// Will try to connect to API database, which should be running locally under WS.
2021-05-02 10:52:32 +02:00
db , err := sql . Open ( "sqlite3" , utils . GetSQLiteDbConnectionDetails ( ) )
2021-02-13 15:51:14 +01:00
// if there is an error opening the connection, handle it
if err != nil {
panic ( err . Error ( ) )
}
2021-06-02 01:53:17 +02:00
results , err := db . Query ( "SELECT id, task, args, status, result, created, updated FROM task WHERE status = 0 ORDER BY created ASC LIMIT 1;" )
2021-02-13 15:51:14 +01:00
// if there is an error inserting, handle it
if err != nil {
panic ( err . Error ( ) )
}
2021-02-13 17:04:57 +01:00
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
}
}
2021-05-08 22:42:07 +02:00
results . Close ( )
db . Close ( )
2021-02-13 17:04:57 +01:00
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 {
2021-02-13 17:04:57 +01:00
2021-05-02 10:52:32 +02:00
db , err := sql . Open ( "sqlite3" , utils . GetSQLiteDbConnectionDetails ( ) )
2021-02-13 17:04:57 +01:00
2021-02-13 21:49:09 +01:00
if err != nil {
panic ( err . Error ( ) )
}
2021-02-13 17:04:57 +01:00
2021-05-08 22:46:36 +02:00
statement , err := db . Prepare ( "UPDATE task SET status = ?, updated = ? WHERE ID = ?;" ) // Prepare SQL Statement
2021-05-08 22:42:07 +02:00
if err != nil {
log . Fatal ( err . Error ( ) )
}
2021-02-13 21:49:09 +01:00
2021-05-30 13:28:42 +02:00
formatedDatetime := utils . GetSQLiteFormattedDateTime ( time . Now ( ) )
2023-05-29 21:52:27 +02:00
fmt . Println ( "Changing task status to executing: " + task . Task )
2021-06-17 21:48:15 +02:00
_ , err = statement . Exec ( STATUS_EXECUTING , formatedDatetime , strconv . Itoa ( task . ID ) ) // Execute SQL Statement
2021-02-13 21:49:09 +01:00
if err != nil {
2021-05-08 22:42:07 +02:00
log . Fatal ( err . Error ( ) )
2021-02-13 21:49:09 +01:00
}
2022-02-06 15:37:50 +01:00
if diagnostics . GetReleaseVersion ( ) == diagnostics . DEV_VERSION {
2021-02-14 03:50:21 +01:00
log . Printf ( "Dev environemnt. Not executing tasks." )
2021-02-14 01:04:50 +01:00
} else {
2021-02-14 05:22:08 +01:00
log . Println ( "Task: " + task . Task )
2022-02-06 15:37:50 +01:00
log . Println ( "Args: " + task . Args . String )
2021-02-14 01:04:50 +01:00
switch task . Task {
2023-05-29 21:52:27 +02:00
case "setup_backups" :
log . Println ( "Setting up Backups Destination..." )
var args taskSetupBackupsArgs
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
if err != nil {
log . Println ( "Error reading arguments of setup_backups task: %s" , err )
} else {
taskResult := taskSetupBackups ( args )
taskResultBool := true
// Check if returned taskResult string contains "error"
if strings . Contains ( taskResult , "error" ) {
taskResultBool = false
}
task . Result = sql . NullString { String : taskResult , Valid : taskResultBool }
}
case "start_backup" :
log . Println ( "Backing up Edgebox..." )
taskResult := taskBackup ( )
taskResultBool := true
// Check if returned taskResult string contains "error"
if strings . Contains ( taskResult , "error" ) {
taskResultBool = false
}
task . Result = sql . NullString { String : taskResult , Valid : taskResultBool }
2021-02-14 05:22:08 +01:00
case "setup_tunnel" :
2021-02-14 01:04:50 +01:00
2023-03-20 00:54:42 +01:00
log . Println ( "Setting up Cloudflare Tunnel..." )
2021-02-14 05:22:08 +01:00
var args taskSetupTunnelArgs
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-02-14 01:04:50 +01:00
if err != nil {
2023-03-20 00:54:42 +01:00
log . Printf ( "Error reading arguments of setup_tunnel task: %s" , err )
status := "{\"status\": \"error\", \"message\": \"The Domain Name you are going to Authorize must be provided beforehand! Please insert a domain name and try again.\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
2021-02-14 01:04:50 +01:00
} else {
2021-02-14 05:22:08 +01:00
taskResult := taskSetupTunnel ( args )
2021-02-14 03:50:21 +01:00
task . Result = sql . NullString { String : taskResult , Valid : true }
2021-02-14 01:04:50 +01:00
}
2023-03-20 00:54:42 +01:00
case "start_tunnel" :
log . Println ( "Starting Cloudflare Tunnel..." )
taskResult := taskStartTunnel ( )
task . Result = sql . NullString { String : taskResult , Valid : true }
case "stop_tunnel" :
log . Println ( "Stopping Cloudflare Tunnel..." )
taskResult := taskStopTunnel ( )
task . Result = sql . NullString { String : taskResult , Valid : true }
case "disable_tunnel" :
log . Println ( "Disabling Cloudflare Tunnel..." )
taskResult := taskDisableTunnel ( )
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
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-03-04 16:06:54 +01:00
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
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-03-04 16:06:54 +01:00
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 }
}
2021-02-14 01:04:50 +01:00
case "start_edgeapp" :
2021-02-18 23:59:14 +01:00
log . Println ( "Starting EdgeApp..." )
var args taskStartEdgeAppArgs
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-02-18 23:59:14 +01:00
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 }
}
2021-02-14 01:04:50 +01:00
case "stop_edgeapp" :
2021-02-18 23:59:14 +01:00
log . Println ( "Stopping EdgeApp..." )
var args taskStopEdgeAppArgs
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-02-18 23:59:14 +01:00
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 }
}
2021-02-20 15:26:23 +01:00
case "enable_online" :
log . Println ( "Enabling online access to EdgeApp..." )
var args taskEnableOnlineArgs
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-02-20 15:26:23 +01:00
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
2021-05-19 12:43:47 +02:00
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
2021-02-20 15:26:23 +01:00
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 }
}
2022-02-06 15:37:50 +01:00
case "enable_public_dashboard" :
log . Println ( "Enabling online access to Dashboard..." )
var args taskEnablePublicDashboardArgs
err := json . Unmarshal ( [ ] byte ( task . Args . String ) , & args )
if err != nil {
log . Printf ( "Error reading arguments of enable_public_dashboard task: %s" , err )
} else {
taskResult := taskEnablePublicDashboard ( args )
task . Result = sql . NullString { String : taskResult , Valid : true }
}
case "disable_public_dashboard" :
log . Println ( "Disabling online access to Dashboard..." )
taskResult := taskDisablePublicDashboard ( )
task . Result = sql . NullString { String : taskResult , Valid : true }
2021-02-14 01:04:50 +01:00
}
2021-02-20 15:26:23 +01:00
2021-02-13 21:49:09 +01:00
}
2021-05-08 22:46:36 +02:00
statement , err = db . Prepare ( "Update task SET status = ?, result = ?, updated = ? WHERE ID = ?;" ) // Prepare SQL Statement
2021-05-08 22:42:07 +02:00
if err != nil {
log . Fatal ( err . Error ( ) )
}
if err != nil {
log . Fatal ( err . Error ( ) )
}
2021-05-30 13:28:42 +02:00
formatedDatetime = utils . GetSQLiteFormattedDateTime ( time . Now ( ) )
2021-02-13 21:49:09 +01:00
if task . Result . Valid {
2023-05-29 21:52:27 +02:00
fmt . Println ( "Task Result: " + task . Result . String )
2021-06-17 21:48:15 +02:00
_ , err = statement . Exec ( STATUS_FINISHED , task . Result . String , formatedDatetime , strconv . Itoa ( task . ID ) ) // Execute SQL Statement with result info
2021-05-08 22:42:07 +02:00
if err != nil {
log . Fatal ( err . Error ( ) )
}
2021-02-13 21:49:09 +01:00
} else {
2023-05-29 21:52:27 +02:00
fmt . Println ( "Error executing task with result: " + task . Result . String )
2021-06-17 21:48:15 +02:00
_ , err = statement . Exec ( STATUS_ERROR , "Error" , formatedDatetime , strconv . Itoa ( task . ID ) ) // Execute SQL Statement with Error info
2021-05-08 22:42:07 +02:00
if err != nil {
log . Fatal ( err . Error ( ) )
}
2021-02-13 21:49:09 +01:00
}
if err != nil {
panic ( err . Error ( ) )
}
2021-05-08 22:42:07 +02:00
db . Close ( )
2021-02-13 21:49:09 +01:00
returnTask := task
2021-02-13 15:51:14 +01:00
2021-02-13 21:49:09 +01:00
return returnTask
2021-02-13 15:51:14 +01:00
}
2021-02-14 01:04:50 +01:00
2021-02-15 19:14:46 +01:00
// ExecuteSchedules - Run Specific tasks without input each multiple x of ticks.
func ExecuteSchedules ( tick int ) {
2021-02-15 20:37:16 +01:00
if tick == 1 {
2021-05-31 13:21:14 +02:00
2022-02-06 15:37:50 +01:00
ip := taskGetSystemIP ( )
log . Println ( "System IP is: " + ip )
release := taskSetReleaseVersion ( )
log . Println ( "Setting api option flag for Edgeboxctl (" + release + " version)" )
hostname := taskGetHostname ( )
log . Println ( "Hostname is " + hostname )
// if diagnostics.Version == "cloud" && !edgeapps.IsPublicDashboard() {
// taskEnablePublicDashboard(taskEnablePublicDashboardArgs{
// InternetURL: hostname + ".myedge.app",
// })
// }
if diagnostics . GetReleaseVersion ( ) == diagnostics . CLOUD_VERSION {
log . Println ( "Setting up cloud version options (name, email, api token)" )
taskSetupCloudOptions ( )
}
2021-02-15 20:37:16 +01:00
// Executing on startup (first tick). Schedules run before tasks in the SystemIterator
2021-05-31 13:21:14 +02:00
uptime := taskGetSystemUptime ( )
log . Println ( "Uptime is " + uptime + " seconds (" + system . GetUptimeFormatted ( ) + ")" )
2021-06-13 12:03:36 +02:00
log . Println ( taskGetStorageDevices ( ) )
2021-02-17 13:34:53 +01:00
log . Println ( taskGetEdgeApps ( ) )
2021-05-31 13:21:14 +02:00
2021-02-15 20:37:16 +01:00
}
2021-06-13 12:03:36 +02:00
if tick % 5 == 0 {
// Executing every 5 ticks
2022-02-06 15:37:50 +01:00
taskGetSystemUptime ( )
2021-06-13 12:03:36 +02:00
log . Println ( taskGetStorageDevices ( ) )
}
2021-02-15 19:14:46 +01:00
if tick % 30 == 0 {
// Executing every 30 ticks
2021-02-17 13:34:53 +01:00
log . Println ( taskGetEdgeApps ( ) )
2023-05-29 21:52:27 +02:00
// RESET SOME VARIABLES HERE IF NEEDED, SINCE SYSTEM IS UNBLOCKED
utils . WriteOption ( "BACKUP_IS_WORKING" , "0" )
2021-02-15 19:14:46 +01:00
}
if tick % 60 == 0 {
2022-02-06 15:37:50 +01:00
ip := taskGetSystemIP ( )
log . Println ( "System IP is: " + ip )
2021-02-15 19:14:46 +01:00
}
2023-05-29 21:52:27 +02:00
if tick % 3600 == 0 {
// Executing every 3600 ticks (1 hour)
backup := taskAutoBackup ( )
log . Println ( "Auto Backup: " + backup )
}
2021-02-15 19:14:46 +01:00
// Just add a schedule here if you need a custom one (every "tick hour", every "tick day", etc...)
}
2023-05-29 21:52:27 +02:00
func taskSetupBackups ( args taskSetupBackupsArgs ) string {
fmt . Println ( "Executing taskSetupBackups" + args . Service )
// ...
service_url := ""
key_id_name := "AWS_ACCESS_KEY_ID"
key_secret_name := "AWS_SECRET_ACCESS_KEY"
repo_location := "/home/system/components/apps/"
service_found := false
switch args . Service {
case "s3" :
service_url = "s3.amazonaws.com/"
service_found = true
case "b2" :
service_url = ""
key_id_name = "B2_ACCOUNT_ID"
key_secret_name = "B2_ACCOUNT_KEY"
service_found = true
case "wasabi" :
service_found = true
service_url = "s3.wasabisys.com/"
}
if ! service_found {
fmt . Println ( "Service not found" )
return "{\"status\": \"error\", \"message\": \"Service not found\"}"
}
fmt . Println ( "Creating env vars for authentication with backup service" )
os . Setenv ( key_id_name , args . AccessKeyID )
os . Setenv ( key_secret_name , args . SecretAccessKey )
fmt . Println ( "Creating restic password file" )
system . CreateBackupsPasswordFile ( args . RepositoryPassword )
fmt . Println ( "Initializing restic repository" )
utils . WriteOption ( "BACKUP_IS_WORKING" , "1" )
cmdArgs := [ ] string { "-r" , args . Service + ":" + service_url + args . RepositoryName + ":" + repo_location , "init" , "--password-file" , utils . GetPath ( utils . BackupPasswordFileLocation ) , "--verbose=3" }
result := utils . ExecAndStream ( repo_location , "restic" , cmdArgs )
utils . WriteOption ( "BACKUP_IS_WORKING" , "0" )
// See if result contains the substring "Fatal:"
if strings . Contains ( result , "Fatal:" ) {
fmt . Println ( "Error initializing restic repository" )
utils . WriteOption ( "BACKUP_STATUS" , "error" )
utils . WriteOption ( "BACKUP_ERROR_MESSAGE" , result )
return "{\"status\": \"error\", \"message\": \"" + result + "\"}"
}
// Save options to database
utils . WriteOption ( "BACKUP_STATUS" , "initiated" )
utils . WriteOption ( "BACKUP_SERVICE" , args . Service )
utils . WriteOption ( "BACKUP_SERVICE_URL" , service_url )
utils . WriteOption ( "BACKUP_REPOSITORY_NAME" , args . RepositoryName )
utils . WriteOption ( "BACKUP_REPOSITORY_PASSWORD" , args . RepositoryPassword )
utils . WriteOption ( "BACKUP_REPOSITORY_ACCESS_KEY_ID" , args . AccessKeyID )
utils . WriteOption ( "BACKUP_REPOSITORY_SECRET_ACCESS_KEY" , args . SecretAccessKey )
utils . WriteOption ( "BACKUP_REPOSITORY_LOCATION" , repo_location )
// Populate Stats right away
taskGetBackupStatus ( )
return "{\"status\": \"ok\"}"
}
func taskRemoveBackups ( ) string {
fmt . Println ( "Executing taskRemoveBackups" )
// ... This deletes the restic repository
// cmdArgs := []string{"-r", "s3:https://s3.amazonaws.com/edgebox-backups:/home/system/components/apps/", "forget", "latest", "--password-file", utils.GetPath(utils.BackupPasswordFileLocation), "--verbose=3"}
utils . WriteOption ( "BACKUP_STATUS" , "" )
utils . WriteOption ( "BACKUP_IS_WORKING" , "0" )
return "{\"status\": \"ok\"}"
}
func taskBackup ( ) string {
fmt . Println ( "Executing taskBackup" )
// Load Backup Options
backup_service := utils . ReadOption ( "BACKUP_SERVICE" )
backup_service_url := utils . ReadOption ( "BACKUP_SERVICE_URL" )
backup_repository_name := utils . ReadOption ( "BACKUP_REPOSITORY_NAME" )
// backup_repository_password := utils.ReadOption("BACKUP_REPOSITORY_PASSWORD")
backup_repository_access_key_id := utils . ReadOption ( "BACKUP_REPOSITORY_ACCESS_KEY_ID" )
backup_repository_secret_access_key := utils . ReadOption ( "BACKUP_REPOSITORY_SECRET_ACCESS_KEY" )
backup_repository_location := utils . ReadOption ( "BACKUP_REPOSITORY_LOCATION" )
key_id_name := "AWS_ACCESS_KEY_ID"
key_secret_name := "AWS_SECRET_ACCESS_KEY"
service_found := false
switch backup_service {
case "s3" :
service_found = true
case "b2" :
key_id_name = "B2_ACCOUNT_ID"
key_secret_name = "B2_ACCOUNT_KEY"
service_found = true
case "wasabi" :
service_found = true
}
if ! service_found {
fmt . Println ( "Service not found" )
return "{\"status\": \"error\", \"message\": \"Backup Service not found\"}"
}
fmt . Println ( "Creating env vars for authentication with backup service" )
fmt . Println ( key_id_name )
os . Setenv ( key_id_name , backup_repository_access_key_id )
fmt . Println ( key_secret_name )
os . Setenv ( key_secret_name , backup_repository_secret_access_key )
utils . WriteOption ( "BACKUP_IS_WORKING" , "1" )
// ... This backs up the restic repository
cmdArgs := [ ] string { "-r" , backup_service + ":" + backup_service_url + backup_repository_name + ":" + backup_repository_location , "backup" , backup_repository_location , "--password-file" , utils . GetPath ( utils . BackupPasswordFileLocation ) , "--verbose=3" }
result := utils . ExecAndStream ( backup_repository_location , "restic" , cmdArgs )
utils . WriteOption ( "BACKUP_IS_WORKING" , "0" )
// Write as Unix timestamp
utils . WriteOption ( "BACKUP_LAST_RUN" , strconv . FormatInt ( time . Now ( ) . Unix ( ) , 10 ) )
// See if result contains the substring "Fatal:"
if strings . Contains ( result , "Fatal:" ) {
fmt . Println ( "Error backing up" )
utils . WriteOption ( "BACKUP_STATUS" , "error" )
utils . WriteOption ( "BACKUP_ERROR_MESSAGE" , result )
return "{\"status\": \"error\", \"message\": \"" + result + "\"}"
}
utils . WriteOption ( "BACKUP_STATUS" , "working" )
taskGetBackupStatus ( )
return "{\"status\": \"ok\"}"
}
func taskAutoBackup ( ) string {
fmt . Println ( "Executing taskAutoBackup" )
// Get Backup Status
backup_status := utils . ReadOption ( "BACKUP_STATUS" )
// We only backup is the status is "working"
if backup_status == "working" {
return taskBackup ( )
} else {
fmt . Println ( "Backup status is not working... skipping" )
return "{\"status\": \"skipped\"}"
}
}
func taskGetBackupStatus ( ) string {
fmt . Println ( "Executing taskGetBackupStatus" )
// Load Backup Options
backup_service := utils . ReadOption ( "BACKUP_SERVICE" )
backup_service_url := utils . ReadOption ( "BACKUP_SERVICE_URL" )
backup_repository_name := utils . ReadOption ( "BACKUP_REPOSITORY_NAME" )
// backup_repository_password := utils.ReadOption("BACKUP_REPOSITORY_PASSWORD")
backup_repository_access_key_id := utils . ReadOption ( "BACKUP_REPOSITORY_ACCESS_KEY_ID" )
backup_repository_secret_access_key := utils . ReadOption ( "BACKUP_REPOSITORY_SECRET_ACCESS_KEY" )
backup_repository_location := utils . ReadOption ( "BACKUP_REPOSITORY_LOCATION" )
key_id_name := "AWS_ACCESS_KEY_ID"
key_secret_name := "AWS_SECRET_ACCESS_KEY"
service_found := false
switch backup_service {
case "s3" :
service_found = true
case "b2" :
key_id_name = "B2_ACCOUNT_ID"
key_secret_name = "B2_ACCOUNT_KEY"
service_found = true
case "wasabi" :
service_found = true
}
if ! service_found {
fmt . Println ( "Service not found" )
return "{\"status\": \"error\", \"message\": \"Backup Service not found\"}"
}
fmt . Println ( "Creating env vars for authentication with backup service" )
os . Setenv ( key_id_name , backup_repository_access_key_id )
os . Setenv ( key_secret_name , backup_repository_secret_access_key )
// ... This gets the restic repository status
cmdArgs := [ ] string { "-r" , backup_service + ":" + backup_service_url + backup_repository_name + ":" + backup_repository_location , "stats" , "--password-file" , utils . GetPath ( utils . BackupPasswordFileLocation ) , "--verbose=3" }
utils . WriteOption ( "BACKUP_STATS" , utils . ExecAndStream ( backup_repository_location , "restic" , cmdArgs ) )
return "{\"status\": \"ok\"}"
}
2021-02-14 05:22:08 +01:00
func taskSetupTunnel ( args taskSetupTunnelArgs ) string {
fmt . Println ( "Executing taskSetupTunnel" )
2023-03-20 00:54:42 +01:00
wsPath := utils . GetPath ( utils . WsPath )
// Stop a the service if it is running
system . StopService ( "cloudflared" )
2021-02-14 03:50:21 +01:00
2023-03-20 00:54:42 +01:00
// Uninstall the service if it is installed
system . RemoveTunnelService ( )
2021-02-14 01:04:50 +01:00
2023-03-20 00:54:42 +01:00
fmt . Println ( "Creating cloudflared folder" )
cmdargs := [ ] string { "/home/system/.cloudflared" }
utils . Exec ( wsPath , "mkdir" , cmdargs )
cmd := exec . Command ( "sh" , "/home/system/components/edgeboxctl/scripts/cloudflared_login.sh" )
stdout , err := cmd . StdoutPipe ( )
if err != nil {
panic ( err )
}
scanner := bufio . NewScanner ( stdout )
err = cmd . Start ( )
if err != nil {
panic ( err )
}
url := ""
for scanner . Scan ( ) {
fmt . Println ( scanner . Text ( ) )
text := scanner . Text ( )
if strings . Contains ( text , "https://" ) {
url = text
fmt . Println ( "Tunnel setup is requesting auth with URL: " + url )
status := "{\"status\": \"waiting\", \"login_link\": \"" + url + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
break
}
}
if scanner . Err ( ) != nil {
cmd . Process . Kill ( )
cmd . Wait ( )
panic ( scanner . Err ( ) )
}
go func ( ) {
fmt . Println ( "Running async" )
cmd . Wait ( )
// Keep retrying to read cert.pem file until it is created
// When running as a service, the cert is saved to a different folder,
// so we check both :)
for {
_ , err := os . Stat ( "/home/system/.cloudflared/cert.pem" )
_ , err2 := os . Stat ( "/root/.cloudflared/cert.pem" )
if err == nil || err2 == nil {
fmt . Println ( "cert.pem file detected" )
break
}
time . Sleep ( 1 * time . Second )
fmt . Println ( "Waiting for cert.pem file to be created" )
}
2021-02-14 01:04:50 +01:00
2023-03-20 00:54:42 +01:00
fmt . Println ( "Tunnel auth setup finished without errors." )
status := "{\"status\": \"starting\", \"login_link\": \"" + url + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
// Remove old tunnel if it exists, and create from scratch
system . DeleteTunnel ( )
// Create new tunnel (destination config file is param)
system . CreateTunnel ( "/home/system/.cloudflared/config.yml" )
fmt . Println ( "Creating DNS Routes for @ and *." )
cmd = exec . Command ( "cloudflared" , "tunnel" , "route" , "dns" , "-f" , "edgebox" , "*." + args . DomainName )
cmd . Start ( )
err = cmd . Wait ( )
if err != nil {
log . Fatal ( err )
}
cmd = exec . Command ( "cloudflared" , "tunnel" , "route" , "dns" , "-f" , "edgebox" , args . DomainName )
cmd . Start ( )
err = cmd . Wait ( )
if err != nil {
log . Fatal ( err )
}
domainNameInfo := args . DomainName
utils . WriteOption ( "DOMAIN_NAME" , domainNameInfo )
// Install service with given config file
system . InstallTunnelService ( "/home/system/.cloudflared/config.yml" )
// Start the service
system . StartService ( "cloudflared" )
if err != nil {
fmt . Println ( "Tunnel auth setup finished with errors." )
status := "{\"status\": \"error\", \"login_link\": \"" + url + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
log . Fatal ( err )
} else {
fmt . Println ( "Tunnel auth setup finished without errors." )
status := "{\"status\": \"connected\", \"login_link\": \"" + url + "\", \"domain\": \"" + args . DomainName + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
}
fmt . Println ( "Finished running async" )
} ( )
return "{\"url\": \"" + url + "\"}"
}
func taskStartTunnel ( ) string {
fmt . Println ( "Executing taskStartTunnel" )
system . StartService ( "cloudflared" )
domainName := utils . ReadOption ( "DOMAIN_NAME" )
status := "{\"status\": \"connected\", \"domain\": \"" + domainName + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
return "{\"status\": \"ok\"}"
}
func taskStopTunnel ( ) string {
fmt . Println ( "Executing taskStopTunnel" )
system . StopService ( "cloudflared" )
domainName := utils . ReadOption ( "DOMAIN_NAME" )
status := "{\"status\": \"stopped\", \"domain\": \"" + domainName + "\"}"
utils . WriteOption ( "TUNNEL_STATUS" , status )
return "{\"status\": \"ok\"}"
}
2021-02-14 01:04:50 +01:00
2023-03-20 00:54:42 +01:00
func taskDisableTunnel ( ) string {
fmt . Println ( "Executing taskDisableTunnel" )
system . StopService ( "cloudflared" )
system . DeleteTunnel ( )
system . RemoveTunnelService ( )
utils . DeleteOption ( "DOMAIN_NAME" )
utils . DeleteOption ( "TUNNEL_STATUS" )
return "{\"status\": \"ok\"}"
2021-02-14 01:04:50 +01:00
}
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 )
}
2021-02-18 23:59:14 +01:00
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 )
}
2021-02-20 15:26:23 +01:00
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 {
2021-02-20 19:09:41 +01:00
fmt . Println ( "Executing taskDisableOnline for " + args . ID )
2021-02-20 15:26:23 +01:00
result := edgeapps . DisableOnline ( args . ID )
resultJSON , _ := json . Marshal ( result )
taskGetEdgeApps ( )
return string ( resultJSON )
}
2022-02-06 15:37:50 +01:00
func taskEnablePublicDashboard ( args taskEnablePublicDashboardArgs ) string {
fmt . Println ( "Enabling taskEnablePublicDashboard" )
result := edgeapps . EnablePublicDashboard ( args . InternetURL )
if result {
2021-02-15 19:14:46 +01:00
2022-02-06 15:37:50 +01:00
utils . WriteOption ( "PUBLIC_DASHBOARD" , args . InternetURL )
return "{result: true}"
2021-02-17 01:08:10 +01:00
2022-02-06 15:37:50 +01:00
}
2021-02-17 12:10:15 +01:00
2022-02-06 15:37:50 +01:00
return "{result: false}"
}
2021-02-17 13:34:53 +01:00
2022-02-06 15:37:50 +01:00
func taskDisablePublicDashboard ( ) string {
fmt . Println ( "Executing taskDisablePublicDashboard" )
result := edgeapps . DisablePublicDashboard ( )
utils . WriteOption ( "PUBLIC_DASHBOARD" , "" )
if result {
return "{result: true}"
2021-02-17 13:34:53 +01:00
}
2022-02-06 15:37:50 +01:00
return "{result: false}"
}
2021-02-17 12:10:15 +01:00
2022-02-06 15:37:50 +01:00
func taskSetReleaseVersion ( ) string {
2021-02-17 12:10:15 +01:00
2022-02-06 15:37:50 +01:00
fmt . Println ( "Executing taskSetReleaseVersion" )
2021-05-30 13:28:42 +02:00
2022-02-06 15:37:50 +01:00
utils . WriteOption ( "RELEASE_VERSION" , diagnostics . Version )
2021-02-17 12:10:15 +01:00
2022-02-06 15:37:50 +01:00
return diagnostics . Version
}
2021-05-08 22:42:07 +02:00
2022-02-06 15:37:50 +01:00
func taskGetEdgeApps ( ) string {
fmt . Println ( "Executing taskGetEdgeApps" )
2021-02-15 19:14:46 +01:00
2022-02-06 15:37:50 +01:00
edgeApps := edgeapps . GetEdgeApps ( )
edgeAppsJSON , _ := json . Marshal ( edgeApps )
utils . WriteOption ( "EDGEAPPS_LIST" , string ( edgeAppsJSON ) )
return string ( edgeAppsJSON )
2021-02-15 19:14:46 +01:00
}
2021-05-31 13:21:14 +02:00
func taskGetSystemUptime ( ) string {
fmt . Println ( "Executing taskGetSystemUptime" )
uptime := system . GetUptimeInSeconds ( )
2022-02-06 15:37:50 +01:00
utils . WriteOption ( "SYSTEM_UPTIME" , uptime )
2021-05-31 13:21:14 +02:00
return uptime
}
2021-06-13 12:03:36 +02:00
func taskGetStorageDevices ( ) string {
fmt . Println ( "Executing taskGetStorageDevices" )
2022-02-06 15:37:50 +01:00
devices := storage . GetDevices ( diagnostics . GetReleaseVersion ( ) )
2021-06-13 12:03:36 +02:00
devicesJSON , _ := json . Marshal ( devices )
2022-02-06 15:37:50 +01:00
utils . WriteOption ( "STORAGE_DEVICES_LIST" , string ( devicesJSON ) )
2021-06-13 12:03:36 +02:00
2022-02-06 15:37:50 +01:00
return string ( devicesJSON )
}
2021-06-13 12:03:36 +02:00
2022-02-06 15:37:50 +01:00
func taskGetSystemIP ( ) string {
fmt . Println ( "Executing taskGetStorageDevices" )
ip := system . GetIP ( )
utils . WriteOption ( "IP_ADDRESS" , ip )
return ip
}
2021-06-13 12:03:36 +02:00
2022-02-06 15:37:50 +01:00
func taskGetHostname ( ) string {
fmt . Println ( "Executing taskGetHostname" )
hostname := system . GetHostname ( )
utils . WriteOption ( "HOSTNAME" , hostname )
return hostname
}
2021-06-13 12:03:36 +02:00
2022-02-06 15:37:50 +01:00
func taskSetupCloudOptions ( ) {
fmt . Println ( "Executing taskSetupCloudOptions" )
system . SetupCloudOptions ( )
2021-06-13 12:03:36 +02:00
}