diff --git a/Makefile b/Makefile index b333528..1e646b3 100644 --- a/Makefile +++ b/Makefile @@ -69,5 +69,8 @@ start: stop: systemctl stop edgeboxctl +status: + systemctl status edgeboxctl + log: start journalctl -fu edgeboxctl diff --git a/internal/edgeapps/edgeapps.go b/internal/edgeapps/edgeapps.go index e49652a..05650bf 100644 --- a/internal/edgeapps/edgeapps.go +++ b/internal/edgeapps/edgeapps.go @@ -11,6 +11,7 @@ import ( "github.com/edgebox-iot/edgeboxctl/internal/system" "github.com/edgebox-iot/edgeboxctl/internal/utils" + "github.com/edgebox-iot/edgeboxctl/internal/diagnostics" ) // EdgeApp : Struct representing an EdgeApp in the system @@ -18,6 +19,7 @@ type EdgeApp struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description"` + Experimental bool `json:"experimental"` Status EdgeAppStatus `json:"status"` Services []EdgeAppService `json:"services"` InternetAccessible bool `json:"internet_accessible"` @@ -86,6 +88,7 @@ func GetEdgeApp(ID string) MaybeEdgeApp { edgeAppName := ID edgeAppDescription := "" + edgeAppExperimental := false edgeAppOptions := []EdgeAppOption{} edgeAppEnv, err := godotenv.Read(utils.GetPath(utils.EdgeAppsPath) + ID + envFilename) @@ -99,6 +102,9 @@ func GetEdgeApp(ID string) MaybeEdgeApp { if edgeAppEnv["EDGEAPP_DESCRIPTION"] != "" { edgeAppDescription = edgeAppEnv["EDGEAPP_DESCRIPTION"] } + if edgeAppEnv["EDGEAPP_EXPERIMENTAL"] == "true" { + edgeAppExperimental = true + } } needsConfig := false @@ -231,6 +237,7 @@ func GetEdgeApp(ID string) MaybeEdgeApp { ID: ID, Name: edgeAppName, Description: edgeAppDescription, + Experimental: edgeAppExperimental, Status: GetEdgeAppStatus(ID), Services: GetEdgeAppServices(ID), InternetAccessible: edgeAppInternetAccessible, @@ -263,22 +270,54 @@ func IsEdgeAppInstalled(ID string) bool { } +func writeAppRunnableFiles(ID string) bool { + edgeAppPath := utils.GetPath(utils.EdgeAppsPath) + _, err := os.Stat(edgeAppPath + ID + runnableFilename) + if os.IsNotExist(err) { + _, err := os.Create(edgeAppPath + ID + runnableFilename) + if err != nil { + log.Fatal("Runnable file for EdgeApp could not be created!") + return false + } + + // Check the block default apps option + blockDefaultAppsOption := utils.ReadOption("DASHBOARD_BLOCK_DEFAULT_APPS_PUBLIC_ACCESS") + if blockDefaultAppsOption != "yes" { + // Create myedgeapp.env file with default network URL + envFilePath := edgeAppPath + ID + myEdgeAppServiceEnvFilename + + var networkURL string + domainName := utils.ReadOption("DOMAIN_NAME") + + if domainName != "" { + networkURL = ID + "." + domainName + } else if diagnostics.GetReleaseVersion() == diagnostics.CLOUD_VERSION { + cluster := utils.ReadOption("CLUSTER") + username := utils.ReadOption("USERNAME") + if cluster != "" && username != "" { + networkURL = username + "-" + ID + "." + cluster + } + } else { + networkURL = ID + "." + system.GetHostname() + ".local" // default + } + + env, _ := godotenv.Unmarshal("INTERNET_URL=" + networkURL) + err = godotenv.Write(env, envFilePath) + if err != nil { + log.Printf("Error creating myedgeapp.env file: %s", err) + // result = false + } + } + } + return true +} + func SetEdgeAppInstalled(ID string) bool { result := true - edgeAppPath := utils.GetPath(utils.EdgeAppsPath) - - _, err := os.Stat(edgeAppPath + ID + runnableFilename) - if os.IsNotExist(err) { - - _, err := os.Create(edgeAppPath + ID + runnableFilename) - result = true - - if err != nil { - log.Fatal("Runnable file for EdgeApp could not be created!") - result = false - } + if writeAppRunnableFiles(ID) { + buildFrameworkContainers() } else { @@ -292,6 +331,21 @@ func SetEdgeAppInstalled(ID string) bool { } +func SetEdgeAppBulkInstalled(IDs []string) bool { + + result := true + + for _, ID := range IDs { + writeAppRunnableFiles(ID) + } + + buildFrameworkContainers() + + return result + +} + + func SetEdgeAppNotInstalled(ID string) bool { // Stop the app first diff --git a/internal/tasks/tasks.go b/internal/tasks/tasks.go index 4474cae..f68227a 100644 --- a/internal/tasks/tasks.go +++ b/internal/tasks/tasks.go @@ -56,6 +56,10 @@ type taskInstallEdgeAppArgs struct { ID string `json:"id"` } +type taskInstallBulkEdgeAppsArgs struct { + IDS []string `json:"ids"` +} + type taskRemoveEdgeAppArgs struct { ID string `json:"id"` } @@ -299,6 +303,18 @@ func ExecuteTask(task Task) Task { task.Result = sql.NullString{String: taskResult, Valid: true} } + case "install_bulk_edgeapps": + + log.Println("Installing Bulk EdgeApps...") + var args taskInstallBulkEdgeAppsArgs + err := json.Unmarshal([]byte(task.Args.String), &args) + if err != nil { + log.Printf("Error reading arguments of install_bulk_edgeapps task: %s", err) + } else { + taskResult := taskInstallBulkEdgeApps(args) + task.Result = sql.NullString{String: taskResult, Valid: true} + } + case "remove_edgeapp": log.Println("Removing EdgeApp...") @@ -975,12 +991,19 @@ func taskSetupTunnel(args taskSetupTunnelArgs) string { } 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\"}" + fmt.Println("Executing taskStartTunnel") + + // Read tunnel status to check if cloudflare is configured + tunnelStatus := utils.ReadOption("TUNNEL_STATUS") + if tunnelStatus != "" { + // Only start cloudflared if we have a tunnel configured + system.StartService("cloudflared") + domainName := utils.ReadOption("DOMAIN_NAME") + status := "{\"status\": \"connected\", \"domain\": \"" + domainName + "\"}" + utils.WriteOption("TUNNEL_STATUS", status) + } + + return "{\"status\": \"ok\"}" } func taskStopTunnel() string { @@ -1084,6 +1107,16 @@ func taskInstallEdgeApp(args taskInstallEdgeAppArgs) string { return string(resultJSON) } +func taskInstallBulkEdgeApps(args taskInstallBulkEdgeAppsArgs) string { + fmt.Println("Executing taskInstallBulkEdgeApps for " + strings.Join(args.IDS, ", ")) + + // args.Apps is a list of edgeapp ids + edgeapps.SetEdgeAppBulkInstalled(args.IDS) + + taskGetEdgeApps() + return "{\"status\": \"ok\"}" +} + func taskRemoveEdgeApp(args taskRemoveEdgeAppArgs) string { fmt.Println("Executing taskRemoveEdgeApp for " + args.ID) @@ -1290,6 +1323,7 @@ func taskCheckSystemUpdates() string { func taskUpdateSystem() string { fmt.Println("Executing taskUpdateSystem") system.ApplyUpdates() + utils.WriteOption("LAST_UPDATE", strconv.FormatInt(time.Now().Unix(), 10)) return "{result: true}" }