package main import ( "bytes" "compress/gzip" "io" "os" "path/filepath" restful "github.com/emicklei/go-restful" "gopkg.in/yaml.v2" "m.cluseau.fr/go/httperr" "novit.tech/direktil/pkg/localconfig" ) func wsUploadConfig(req *restful.Request, resp *restful.Response) { cfg := &localconfig.Config{} if err := req.ReadEntity(cfg); err != nil { wsError(resp, httperr.BadRequest(err.Error())) return } cfgBytes, err := yaml.Marshal(cfg) if err != nil { wsError(resp, err) return } err = writeNewConfig(cfgBytes) if err != nil { wsError(resp, err) return } resp.WriteEntity(true) } func writeNewConfig(cfgBytes []byte) (err error) { out, err := os.CreateTemp(*dataDir, ".config-upload") if err != nil { return } defer os.Remove(out.Name()) _, err = io.Copy(out, bytes.NewReader(cfgBytes)) out.Close() if err != nil { return } cfgPath := configFilePath() in, err := os.Open(cfgPath) if err != nil { if os.IsNotExist(err) { // nothing to backup } else { return // real error } } else { err = backupCurrentConfig(in) if err != nil { return } } err = os.Rename(out.Name(), cfgPath) updateState() return } func backupCurrentConfig(in io.ReadCloser) (err error) { archivesPath := filepath.Join(*dataDir, "archives") err = os.MkdirAll(archivesPath, 0700) if err != nil { return } backupPath := filepath.Join(archivesPath, "config."+ulid()+".yaml.gz") bck, err := os.Create(backupPath) if err != nil { return } defer bck.Close() gz, err := gzip.NewWriterLevel(bck, 2) if err != nil { return } _, err = io.Copy(gz, in) gz.Close() in.Close() return }