func (r *RouterHaProxy) Update(serviceReports []ServiceReport) error { reloadNeeded := r.socketPath == "" for _, report := range serviceReports { front, back, err := r.toFrontendAndBackend(report) if err != nil { return errs.WithEF(err, r.RouterCommon.fields.WithField("report", report), "Failed to prepare frontend and backend") } r.Frontend[report.Service.Name+"_"+strconv.Itoa(report.Service.id)] = front r.Backend[report.Service.Name+"_"+strconv.Itoa(report.Service.id)] = back if !r.isSocketUpdatable(report) { reloadNeeded = true } } if reloadNeeded { if err := r.Reload(); err != nil { return errs.WithEF(err, r.RouterCommon.fields, "Failed to reload haproxy") } } else if err := r.SocketUpdate(); err != nil { r.synapse.routerUpdateFailures.WithLabelValues(r.Type + PrometheusLabelSocketSuffix).Inc() logs.WithEF(err, r.RouterCommon.fields).Error("Update by Socket failed. Reloading instead") if err := r.Reload(); err != nil { return errs.WithEF(err, r.RouterCommon.fields, "Failed to reload haproxy") } } return nil }
func (b *Builder) tarAci() error { upperId, err := b.upperTreeStoreId() if err != nil { return err } upperPath := b.pod.Root + PATH_OVERLAY + "/" + upperId + PATH_UPPER upperNamedRootfs := upperPath + "/" + manifestApp(b.pod).Name.String() upperRootfs := upperPath + common.PathRootfs if err := os.Rename(upperNamedRootfs, upperRootfs); err != nil { // TODO this is dirty and can probably be renamed during tar return errs.WithEF(err, b.fields.WithField("path", upperNamedRootfs), "Failed to rename rootfs") } defer os.Rename(upperRootfs, upperNamedRootfs) dir, err := os.Getwd() if err != nil { return errs.WithEF(err, b.fields, "Failed to get current working directory") } defer func() { if err := os.Chdir(dir); err != nil { logs.WithEF(err, b.fields.WithField("path", dir)).Warn("Failed to chdir back") } }() if err := os.Chdir(upperPath); err != nil { return errs.WithEF(err, b.fields.WithField("path", upperPath), "Failed to chdir to upper base path") } if err := common.Tar(b.aciTargetPath+common.PathImageAci, common.PathManifest[1:], common.PathRootfs[1:]+"/"); err != nil { return errs.WithEF(err, b.fields, "Failed to tar aci") } logs.WithField("path", dir).Debug("chdir") return nil }
func (b *Builder) Build() error { logs.WithF(b.fields).Info("Building aci") lfd, err := rktcommon.GetRktLockFD() if err != nil { return errs.WithEF(err, b.fields, "can't get rkt lock fd") } if err := sys.CloseOnExec(lfd, true); err != nil { return errs.WithEF(err, b.fields, "can't set FD_CLOEXEC on rkt lock") } if err := b.runBuild(); err != nil { return err } if err := b.writeManifest(); err != nil { return err } if err := b.tarAci(); err != nil { return err } return nil }
func RouterFromJson(content []byte, s *Synapse) (Router, error) { t := &RouterCommon{} if err := json.Unmarshal([]byte(content), t); err != nil { return nil, errs.WithE(err, "Failed to unmarshall check type") } fields := data.WithField("type", t.Type) var typedRouter Router switch t.Type { case "console": typedRouter = NewRouterConsole() case "haproxy": typedRouter = NewRouterHaProxy() case "template": typedRouter = NewRouterTemplate() default: return nil, errs.WithF(fields, "Unsupported router type") } if err := json.Unmarshal([]byte(content), &typedRouter); err != nil { return nil, errs.WithEF(err, fields, "Failed to unmarshall router") } if err := typedRouter.Init(s); err != nil { return nil, errs.WithEF(err, fields, "Failed to init router") } return typedRouter, nil }
func (r *RouterTemplate) Update(reports []ServiceReport) error { buff := bytes.Buffer{} writer := bufio.NewWriter(&buff) if err := r.tmpl.Execute(writer, reports); err != nil { return errs.WithEF(err, r.fields, "Templating execution failed") } if err := writer.Flush(); err != nil { return errs.WithEF(err, r.fields, "Failed to flush buffer") } buff.WriteByte('\n') if err := os.MkdirAll(filepath.Dir(r.DestinationFile), 0755); err != nil { return errs.WithEF(err, r.fields, "Cannot create directories") } if err := ioutil.WriteFile(r.DestinationFile, buff.Bytes(), r.DestinationFileMode); err != nil { return errs.WithEF(err, r.fields, "Failed to write destination file") } if len(r.PostTemplateCommand) > 0 { if err := nerve.ExecCommand(r.PostTemplateCommand, r.PostTemplateCommandTimeoutInMilli); err != nil { return errs.WithEF(err, r.fields, "Post template command failed") } } return nil }
func ReporterFromJson(data []byte, s *Service) (Reporter, error) { t := &ReporterCommon{} if err := json.Unmarshal([]byte(data), t); err != nil { return nil, errs.WithE(err, "Failed to unmarshall reporter type") } fields := s.fields.WithField("type", t.Type) var typedReporter Reporter switch t.Type { case "file": typedReporter = NewReporterFile() case "console": typedReporter = NewReporterConsole() case "zookeeper": typedReporter = NewReporterZookeeper() default: return nil, errs.WithF(fields, "Unsupported reporter type") } if err := json.Unmarshal([]byte(data), &typedReporter); err != nil { return nil, errs.WithEF(err, fields, "Failed to unmarshall reporter") } if err := typedReporter.getCommon().Init(s); err != nil { return nil, errs.WithEF(err, fields, "Failed to init common reporter") } if err := typedReporter.Init(s); err != nil { return nil, errs.WithEF(err, fields, "Failed to init reporter") } return typedReporter, nil }
func ExtractManifestContentFromAci(aciPath string) ([]byte, error) { fields := data.WithField("file", aciPath) input, err := os.Open(aciPath) if err != nil { return nil, errs.WithEF(err, fields, "Cannot open file") } defer input.Close() tr, err := aci.NewCompressedTarReader(input) if err != nil { return nil, errs.WithEF(err, fields, "Cannot open file as tar") } Tar: for { hdr, err := tr.Next() switch err { case io.EOF: break Tar case nil: if filepath.Clean(hdr.Name) == aci.ManifestFile { bytes, err := ioutil.ReadAll(tr) if err != nil { return nil, errs.WithEF(err, fields, "Cannot read manifest content in tar") } return bytes, nil } default: return nil, errs.WithEF(err, fields, "error reading tarball file") } } return nil, errs.WithEF(err, fields, "Cannot found manifest in file") }
func ExecCommandFull(cmd []string, env []string, timeoutInMilli int) error { command := exec.Command(cmd[0], cmd[1:]...) var b bytes.Buffer command.Stdout = &b command.Stderr = &b command.Env = env if err := command.Start(); err != nil { return errs.WithEF(err, data.WithField("cmd", cmd), "Failed to start command") } var after *errs.EntryError timer := time.AfterFunc(time.Duration(timeoutInMilli)*time.Millisecond, func() { data := data.WithField("command", strings.Join(cmd, " ")).WithField("timeout", timeoutInMilli) logs.WithF(data).Debug("Command timeout") after = errs.WithF(data, "Exec command timeout") command.Process.Kill() }) err := command.Wait() timer.Stop() if logs.IsTraceEnabled() { logs.WithField("cmd", cmd).WithField("output", string(b.Bytes())).Trace("Command output") } if err != nil { return errs.WithEF(err, data.WithField("cmd", cmd). WithField("output", string(b.Bytes())), "Command failed"). WithErr(after) } return nil }
func (aci *Aci) prepareBuildAci() (string, error) { logs.WithFields(aci.fields).Debug("Preparing builder") if err := os.MkdirAll(aci.target+pathBuilder+common.PathRootfs, 0777); err != nil { return "", errs.WithEF(err, aci.fields.WithField("path", aci.target+pathBuilder), "Failed to create builder aci path") } if err := ioutil.WriteFile(aci.target+pathBuilder+common.PathRootfs+"/.keep", []byte(""), 0644); err != nil { return "", errs.WithEF(err, aci.fields.WithField("file", aci.target+pathBuilder+common.PathRootfs+"/.keep"), "Failed to write keep file") } aci.manifest.Aci.App.Isolators = []common.Isolator{{Name: "os/linux/capabilities-retain-set", Value: common.LinuxCapabilitiesSetValue{Set: []types.LinuxCapability{"all"}}}} if err := common.WriteAciManifest(aci.manifest, aci.target+pathBuilder+common.PathManifest, common.PrefixBuilder+aci.manifest.NameAndVersion.Name(), dgrVersion); err != nil { return "", err } if err := aci.tarAci(aci.target + pathBuilder); err != nil { return "", err } logs.WithF(aci.fields.WithField("path", aci.target+pathBuilder+pathImageAci)).Info("Importing build to rkt") hash, err := Home.Rkt.FetchInsecure(aci.target + pathBuilder + pathImageAci) if err != nil { return "", errs.WithEF(err, aci.fields, "fetch of builder aci failed") } return hash, nil }
func NewAciWithManifest(path string, args BuildArgs, manifest spec.AciManifest, checked *chan bool) (*Aci, error) { if manifest.NameAndVersion == "" { logs.WithField("path", path).Fatal("name is mandatory in manifest") } fields := data.WithField("aci", manifest.NameAndVersion.String()) logs.WithF(fields).WithFields(data.Fields{"args": args, "path": path, "manifest": manifest}).Debug("New aci") fullPath, err := filepath.Abs(path) if err != nil { return nil, errs.WithEF(err, fields, "Cannot get fullpath of project") } target := fullPath + PATH_TARGET if cnt.Home.Config.TargetWorkDir != "" { currentAbsDir, err := filepath.Abs(cnt.Home.Config.TargetWorkDir + "/" + manifest.NameAndVersion.ShortName()) if err != nil { return nil, errs.WithEF(err, fields.WithField("path", path), "Invalid target path") } target = currentAbsDir } aci := &Aci{ fields: fields, args: args, path: fullPath, manifest: manifest, target: target, rootfs: target + PATH_ROOTFS, FullyResolveDep: true, } go aci.checkLatestVersions(checked) return aci, nil }
func (p *Pod) buildAci(e common.RuntimeApp) (*Aci, error) { if err := p.fillRuntimeAppFromDependencies(&e); err != nil { return nil, err } aci, err := p.toPodAci(e) if err != nil { return nil, err } aci.Clean() // TODO attributes should be builder dependent only if empty, err := common.IsDirEmpty(p.path + "/attributes"); !empty && err == nil { path := aci.target + pathBuilder + common.PathRootfs + "/dgr/pod/attributes" if err := os.MkdirAll(path, 0777); err != nil { return nil, errs.WithEF(err, aci.fields.WithField("path", path), "Failed to create pod attributes directory in builder") } if err := common.CopyDir(p.path+"/attributes", path); err != nil { return nil, errs.WithEF(err, aci.fields, "Failed to copy pod attributes to aci builder") } } if err := aci.Build(); err != nil { return nil, errs.WithEF(err, p.fields.WithField("name", e.Name), "build of pod's aci failed") } return aci, nil }
func (aci *Aci) upload(name *common.ACFullname) error { if Home.Config.Push.Type == "maven" && name.DomainName() == "aci.blbl.cr" { // TODO this definitely need to be removed logs.WithF(aci.fields).Info("Uploading aci") if err := common.ExecCmd("curl", "-f", "-i", "-F", "r=releases", "-F", "hasPom=false", "-F", "e=aci", "-F", "g=com.blablacar.aci.linux.amd64", "-F", "p=aci", "-F", "v="+name.Version(), "-F", "a="+strings.Split(string(name.Name()), "/")[1], "-F", "file=@"+aci.target+pathImageGzAci, "-u", Home.Config.Push.Username+":"+Home.Config.Push.Password, Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil { return errs.WithEF(err, aci.fields, "Failed to push aci") } } else { systemConf := Home.Config.Rkt.SystemConfig if systemConf == "" { systemConf = "/usr/lib/rkt" } localConf := Home.Config.Rkt.LocalConfig if localConf == "" { localConf = "/etc/rkt" } conf, err := config.GetConfigFrom(systemConf, localConf) if err != nil { return errs.WithEF(err, aci.fields, "Failed to get rkt configuration") } upload := Uploader{ Acipath: aci.target + pathImageGzAci, Ascpath: aci.target + pathImageGzAciAsc, Uri: aci.manifest.NameAndVersion.String(), Debug: false, SetHTTPHeaders: func(r *http.Request) { if r.URL == nil { return } headerer, ok := conf.AuthPerHost[r.URL.Host] if !ok { logs.WithFields(aci.fields).WithField("domain", r.URL.Host). Warn("No auth credential found in rkt configuration for this domain") return } header := headerer.Header() for k, v := range header { r.Header[k] = append(r.Header[k], v...) } }, } err = upload.Upload() if err != nil { return errs.WithEF(err, aci.fields, "Failed to upload aci") } } return nil }
func (aci *Aci) prepareBuildAci() (string, error) { logs.WithFields(aci.fields).Debug("Preparing builder") if err := os.MkdirAll(aci.target+pathBuilder+common.PathRootfs, 0777); err != nil { return "", errs.WithEF(err, aci.fields.WithField("path", aci.target+pathBuilder), "Failed to create builder aci path") } if err := ioutil.WriteFile(aci.target+pathBuilder+common.PathRootfs+"/.keep", []byte(""), 0644); err != nil { return "", errs.WithEF(err, aci.fields.WithField("file", aci.target+pathBuilder+common.PathRootfs+"/.keep"), "Failed to write keep file") } if err := common.WriteAciManifest(aci.manifest, aci.target+pathBuilder+common.PathManifest, common.PrefixBuilder+aci.manifest.NameAndVersion.Name(), dgrVersion); err != nil { return "", err } if err := aci.tarAci(aci.target + pathBuilder); err != nil { return "", err } logs.WithF(aci.fields.WithField("path", aci.target+pathBuilder+pathImageAci)).Info("Importing build to rkt") hash, err := Home.Rkt.Fetch(aci.target + pathBuilder + pathImageAci) if err != nil { return "", errs.WithEF(err, aci.fields, "fetch of builder aci failed") } return hash, nil }
func (p *Pod) buildAci(e common.RuntimeApp) (*Aci, error) { if err := p.fillRuntimeAppFromDependencies(&e); err != nil { return nil, err } path := p.path + "/" + e.Name if dir, err := os.Stat(path); err != nil || !dir.IsDir() { path = p.target + "/" + e.Name if err := os.Mkdir(path, 0777); err != nil { return nil, errs.WithEF(err, p.fields.WithField("path", path), "Cannot created pod's aci directory") } } tmpl, err := p.toAciManifestTemplate(e) if err != nil { return nil, err } aci, err := NewAciWithManifest(path, p.args, tmpl, p.checkWg) if err != nil { return nil, errs.WithEF(err, p.fields.WithField("aci", path), "Failed to prepare aci") } aci.podName = &p.manifest.Name if err := aci.CleanAndBuild(); err != nil { return nil, errs.WithEF(err, p.fields.WithField("name", e.Name), "build of pod's aci failed") } return aci, nil }
func (aci *Aci) prepareBuildAci() (string, error) { logs.WithFields(aci.fields).Debug("Preparing builder") if err := os.MkdirAll(aci.target+pathBuilder+common.PathRootfs, 0777); err != nil { return "", errs.WithEF(err, aci.fields.WithField("path", aci.target+pathBuilder), "Failed to create builder aci path") } if err := ioutil.WriteFile(aci.target+pathBuilder+common.PathRootfs+"/.keep", []byte(""), 0644); err != nil { return "", errs.WithEF(err, aci.fields.WithField("file", aci.target+pathBuilder+common.PathRootfs+"/.keep"), "Failed to write keep file") } capa, err := types.NewLinuxCapabilitiesRetainSet("all") if err != nil { return "", errs.WithEF(err, aci.fields, "Failed to create all capability retain Set") } allIsolator, err := capa.AsIsolator() if err != nil { return "", errs.WithEF(err, aci.fields, "Failed to prepare all retain set isolator") } aci.manifest.Aci.App.Isolators = types.Isolators([]types.Isolator{*allIsolator}) if err := common.WriteAciManifest(aci.manifest, aci.target+pathBuilder+common.PathManifest, common.PrefixBuilder+aci.manifest.NameAndVersion.Name(), BuildVersion); err != nil { return "", err } if err := aci.tarAci(aci.target + pathBuilder); err != nil { return "", err } logs.WithF(aci.fields.WithField("path", aci.target+pathBuilder+pathImageAci)).Info("Importing build to rkt") hash, err := Home.Rkt.FetchInsecure(aci.target + pathBuilder + pathImageAci) if err != nil { return "", errs.WithEF(err, aci.fields, "fetch of builder aci failed") } return hash, nil }
func CheckerFromJson(data []byte, s *Service) (Checker, error) { t := &CheckCommon{} if err := json.Unmarshal([]byte(data), t); err != nil { return nil, errs.WithE(err, "Failed to unmarshall check type") } fields := s.fields.WithField("type", t.Type) var typedCheck Checker switch t.Type { case "http": typedCheck = NewCheckHttp() case "proxyhttp": typedCheck = NewCheckProxyHttp() case "tcp": typedCheck = NewCheckTcp() case "sql": typedCheck = NewCheckSql() case "amqp": typedCheck = NewCheckAmqp() case "exec": typedCheck = NewCheckExec() default: return nil, errs.WithF(fields, "Unsupported check type") } if err := json.Unmarshal([]byte(data), &typedCheck); err != nil { return nil, errs.WithEF(err, fields, "Failed to unmarshall check") } if err := typedCheck.Init(s); err != nil { return nil, errs.WithEF(err, fields, "Failed to init check") } return typedCheck, nil }
func (aci *Aci) buildTestAci() (string, error) { manifest, err := common.ExtractManifestFromAci(aci.target + common.PathImageAci) if err != nil { return "", errs.WithEF(err, aci.fields.WithField("file", aci.target+common.PathImageAci), "Failed to extract manifest from aci") } name := prefixTest + manifest.Name.String() if version, ok := manifest.Labels.Get("version"); ok { name += ":" + version } fullname := common.NewACFullName(name) resultMountName, _ := types.NewACName(mountAcname) aciManifest := &common.AciManifest{ Builder: aci.manifest.Tester.Builder, Aci: common.AciDefinition{ App: common.DgrApp{ Exec: aci.manifest.Aci.App.Exec, MountPoints: []types.MountPoint{{Path: pathTestsResult, Name: *resultMountName}}, WorkingDirectory: aci.manifest.Aci.App.WorkingDirectory, User: aci.manifest.Aci.App.User, Group: aci.manifest.Aci.App.Group, SupplementaryGIDs: aci.manifest.Aci.App.SupplementaryGIDs, Environment: aci.manifest.Aci.App.Environment, Ports: aci.manifest.Aci.App.Ports, Isolators: aci.manifest.Aci.App.Isolators, }, Dependencies: append(aci.manifest.Tester.Aci.Dependencies, *common.NewACFullName(name[len(prefixTest):])), Annotations: aci.manifest.Aci.Annotations, PathWhitelist: aci.manifest.Aci.PathWhitelist, }, NameAndVersion: *fullname, } content, err := yaml.Marshal(aciManifest) if err != nil { return "", errs.WithEF(err, aci.fields, "Failed to marshall manifest for test aci") } testAci, err := NewAciWithManifest(aci.path, aci.args, string(content), aci.checkWg) if err != nil { return "", errs.WithEF(err, aci.fields, "Failed to prepare test's build aci") } testAci.FullyResolveDep = false // this is required to run local tests without discovery testAci.target = aci.target + pathTestsTarget if err := testAci.CleanAndBuild(); err != nil { return "", errs.WithEF(err, aci.fields, "Build of test aci failed") } hash, err := Home.Rkt.Fetch(aci.target + pathTestsTarget + pathImageAci) if err != nil { return "", errs.WithEF(err, aci.fields, "fetch of test aci failed") } return hash, nil }
func (hap *HaProxyClient) SocketUpdate() error { if hap.socketPath == "" { return errs.WithF(hap.fields, "No socket file specified. Cannot update") } logs.WithF(hap.fields).Debug("Updating haproxy by socket") if err := hap.writeConfig(); err != nil { // just to stay in sync logs.WithEF(err, hap.fields).Warn("Failed to write configuration file") } conn, err := net.Dial("unix", hap.socketPath) if err != nil { return errs.WithEF(err, hap.fields.WithField("socket", hap.socketPath), "Failed to connect to haproxy socket") } defer conn.Close() i := 0 b := bytes.Buffer{} for name, servers := range hap.Backend { for _, server := range servers { res := hap.weightRegex.FindStringSubmatch(server) if len(res) == 3 { i++ b.WriteString("set weight " + name + "/" + res[1] + " " + res[2] + "\n") } } } if b.Len() == 0 { logs.WithF(hap.fields).Debug("Nothing to update by socket. No weight set") return nil } commands := b.Bytes() logs.WithF(hap.fields.WithField("command", string(commands))).Trace("Running command on hap socket") count, err := conn.Write(commands) if count != len(commands) || err != nil { return errs.WithEF(err, hap.fields. WithField("written", count). WithField("len", len(commands)). WithField("command", string(commands)), "Failed to write command to haproxy") } buff := bufio.NewReader(conn) line, prefix, err := buff.ReadLine() if err != nil || prefix { return errs.WithEF(err, hap.fields.WithField("line-too-long", prefix), "Failed to read hap socket response") } if string(line) != "" { return errs.WithF(hap.fields.WithField("response", string(line)), "Bad response for haproxy socket command") } return nil }
func WritePodManifest(im *schema.PodManifest, targetFile string) error { buff, err := json.MarshalIndent(im, "", " ") if err != nil { return errs.WithEF(err, data.WithField("object", im), "Failed to marshal manifest") } err = ioutil.WriteFile(targetFile, []byte(buff), 0644) if err != nil { return errs.WithEF(err, data.WithField("file", targetFile), "Failed to write pod manifest") } return nil }
func (p *Pod) processAci(e common.RuntimeApp) (*schema.RuntimeApp, error) { aci, err := p.buildAci(e) if err != nil { return nil, err } name, err := types.NewACName(e.Name) if err != nil { return nil, errs.WithEF(err, p.fields.WithField("name", e.Name), "Invalid name format") } sum, err := Sha512sum(aci.target + pathImageAci) if err != nil { return nil, errs.WithEF(err, p.fields.WithField("file", aci.target+pathImageAci), "Failed to calculate sha512 of aci") } tmp, _ := types.NewHash("sha512-" + sum) labels := types.Labels{} labels = append(labels, types.Label{Name: "version", Value: aci.manifest.NameAndVersion.Version()}) identifier, _ := types.NewACIdentifier(aci.manifest.NameAndVersion.Name()) ttmp := schema.RuntimeImage{Name: identifier, ID: *tmp, Labels: labels} e.App.Group = aci.manifest.Aci.App.Group e.App.User = aci.manifest.Aci.App.User if e.App.User == "" { e.App.User = "******" } if e.App.Group == "" { e.App.Group = "0" } isolators, err := common.ToAppcIsolators(e.App.Isolators) if err != nil { return nil, errs.WithEF(err, p.fields, "Failed to prepare isolators") } return &schema.RuntimeApp{ Name: *name, Image: ttmp, App: &types.App{ Exec: e.App.Exec, User: e.App.User, Group: e.App.Group, WorkingDirectory: e.App.WorkingDirectory, SupplementaryGIDs: e.App.SupplementaryGIDs, Environment: e.App.Environment, MountPoints: e.App.MountPoints, Ports: e.App.Ports, Isolators: isolators, }, Mounts: e.Mounts, Annotations: e.Annotations}, nil }
func (p *Pod) fillRuntimeAppFromDependencies(e *common.RuntimeApp) error { fields := p.fields.WithField("aci", e.Name) if len(e.Dependencies) >= 1 { Home.Rkt.Fetch(e.Dependencies[0].String()) manifestStr, err := Home.Rkt.CatManifest(e.Dependencies[0].String()) if err != nil { return errs.WithEF(err, fields.WithField("dependency", e.Dependencies[0].String()), "Failed to get dependency manifest") } manifest := schema.ImageManifest{} if err := json.Unmarshal([]byte(manifestStr), &manifest); err != nil { return errs.WithEF(err, fields.WithField("content", manifestStr), "Failed to unmarshal stage1 manifest received from rkt") } if len(e.App.Exec) == 0 { e.App.Exec = manifest.App.Exec } if e.App.User == "" { e.App.User = manifest.App.User } if e.App.Group == "" { e.App.Group = manifest.App.Group } if e.App.WorkingDirectory == "" { e.App.WorkingDirectory = manifest.App.WorkingDirectory } if len(e.App.SupplementaryGIDs) == 0 { e.App.SupplementaryGIDs = manifest.App.SupplementaryGIDs } if len(e.App.Isolators) == 0 { res, err := common.FromAppcIsolators(manifest.App.Isolators) if err != nil { return errs.WithEF(err, fields, "Failed to replicate isolators from aci to pod") } e.App.Isolators = res } if len(e.App.Ports) == 0 { e.App.Ports = manifest.App.Ports } if len(e.App.MountPoints) == 0 { e.App.MountPoints = manifest.App.MountPoints } if len(e.App.Environment) == 0 { e.App.Environment = manifest.App.Environment } anns := e.Annotations e.Annotations = manifest.Annotations for _, ann := range anns { e.Annotations.Set(ann.Name, ann.Value) } } return nil }
func ExtractManifestFromAci(aciPath string) (*schema.ImageManifest, error) { fields := data.WithField("file", aciPath) content, err := ExtractManifestContentFromAci(aciPath) if err != nil { return nil, errs.WithEF(err, fields, "Cannot extract aci manifest content from file") } im := &schema.ImageManifest{} if err = im.UnmarshalJSON(content); err != nil { return nil, errs.WithEF(err, fields.WithField("content", string(content)), "Cannot unmarshall json content") } return im, nil }
func NewAciWithManifest(path string, args BuildArgs, manifestTmpl string, checkWg *sync.WaitGroup) (*Aci, error) { manifest, err := common.ProcessManifestTemplate(manifestTmpl, nil, false) if err != nil { return nil, errs.WithEF(err, data.WithField("content", manifestTmpl), "Failed to process manifest") } if manifest.NameAndVersion == "" { logs.WithField("path", path).Fatal("name is mandatory in manifest") } fields := data.WithField("aci", manifest.NameAndVersion.String()) logs.WithF(fields).WithFields(data.Fields{"args": args, "path": path, "manifest": manifest}).Debug("New aci") fullPath, err := filepath.Abs(path) if err != nil { return nil, errs.WithEF(err, fields, "Cannot get fullpath of project") } target := fullPath + pathTarget if Home.Config.TargetWorkDir != "" { currentAbsDir, err := filepath.Abs(Home.Config.TargetWorkDir + "/" + manifest.NameAndVersion.ShortName()) if err != nil { return nil, errs.WithEF(err, fields.WithField("path", path), "Invalid target path") } target = currentAbsDir } aci := &Aci{ fields: fields, args: args, path: fullPath, manifestTmpl: manifestTmpl, manifest: manifest, target: target, FullyResolveDep: true, checkWg: checkWg, } froms, err := manifest.GetFroms() if err != nil { logs.WithEF(err, aci.fields).Fatal("Invalid from data") } if len(froms) != 0 { if froms[0].String() == "" { logs.WithF(aci.fields).Warn("From is deprecated and empty, remove it") } else { logs.WithF(aci.fields).Warn("From is deprecated and processed as dependency. move from to dependencies") aci.manifest.Aci.Dependencies = append(froms, aci.manifest.Aci.Dependencies...) } } return aci, nil }
func (aci *Aci) zipAci() error { if _, err := os.Stat(aci.target + pathImageGzAci); err == nil { return nil } if stdout, stderr, err := common.ExecCmdGetStdoutAndStderr("gzip", "-k", aci.target+pathImageAci); err != nil { return errs.WithEF(err, aci.fields.WithField("path", aci.target+pathImageAci).WithField("stdout", stdout).WithField("stderr", stderr), "Failed to zip aci") } if err := common.ExecCmd("mv", aci.target+pathImageAci+".gz", aci.target+pathImageGzAci); err != nil { return errs.WithEF(err, aci.fields.WithField("from", aci.target+pathImageAci+".gz"). WithField("to", aci.target+pathImageGzAci), "Failed to rename zip aci") } return nil }
func (aci *Aci) Sign() error { logs.WithF(aci.fields).Debug("Signing") if err := aci.EnsureZip(); err != nil { return errs.WithEF(err, aci.fields, "Failed to prepare image for signature") } err := common.ExecCmd("gpg", "--armor", "--output", aci.target+pathImageGzAciAsc, "--detach-sig", aci.target+pathImageGzAci) if err != nil { return errs.WithEF(err, aci.fields, "Failed to sign image") } return nil }
func LoadConfig(configPath string) (*synapse.Synapse, error) { file, err := ioutil.ReadFile(configPath) if err != nil { return nil, errs.WithEF(err, data.WithField("file", configPath), "Failed to read configuration file") } conf := &synapse.Synapse{} err = yaml.Unmarshal(file, conf) if err != nil { return nil, errs.WithEF(err, data.WithField("file", configPath), "Invalid configuration format") } return conf, nil }
func (w *WatcherZookeeper) Init(service *Service) error { if err := w.CommonInit(service); err != nil { return errs.WithEF(err, w.fields, "Failed to init discovery") } w.fields = w.fields.WithField("path", w.Path) conn, err := nerve.NewSharedZkConnection(w.Hosts, time.Duration(w.TimeoutInMilli)*time.Millisecond) if err != nil { return errs.WithEF(err, w.fields, "Failed to prepare connection to zookeeper") } w.connection = conn w.connectionEvents = w.connection.Subscribe() return nil }
func (b *Builder) getStage1Manifest() (*schema.ImageManifest, error) { content, err := ioutil.ReadFile(rktcommon.Stage1ManifestPath(b.pod.Root)) if err != nil { return nil, errs.WithEF(err, b.fields.WithField("file", rktcommon.Stage1ManifestPath(b.pod.Root)), "Failed to read stage1 manifest") } im := &schema.ImageManifest{} err = im.UnmarshalJSON(content) if err != nil { return nil, errs.WithEF(err, b.fields.WithField("content", string(content)). WithField("file", rktcommon.Stage1ManifestPath(b.pod.Root)), "Cannot unmarshall json content from file") } return im, nil }
func templateAttribute(text string, attributes interface{}) (string, error) { tmpl, err := template.New("").Funcs(tpl.TemplateFunctions).Funcs(map[string]interface{}(gtf.GtfFuncMap)).Parse(text) if err != nil { return "", errs.WithEF(err, data.WithField("attribute", text), "Failed to parse template for attribute") } var b bytes.Buffer if err := tmpl.Execute(&b, attributes); err != nil { return "", errs.WithEF(err, data.WithField("attribute", text), "Failed to template attribute") } res := b.String() if logs.IsDebugEnabled() { logs.WithField("from", text).WithField("to", res).Debug("attribute templated") } return res, nil }
func (aci *Aci) Push() error { defer aci.giveBackUserRightsToTarget() if Home.Config.Push.Type == "" { return errs.WithF(aci.fields, "Cannot push, push is not configured in dgr global configuration file") } if err := aci.EnsureBuilt(); err != nil { return err } if aci.args.Test { aci.args.Test = false if err := aci.Test(); err != nil { return err } } logs.WithF(aci.fields).Info("Gzipping aci before upload") im, err := common.ExtractManifestFromAci(aci.target + pathImageAci) if err != nil { return errs.WithEF(err, aci.fields.WithField("file", pathImageAci), "Failed to extract manifest from aci file") } val, ok := im.Labels.Get("version") if !ok { return errs.WithEF(err, aci.fields.WithField("file", pathImageAci), "Failed to get version from aci manifest") } if err := aci.zipAci(); err != nil { return errs.WithEF(err, aci.fields, "Failed to zip aci") } logs.WithF(aci.fields).Info("Uploading aci") if err := common.ExecCmd("curl", "-f", "-i", "-F", "r=releases", "-F", "hasPom=false", "-F", "e=aci", "-F", "g=com.blablacar.aci.linux.amd64", "-F", "p=aci", "-F", "v="+val, "-F", "a="+strings.Split(string(im.Name), "/")[1], "-F", "file=@"+aci.target+pathImageGzAci, "-u", Home.Config.Push.Username+":"+Home.Config.Push.Password, Home.Config.Push.Url+"/service/local/artifact/maven/content"); err != nil { return errs.WithEF(err, aci.fields, "Failed to push aci") } return nil }