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 (b *Builder) writeManifest() error { upperId, err := b.upperTreeStoreId() if err != nil { return err } attrMerger, err := merger.NewAttributesMerger(b.stage1Rootfs + PATH_DGR + PATH_BUILDER + PATH_ATTRIBUTES) if err != nil { logs.WithE(err).Warn("Failed to prepare attributes") } attributes := attrMerger.Merge() logs.WithFields(b.fields).WithField("attributes", attributes).Debug("Merged attributes for manifest templating") content, err := ioutil.ReadFile(b.aciTargetPath + common.PathManifestYmlTmpl) if err != nil { return errs.WithEF(err, b.fields.WithField("file", b.aciTargetPath+common.PathManifestYmlTmpl), "Failed to read manifest template") } aciManifest, err := common.ProcessManifestTemplate(string(content), attributes, true) if err != nil { return errs.WithEF(err, b.fields.WithField("content", string(content)), "Failed to process manifest template") } target := b.pod.Root + PATH_OVERLAY + "/" + upperId + PATH_UPPER + common.PathManifest dgrVersion, ok := manifestApp(b.pod).App.Environment.Get(common.EnvDgrVersion) if !ok { return errs.WithF(b.fields, "Cannot find dgr version") } froms, err := aciManifest.GetFroms() if len(froms) != 0 { if froms[0].String() != "" { aciManifest.Aci.Dependencies = append(froms, aciManifest.Aci.Dependencies...) } } if aciManifest.NameAndVersion.Version() == "" { aciManifest.NameAndVersion = *common.NewACFullName(aciManifest.NameAndVersion.Name() + ":" + common.GenerateVersion(b.aciTargetPath)) } if err := common.WriteAciManifest(aciManifest, target, aciManifest.NameAndVersion.Name(), dgrVersion); err != nil { return errs.WithEF(err, b.fields.WithField("file", target), "Failed to write manifest") } return 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, } return aci, nil }
func (b *Builder) prepareNspawnArgsAndEnv(commandPath string) ([]string, []string, error) { var args []string env := os.Environ() args = append(args, b.stage1Rootfs+"/dgr/usr/lib/ld-linux-x86-64.so.2") args = append(args, b.stage1Rootfs+"/dgr/usr/bin/systemd-nspawn") if context := os.Getenv(rktcommon.EnvSELinuxContext); context != "" { args = append(args, fmt.Sprintf("-Z%s", context)) } args = append(args, "--register=no") args = append(args, "-q") args = append(args, "--link-journal=auto") env = append(env, "LD_LIBRARY_PATH="+b.stage1Rootfs+"/dgr/usr/lib") if !logs.IsDebugEnabled() { args = append(args, "--quiet") } lvl := "info" switch logs.GetLevel() { case logs.FATAL: lvl = "crit" case logs.PANIC: lvl = "alert" case logs.ERROR: lvl = "err" case logs.WARN: lvl = "warning" case logs.INFO: lvl = "info" case logs.DEBUG | logs.TRACE: lvl = "debug" } args = append(args, "--uuid="+b.pod.UUID.String()) args = append(args, "--machine=dgr"+b.pod.UUID.String()) env = append(env, "SYSTEMD_LOG_LEVEL="+lvl) for _, e := range manifestApp(b.pod).App.Environment { if e.Name != common.EnvBuilderCommand && e.Name != common.EnvAciTarget { args = append(args, "--setenv="+e.Name+"="+e.Value) } } catchError, _ := manifestApp(b.pod).App.Environment.Get(common.EnvCatchOnError) catchStep, _ := manifestApp(b.pod).App.Environment.Get(common.EnvCatchOnStep) args = append(args, "--setenv="+common.EnvCatchOnError+"="+string(catchError)) args = append(args, "--setenv="+common.EnvCatchOnStep+"="+string(catchStep)) version, ok := manifestApp(b.pod).Image.Labels.Get("version") if ok { args = append(args, "--setenv=ACI_VERSION="+version) } args = append(args, "--setenv=ACI_NAME="+manifestApp(b.pod).Name.String()) args = append(args, "--setenv=ACI_EXEC="+"'"+strings.Join(manifestApp(b.pod).App.Exec, "' '")+"'") args = append(args, "--setenv=ROOTFS="+PATH_OPT+PATH_STAGE2+"/"+manifestApp(b.pod).Name.String()+common.PathRootfs) args = append(args, "--capability=all") args = append(args, "--directory="+b.stage1Rootfs) args = append(args, "--bind="+b.aciHomePath+"/:/dgr/aci-home") args = append(args, "--bind="+b.aciTargetPath+"/:/dgr/aci-target") // content, err := ioutil.ReadFile(b.aciTargetPath + common.PathManifestYmlTmpl) if err != nil { return args, env, errs.WithEF(err, b.fields.WithField("file", b.aciTargetPath+common.PathManifestYmlTmpl), "Failed to read manifest template") } aciManifest, err := common.ProcessManifestTemplate(string(content), nil, false) if err != nil { return args, env, errs.WithEF(err, b.fields.WithField("content", string(content)), "Failed to process manifest template") } for _, mount := range aciManifest.Builder.MountPoints { if strings.HasPrefix(mount.From, "~/") { user, err := user.Current() if err != nil { return args, env, errs.WithEF(err, b.fields, "Cannot found current user") } mount.From = user.HomeDir + mount.From[1:] } from := mount.From if from[0] != '/' { from = b.aciHomePath + "/" + from } if _, err := os.Stat(from); err != nil { os.MkdirAll(from, 0755) } args = append(args, "--bind="+from+":"+mount.To) } args = append(args, commandPath) return args, env, nil }