Explorar o código

[release] v0.13.0-unstable8

Yann Stepienik hai 1 ano
pai
achega
9085b2587c

+ 4 - 1
changelog.md

@@ -1,6 +1,8 @@
 ## Version 0.13.0
  - Display containers as stacks
  - New Delete modal to delete services entirely
+ - Upload custom icons to containers
+ - improve backup file, by splitting cosmos out to a separate docker-compose.yml file
  - Cosmos-networks now have specific names instead for a generic names
  - Fix issue where search bar reset when deleting volume/network
  - Fix breadcrumbs in subpaths
@@ -9,7 +11,8 @@
  - Edit container user and devices from UI
  - Fix bug where Cosmos Constellation's UDP ports by a TCP one
  - Support array command and single device in docker-compose import
- - Add default alert.. by default
+ - Add default alerts... by default (was missing from the default config)
+ - disable few features liks Constellation, Backup and Monitoring when in install mode to reduce logs and prevent issues with the DB
 
 ## Version 0.12.6
  - Fix a security issue with cross-domain APIs availability

+ 1 - 1
client/src/api/index.demo.jsx

@@ -78,7 +78,7 @@ export const checkHost = (host) => {
   });
 }
 
-export const uploadBackground = (file) => {
+export const uploadImage = (file) => {
   return new Promise((resolve, reject) => {
     setTimeout(() => {
       resolve({

+ 5 - 5
client/src/api/index.jsx

@@ -199,10 +199,10 @@ let getDNS = (host) => {
   });
 }
 
-let uploadBackground = (file) => {
+let uploadImage = (file, name) => {
   const formData = new FormData();
-  formData.append('background', file);
-  return wrap(fetch('/cosmos/api/background', {
+  formData.append('image', file);
+  return wrap(fetch('/cosmos/api/upload/' + name, {
     method: 'POST',
     body: formData
   }));
@@ -229,7 +229,7 @@ if(isDemo) {
   isOnline = indexDemo.isOnline;
   checkHost = indexDemo.checkHost;
   getDNS = indexDemo.getDNS;
-  uploadBackground = indexDemo.uploadBackground;
+  uploadImage = indexDemo.uploadImage;
   constellation = constellationDemo;
   metrics = metricsDemo;
 }
@@ -247,5 +247,5 @@ export {
   checkHost,
   getDNS,
   metrics,
-  uploadBackground
+  uploadImage
 };

+ 1 - 0
client/src/pages/config/routes/routeoverview.jsx

@@ -13,6 +13,7 @@ import { CosmosCheckbox } from '../users/formShortcuts';
 import { Field } from 'formik';
 import MiniPlotComponent from '../../dashboard/components/mini-plot';
 import ImageWithPlaceholder from '../../../components/imageWithPlaceholder';
+import UploadButtons from '../../../components/fileUpload';
 
 const info = {
   backgroundColor: 'rgba(0, 0, 0, 0.1)',

+ 6 - 6
client/src/pages/config/users/configman.jsx

@@ -316,10 +316,10 @@ const ConfigManagement = () => {
               <MainCard title="Appearance">
                 <Grid container spacing={3}>
                   <Grid item xs={12}>
-                      {!uploadingBackground && formik.values.Background && <img src=
-                        {formik.values.Background} alt="preview seems broken. Please re-upload."
-                        width={285} />}
-                      {uploadingBackground && <Skeleton variant="rectangular" width={285} height={140} />}
+                    {!uploadingBackground && formik.values.Background && <img src=
+                      {formik.values.Background} alt="preview seems broken. Please re-upload."
+                      width={285} />}
+                    {uploadingBackground && <Skeleton variant="rectangular" width={285} height={140} />}
                      <Stack spacing={1} direction="row">
                       <UploadButtons
                         accept='.jpg, .png, .gif, .jpeg, .webp, .bmp, .avif, .tiff, .svg'
@@ -327,8 +327,8 @@ const ConfigManagement = () => {
                         OnChange={(e) => {
                           setUploadingBackground(true);
                           const file = e.target.files[0];
-                          API.uploadBackground(file).then((data) => {
-                            formik.setFieldValue('Background', "/cosmos/api/background/" + data.data.extension.replace(".", ""));
+                          API.uploadImage(file, "background").then((data) => {
+                            formik.setFieldValue('Background', data.data.path);
                             setUploadingBackground(false);
                           });
                         }}

+ 2 - 2
client/src/pages/servapps/containers/newServiceForm.jsx

@@ -69,9 +69,9 @@ const NewDockerServiceForm = () => {
         image: containerInfo.Config.Image,
         environment: containerInfo.Config.Env,
         labels: containerInfo.Config.Labels,
-        devices: containerInfo.HostConfig.Devices.map((device) => {
+        devices: containerInfo.HostConfig.Devices ? containerInfo.HostConfig.Devices.map((device) => {
           return `${device.PathOnHost}:${device.PathInContainer}:`;
-        }),
+        }) : [],
         expose: containerInfo.Config.ExposedPorts,
         tty: containerInfo.Config.Tty,
         stdin_open: containerInfo.Config.OpenStdin,

+ 20 - 0
client/src/pages/servapps/containers/overview.jsx

@@ -10,6 +10,7 @@ import RestartModal from '../../config/users/restart';
 import GetActions from '../actionBar';
 import { ServAppIcon } from '../../../utils/servapp-icon';
 import MiniPlotComponent from '../../dashboard/components/mini-plot';
+import UploadButtons from '../../../components/fileUpload';
 
 const info = {
   backgroundColor: 'rgba(0, 0, 0, 0.1)',
@@ -87,6 +88,25 @@ const ContainerOverview = ({ containerInfo, config, refresh, updatesAvailable, s
                "dead": <Chip label="Dead" color="error" />,
              })[State.Status]}
             </div>
+            <UploadButtons
+              accept='.jpg, .png, .gif, .jpeg, .webp, .bmp, .avif, .tiff, .svg'
+              label="icon"
+              OnChange={(e) => {
+                const file = e.target.files[0];
+                setIsUpdating(true);
+                API.uploadImage(file, "servapp-" + Name.replace('/', '')).then((data) => {
+                  API.docker.updateContainer(Name.replace('/', ''), {
+                    labels: {
+                      ...Config.Labels,
+                      "cosmos-icon": data.data.path,
+                    }
+                  })
+                  .then(() => {
+                    refreshAll();
+                  });
+                });
+              }}
+            />
           </Stack>
 
           <Stack spacing={2}  style={{ width: '100%' }} >

+ 2 - 2
client/src/pages/servapps/containers/setup.jsx

@@ -71,11 +71,11 @@ const DockerContainerSetup = ({ noCard, containerInfo, installer, OnChange, refr
           labels: Object.keys(containerInfo.Config.Labels).map((key) => {
             return { key, value: containerInfo.Config.Labels[key] };
           }),
-          devices: containerInfo.HostConfig.Devices.map((device) => {
+          devices: containerInfo.HostConfig.Devices ? containerInfo.HostConfig.Devices.map((device) => {
             return (typeof device == "string") ? 
               { key: device.split(":")[0], value: (device.split(":")[1] || device.split(":")[0]) } 
             : { key: device.PathOnHost, value: device.PathInContainer };
-          }),
+          }) : [],
           interactive: containerInfo.Config.Tty && containerInfo.Config.OpenStdin,
         }}
         enableReinitialize

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "cosmos-server",
-  "version": "0.13.0-unstable7",
+  "version": "0.13.0-unstable8",
   "description": "",
   "main": "test-server.js",
   "bugs": {

+ 1 - 0
src/CRON.go

@@ -126,6 +126,7 @@ func CRON() {
 		s.Every(1).Day().At("00:00").Do(func() {
 			utils.CleanupByDate("notifications")
 			utils.CleanupByDate("events")
+			imageCleanUp()
 		})
 		s.Start()
 	}()

+ 0 - 117
src/background.go

@@ -1,117 +0,0 @@
-package main
-
-import (
-	"io/ioutil"
-	"os"
-	"net/http"
-	"path/filepath"
-	"io"
-	"encoding/json"
-
-	"github.com/gorilla/mux"
-	"github.com/azukaar/cosmos-server/src/utils" 
-)
-
-var validExtensions = map[string]bool{
-	".jpg":  true,
-	".jpeg": true,
-	".png":  true,
-	".gif":  true,
-	".bmp":  true,
-	".svg":  true,
-	".webp": true,
-	".tiff": true,
-	".avif": true,
-}
-
-func UploadBackground(w http.ResponseWriter, req *http.Request) {
-	if utils.AdminOnly(w, req) != nil {
-		return
-	}
-
-	if(req.Method == "POST") {
-		// parse the form data
-		err := req.ParseMultipartForm(1 << 20)
-		if err != nil {
-			utils.HTTPError(w, "Error parsing form data", http.StatusInternalServerError, "FORM001")
-			return
-		}
-
-		// retrieve the file part of the form
-		file, header, err := req.FormFile("background")
-		if err != nil {
-			utils.HTTPError(w, "Error retrieving file from form data", http.StatusInternalServerError, "FORM002")
-			return
-		}
-		defer file.Close()
-		
-		// get the file extension
-		ext := filepath.Ext(header.Filename)
-		
-		if !validExtensions[ext] {
-			utils.HTTPError(w, "Invalid file extension " + ext, http.StatusBadRequest, "FILE001")
-			return
-		}
-
-		// create a new file in the config directory
-		dst, err := os.Create(utils.CONFIGFOLDER + "background" + ext)
-		if err != nil {
-			utils.HTTPError(w, "Error creating destination file", http.StatusInternalServerError, "FILE004")
-			return
-		}
-		defer dst.Close()
-
-		// copy the uploaded file to the destination file
-		if _, err := io.Copy(dst, file); err != nil {
-			utils.HTTPError(w, "Error writing to destination file", http.StatusInternalServerError, "FILE005")
-			return
-		}
-
-		// return a response to the client
-		json.NewEncoder(w).Encode(map[string]interface{}{
-			"status": "OK",
-			"data": map[string]interface{}{
-				"filename": header.Filename,
-				"size": header.Size,
-				"extension": ext,
-			},
-		})
-
-	} else {
-		utils.Error("UploadBackground: Method not allowed - " + req.Method, nil)
-		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
-		return
-	}
-}
-
-func GetBackground(w http.ResponseWriter, req *http.Request) {
-	if utils.LoggedInOnly(w, req) != nil {
-		return
-	}
-
-	vars := mux.Vars(req)
-	ext := vars["ext"]
-
-	if !validExtensions["." + ext] {
-		utils.HTTPError(w, "Invalid file extension", http.StatusBadRequest, "FILE001")
-		return
-	}
-
-	if(req.Method == "GET") {
-		// get the background image
-		bg, err := ioutil.ReadFile(utils.CONFIGFOLDER + "background." + ext)
-		if err != nil {
-			utils.HTTPError(w, "Error reading background image", http.StatusInternalServerError, "FILE003")
-			return
-		}
-
-		// return a response to the client
-		w.Header().Set("Content-Type", "image/" + ext)
-		w.Write(bg)
-
-	} else {
-		utils.Error("GetBackground: Method not allowed - " + req.Method, nil)
-		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
-		return
-	}
-}

+ 0 - 2
src/docker/api_blueprint.go

@@ -1013,8 +1013,6 @@ func CreateService(serviceRequest DockerServiceCreateRequest, OnLog func(string)
 func ReOrderServices(serviceMap map[string]ContainerCreateRequestContainer) ([]ContainerCreateRequestContainer, error) {
 	startOrder := []ContainerCreateRequestContainer{}
 
-	utils.Debug(fmt.Sprintf("ReOrderServices:  start: %s", serviceMap))
-
 	for len(serviceMap) > 0 {
 		// Keep track of whether we've added any services in this iteration
 		changed := false

+ 59 - 11
src/docker/export.go

@@ -7,6 +7,8 @@ import (
 	"strconv"
 	"strings"
 	"bytes"
+	"gopkg.in/yaml.v2"
+	"os"
 
 	"github.com/azukaar/cosmos-server/src/utils"
 	"github.com/docker/docker/api/types"
@@ -18,12 +20,17 @@ import (
 var ExportError = "" 
 
 func ExportDocker() {
+	config := utils.GetMainConfig()
+	if config.NewInstall {
+		return
+	}
+
 	ExportError = "" 
 	
 	errD := Connect()
 	if errD != nil {
 		ExportError = "Export Docker - cannot connect - " + errD.Error()
-		utils.Error("ExportDocker - connect - ", errD)
+		utils.MajorError("ExportDocker - connect - ", errD)
 		return
 	}
 
@@ -32,7 +39,7 @@ func ExportDocker() {
 	// List containers
 	containers, err := DockerClient.ContainerList(DockerContext, types.ContainerListOptions{})
 	if err != nil {
-		utils.Error("ExportDocker - Cannot list containers", err)
+		utils.MajorError("ExportDocker - Cannot list containers", err)
 		ExportError = "Export Docker - Cannot list containers - " + err.Error()
 		return
 	}
@@ -44,7 +51,7 @@ func ExportDocker() {
 		// Fetch detailed info of each container
 		detailedInfo, err := DockerClient.ContainerInspect(DockerContext, container.ID)
 		if err != nil {
-			utils.Error("Export Docker - Cannot inspect container" + container.Names[0], err)
+			utils.MajorError("Export Docker - Cannot inspect container" + container.Names[0], err)
 			ExportError = "Export Docker - Cannot inspect container" + container.Names[0] + " - " + err.Error()
 			return
 		}
@@ -118,11 +125,11 @@ func ExportDocker() {
 			// Networks
 			Networks: func() map[string]ContainerCreateRequestServiceNetwork {
 					networks := make(map[string]ContainerCreateRequestServiceNetwork)
-					for netName, netConfig := range detailedInfo.NetworkSettings.Networks {
+					for netName, _ := range detailedInfo.NetworkSettings.Networks {
 							networks[netName] = ContainerCreateRequestServiceNetwork{
-									Aliases:     netConfig.Aliases,
-									IPV4Address: netConfig.IPAddress,
-									IPV6Address: netConfig.GlobalIPv6Address,
+									// Aliases:     netConfig.Aliases,
+									// IPV4Address: netConfig.IPAddress,
+									// IPV6Address: netConfig.GlobalIPv6Address,
 							}
 					}
 					return networks
@@ -175,7 +182,7 @@ func ExportDocker() {
 	// List networks
 	networks, err := DockerClient.NetworkList(DockerContext, types.NetworkListOptions{})
 	if err != nil {
-		utils.Error("Export Docker - Cannot list networks", err)
+		utils.MajorError("Export Docker - Cannot list networks", err)
 		ExportError = "Export Docker - Cannot list networks - " + err.Error()
 		return
 	}
@@ -191,7 +198,7 @@ func ExportDocker() {
 		// Fetch detailed info of each network
 		detailedInfo, err := DockerClient.NetworkInspect(DockerContext, network.ID, types.NetworkInspectOptions{})
 		if err != nil {
-			utils.Error("Export Docker - Cannot inspect network", err)
+			utils.MajorError("Export Docker - Cannot inspect network", err)
 			ExportError = "Export Docker - Cannot inspect network - " + err.Error()
 			return
 		}
@@ -217,6 +224,47 @@ func ExportDocker() {
 		finalBackup.Networks[detailedInfo.Name] = network
 	}
 
+	// remove cosmos from services
+	if os.Getenv("HOSTNAME") != "" {
+		cosmos := services[os.Getenv("HOSTNAME")]
+		delete(services, os.Getenv("HOSTNAME"))
+
+		// export separately cosmos
+		// Create a buffer to hold the JSON output
+		var buf bytes.Buffer
+
+		// Create a new yaml encoder that writes to the buffer
+		encoder := yaml.NewEncoder(&buf)
+
+		// Set escape HTML to false to avoid escaping special characters
+		// encoder.SetEscapeHTML(false)
+		//format
+		// encoder.SetIndent("", "  ")
+
+		// Use the encoder to write the structured data to the buffer
+		toExport := map[string]map[string]ContainerCreateRequestContainer {
+			"services": map[string]ContainerCreateRequestContainer {
+				os.Getenv("HOSTNAME"): cosmos,
+			},
+		}
+
+		err = encoder.Encode(toExport)
+		if err != nil {
+				utils.MajorError("Export Docker - Cannot marshal docker backup", err)
+				ExportError = "Export Docker - Cannot marshal docker backup - " + err.Error()
+		}
+
+		// The JSON data is now in buf.Bytes()
+		yamlData := buf.Bytes()
+
+		// Write the JSON data to a file
+		err = ioutil.WriteFile(utils.CONFIGFOLDER + "cosmos.docker-compose.yaml", yamlData, 0644)
+		if err != nil {
+				utils.MajorError("Export Docker - Cannot save docker backup", err)
+				ExportError = "Export Docker - Cannot save docker backup - " + err.Error()
+		}
+	}
+
 	// Convert the services map to your finalBackup struct
 	finalBackup.Services = services
 
@@ -234,7 +282,7 @@ func ExportDocker() {
 	// Use the encoder to write the structured data to the buffer
 	err = encoder.Encode(finalBackup)
 	if err != nil {
-			utils.Error("Export Docker - Cannot marshal docker backup", err)
+			utils.MajorError("Export Docker - Cannot marshal docker backup", err)
 			ExportError = "Export Docker - Cannot marshal docker backup - " + err.Error()
 	}
 
@@ -244,7 +292,7 @@ func ExportDocker() {
 	// Write the JSON data to a file
 	err = ioutil.WriteFile(utils.CONFIGFOLDER + "backup.cosmos-compose.json", jsonData, 0644)
 	if err != nil {
-		utils.Error("Export Docker - Cannot save docker backup", err)
+		utils.MajorError("Export Docker - Cannot save docker backup", err)
 		ExportError = "Export Docker - Cannot save docker backup - " + err.Error()
 	}
 }

+ 2 - 2
src/httpServer.go

@@ -392,8 +392,8 @@ func InitServer() *mux.Router {
 	
 	srapi.HandleFunc("/api/markets", market.MarketGet)
 
-	srapi.HandleFunc("/api/background", UploadBackground)
-	srapi.HandleFunc("/api/background/{ext}", GetBackground)
+	srapi.HandleFunc("/api/upload/{name}", UploadImage)
+	srapi.HandleFunc("/api/image/{name}", GetImage)
 
 	srapi.HandleFunc("/api/get-backup", configapi.BackupFileApiGet)
 

+ 204 - 0
src/image.go

@@ -0,0 +1,204 @@
+package main
+
+import (
+	"io/ioutil"
+	"os"
+	"net/http"
+	"path/filepath"
+	"io"
+	"encoding/json"
+	"strings"
+	"fmt"
+
+	"github.com/gorilla/mux"
+	"github.com/azukaar/cosmos-server/src/utils" 
+	"github.com/azukaar/cosmos-server/src/docker" 
+)
+
+var validExtensions = map[string]bool{
+	".jpg":  true,
+	".jpeg": true,
+	".png":  true,
+	".gif":  true,
+	".bmp":  true,
+	".svg":  true,
+	".webp": true,
+	".tiff": true,
+	".avif": true,
+}
+
+func UploadImage(w http.ResponseWriter, req *http.Request) {
+	if utils.AdminOnly(w, req) != nil {
+		return
+	}
+	
+	vars := mux.Vars(req)
+	originalName := vars["name"]
+
+	name := originalName + "-" + utils.GenerateRandomString(6)
+
+	// if name includes / or ..
+	if filepath.Clean(name) != name || strings.Contains(name, "/") {
+		utils.HTTPError(w, "Invalid file name", http.StatusBadRequest, "FILE002")
+		return
+	}
+
+	if(req.Method == "POST") {
+		// if the uploads directory does not exist, create it
+		if _, err := os.Stat(utils.CONFIGFOLDER + "/uploads"); os.IsNotExist(err) {
+			os.Mkdir(utils.CONFIGFOLDER + "/uploads", 0750)
+		}
+
+		// parse the form data
+		err := req.ParseMultipartForm(1 << 20)
+		if err != nil {
+			utils.HTTPError(w, "Error parsing form data", http.StatusInternalServerError, "FORM001")
+			return
+		}
+
+		// retrieve the file part of the form
+		file, header, err := req.FormFile("image")
+		if err != nil {
+			utils.HTTPError(w, "Error retrieving file from form data", http.StatusInternalServerError, "FORM002")
+			return
+		}
+		defer file.Close()
+		
+		// get the file extension
+		ext := filepath.Ext(header.Filename)
+		
+		if !validExtensions[ext] {
+			utils.HTTPError(w, "Invalid file extension " + ext, http.StatusBadRequest, "FILE001")
+			return
+		}
+
+		// create a new file in the config directory
+		dst, err := os.Create(utils.CONFIGFOLDER + "/uploads/" + name + ext)
+		if err != nil {
+			utils.HTTPError(w, "Error creating destination file", http.StatusInternalServerError, "FILE004")
+			return
+		}
+		defer dst.Close()
+
+		// copy the uploaded file to the destination file
+		if _, err := io.Copy(dst, file); err != nil {
+			utils.HTTPError(w, "Error writing to destination file", http.StatusInternalServerError, "FILE005")
+			return
+		}
+
+		// return a response to the client
+		json.NewEncoder(w).Encode(map[string]interface{}{
+			"status": "OK",
+			"data": map[string]interface{}{
+				"path": "/cosmos/api/image/" + name + ext,
+				"filename": header.Filename,
+				"size": header.Size,
+				"extension": ext,
+			},
+		})
+
+	} else {
+		utils.Error("UploadBackground: Method not allowed - " + req.Method, nil)
+		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
+		return
+	}
+}
+
+func GetImage(w http.ResponseWriter, req *http.Request) {
+	if utils.LoggedInOnly(w, req) != nil {
+		return
+	}
+
+	utils.Log("API: GetImage")
+
+	vars := mux.Vars(req)
+	name := vars["name"]
+
+	// if name includes / or ..
+	if filepath.Clean(name) != name || strings.Contains(name, "/") {
+		utils.Error("GetBackground: Invalid file name - " + name, nil)
+		utils.HTTPError(w, "Invalid file name", http.StatusBadRequest, "FILE002")
+		return
+	}
+
+	// get the file extension
+	ext := filepath.Ext(name)
+
+	if !validExtensions[ext] {
+		utils.Error("GetBackground: Invalid file extension - " + ext, nil)
+		utils.HTTPError(w, "Invalid file extension", http.StatusBadRequest, "FILE001")
+		return
+	}
+
+	if(req.Method == "GET") {
+		// get the background image
+		bg, err := ioutil.ReadFile(utils.CONFIGFOLDER + "/uploads/" + name)
+		if err != nil {
+			utils.Error("GetBackground: Error reading image - " + name, err)
+			utils.HTTPError(w, "Error reading image", http.StatusInternalServerError, "FILE003")
+			return
+		}
+
+		// return a response to the client
+		w.Header().Set("Content-Type", "image/" + ext)
+		w.Write(bg)
+
+	} else {
+		utils.Error("GetBackground: Method not allowed - " + req.Method, nil)
+		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
+		return
+	}
+}
+
+func imageCleanUp() {
+	utils.Log("Image cleanup")
+
+	config := utils.GetMainConfig()
+	images := map[string]bool{}
+	images[config.HomepageConfig.Background] = true
+
+	for _, route := range config.HTTPConfig.ProxyConfig.Routes {
+		if(route.Icon != "") {
+			images[route.Icon] = true
+		}
+	}
+
+	// get containers
+	containers, err := docker.ListContainers()
+
+	if err != nil {
+		utils.Error("Image cleanup: Error getting containers", err)
+		return
+	}
+
+	for _, container := range containers {
+		if(container.Labels["cosmos-icon"] != "") {
+			images[container.Labels["cosmos-icon"]] = true
+		}
+	}
+
+	fmt.Println(images)
+
+	// if the uploads directory does not exist, return
+	if _, err := os.Stat(utils.CONFIGFOLDER + "/uploads"); os.IsNotExist(err) {
+		return
+	}
+
+	// get the files in the uploads directory
+	files, err := ioutil.ReadDir(utils.CONFIGFOLDER + "/uploads")
+	if err != nil {
+		utils.Error("Image cleanup: Error reading directory", err)
+		return
+	}
+
+	// loop through the files
+	base := "/cosmos/api/image/"
+	for _, f := range files {
+		if(!images[base + f.Name()]) {
+			err := os.Remove(utils.CONFIGFOLDER + "/uploads/" + f.Name())
+			if err != nil {
+				utils.Error("Image cleanup: Error removing file", err)
+			}
+		}
+	}
+}

+ 17 - 12
src/index.go

@@ -45,25 +45,30 @@ func main() {
 		utils.Log("Docker API version: " + version.APIVersion)
 	}
 
-	utils.Log("Starting monitoring services...")
+	config := utils.GetMainConfig()
+	if !config.NewInstall {
 
-	metrics.Init()
+		utils.Log("Starting monitoring services...")
 
-	utils.Log("Starting market services...")
+		metrics.Init()
 
-	market.Init()
-	
-	utils.Log("Starting OpenID services...")
+		utils.Log("Starting market services...")
 
-	authorizationserver.Init()
+		market.Init()
+		
+		utils.Log("Starting OpenID services...")
 
-	utils.Log("Starting constellation services...")
+		authorizationserver.Init()
 
-	constellation.InitDNS()
-	
-	constellation.Init()
+		utils.Log("Starting constellation services...")
+
+		constellation.InitDNS()
+		
+		constellation.Init()
 
-	utils.Log("Starting server...")
+		utils.Log("Starting server...")
+
+	}
 
 	StartServer()
 }

+ 1 - 0
src/utils/types.go

@@ -188,6 +188,7 @@ type ProxyRouteConfig struct {
 	RestrictToConstellation bool
 	OverwriteHostHeader string
 	WhitelistInboundIPs []string
+	Icon string
 }
 
 type EmailConfig struct {