forked from epos-eu/opensource-desktop
-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.go
220 lines (180 loc) · 6.55 KB
/
install.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package main
import (
"bufio"
dockerMethods "github.com/epos-eu/opensource-docker/cmd/methods"
kubernetesMethods "github.com/epos-eu/opensource-kubernetes/cmd/methods"
"database/sql"
"encoding/json"
"fmt"
"os"
"strings"
wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"
_ "github.com/mattn/go-sqlite3"
)
type EposAccessPoints struct {
ApiGateway string `json:"apiGateway"`
DataPortal string `json:"dataPortal"`
}
func (a *App) InstallEnvironment(platform string, environmentSetup EnvironmentSetup, variables []Section, skipImagesAutoupdate bool, isEdit bool) error {
// print for debugging
fmt.Println("Platform: ", platform)
fmt.Println("EnvironmentSetup: ", environmentSetup)
fmt.Println("Variables: ", variables)
fmt.Println("SkipImagesAutoupdate: ", skipImagesAutoupdate)
fmt.Println("IsEdit: ", isEdit)
// Set the flag for the auto update of the images
autoUpdateImages := !skipImagesAutoupdate
var err error
var accessPoints EposAccessPoints
// TODO run the install script
if platform == "docker" {
err = a.installDockerEnvironment(environmentSetup, variables, autoUpdateImages, isEdit)
// Build the access points strings
accessPoints = EposAccessPoints{
DataPortal: "http://" + os.Getenv("API_HOST_ENV") + ":" + os.Getenv("DATA_PORTAL_PORT"),
ApiGateway: "http://" + os.Getenv("API_HOST_ENV") + ":" + os.Getenv("API_PORT") + os.Getenv("DEPLOY_PATH") + os.Getenv("API_PATH") + "/ui/",
}
} else if platform == "kubernetes" {
err = a.installKubernetesEnvironment(environmentSetup, variables, autoUpdateImages, isEdit)
// Build the access points strings
accessPoints = EposAccessPoints{
DataPortal: os.Getenv("PORTAL_URL_READY"),
ApiGateway: os.Getenv("API_URL_READY"),
}
} else {
return fmt.Errorf("unknown platform: %s", platform)
}
if err != nil {
return err
}
// Save the environment to the database
db, err := sql.Open("sqlite3", databasePath)
if err != nil {
return err
}
defer db.Close()
// Convert the variables to a JSON string
variablesJson, err := json.Marshal(variables)
if err != nil {
return err
}
// TODO: maybe get the ports from the environment variables istead of using the values from the variables variable (the deploy might change them if they are already in use)
// Upsert the environment into the database
_, err = db.Exec("INSERT OR REPLACE INTO environments(name, version, platform, dataPortal, apiGateway, variables, context) VALUES(?, ?, ?, ?, ?, ?, ?)",
environmentSetup.Name,
environmentSetup.Version,
platform,
accessPoints.DataPortal,
accessPoints.ApiGateway,
string(variablesJson),
environmentSetup.Context,
)
if err != nil {
return err
}
// Return nil if there was no error
return nil
}
func (a *App) installDockerEnvironment(environmentSetup EnvironmentSetup, variables []Section, autoUpdateImages bool, isEdit bool) error {
// Generate a temporary file with the environment variables
envTempFilePath, err := generateTempFile(os.TempDir(), "configurations", variablesToBinary(variables))
if err != nil {
return err
}
// Add the arguments to the docker command
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
// Create a channel to wait for the command to finish
done := make(chan error)
go func() {
// Run the docker command
err := dockerMethods.CreateEnvironment(
envTempFilePath, // the file with the environment variables
"", // the docker-compose file
"", // external ip
environmentSetup.Name, // the name of the environment
environmentSetup.Version, // the version of the environment
fmt.Sprintf("%t", isEdit), // if the environment is being edited/updated
fmt.Sprintf("%t", autoUpdateImages), // if the images should be updated
)
// back to normal state
w.Close()
os.Stdout = old // restoring the real stdout
done <- err
}()
// Create a scanner to read the output line by line
scanner := bufio.NewScanner(r)
for scanner.Scan() {
// Emit the events to the frontend for each line
wailsRuntime.EventsEmit(a.ctx, "TERMINAL_OUTPUT", scanner.Text())
}
err = <-done // wait for the command to finish
//Remove the temporary file
os.Remove(envTempFilePath)
return err
}
func (a *App) installKubernetesEnvironment(environmentSetup EnvironmentSetup, variables []Section, autoUpdateImages bool, isEdit bool) error {
// Generate a temporary file with the environment variables
envTempFilePath, err := generateTempFile(os.TempDir(), "configurations", variablesToBinary(variables))
if err != nil {
return err
}
old := os.Stdout // keep backup of the real stdout
r, w, _ := os.Pipe()
os.Stdout = w
// Create a channel to wait for the command to finish
done := make(chan error)
go func() {
// Run the kubernetes command
err := kubernetesMethods.CreateEnvironment(
envTempFilePath, // the file with the environment variables
environmentSetup.Context, // the context
environmentSetup.Name, // the namespace
environmentSetup.Version, // the version of the environment
fmt.Sprintf("%t", autoUpdateImages), // if the images should be updated
fmt.Sprintf("%t", isEdit), // if the environment is being edited/updated
)
w.Close()
os.Stdout = old // restoring the real stdout
done <- err
}()
// Create a scanner to read the output line by line
scanner := bufio.NewScanner(r)
for scanner.Scan() {
// Emit the events to the frontend for each line
wailsRuntime.EventsEmit(a.ctx, "TERMINAL_OUTPUT", scanner.Text())
}
err = <-done // wait for the command to finish
//Remove the temporary file
os.Remove(envTempFilePath)
return err
}
// Convert the variables to a binary to be saved in a file
func variablesToBinary(variables []Section) []byte {
var result []string
for _, section := range variables {
variables := section.Variables // a map of variable names to values
for name, value := range variables {
result = append(result, fmt.Sprintf("%s=%s", name, value))
}
}
return []byte(strings.Join(result, "\n"))
}
// Generate a temporary file with the given data and return the file path
func generateTempFile(dname string, filetype string, text []byte) (string, error) {
// If dname already exists, remove it
if _, err := os.Stat(dname); err == nil {
os.RemoveAll(dname)
}
tmpFile, err := os.CreateTemp(dname, filetype)
if err != nil {
return "", err
}
defer tmpFile.Close()
name := tmpFile.Name()
if _, err = tmpFile.Write(text); err != nil {
return "", err
}
return name, nil
}