X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/d3b76845c740935f7474f535d308303c748b0b4a..37d9f94b06ff367a3514b58ec6f0e4d4d0116030:/lib/crunchrun/singularity.go diff --git a/lib/crunchrun/singularity.go b/lib/crunchrun/singularity.go index 741f542454..5af023a83d 100644 --- a/lib/crunchrun/singularity.go +++ b/lib/crunchrun/singularity.go @@ -36,6 +36,8 @@ func newSingularityExecutor(logf func(string, ...interface{})) (*singularityExec }, nil } +func (e *singularityExecutor) Runtime() string { return "singularity" } + func (e *singularityExecutor) getOrCreateProject(ownerUuid string, name string, containerClient *arvados.Client) (*arvados.Group, error) { var gp arvados.GroupList err := containerClient.RequestAndDecode(&gp, @@ -101,7 +103,7 @@ func (e *singularityExecutor) checkImageCache(dockerImageID string, container ar if len(cl.Items) == 1 { imageCollection = cl.Items[0] } else { - collectionName := collectionName + " " + time.Now().UTC().Format(time.RFC3339) + collectionName := "converting " + collectionName exp := time.Now().Add(24 * 7 * 2 * time.Hour) err = containerClient.RequestAndDecode(&imageCollection, arvados.EndpointCollectionCreate.Method, @@ -112,6 +114,7 @@ func (e *singularityExecutor) checkImageCache(dockerImageID string, container ar "name": collectionName, "trash_at": exp.UTC().Format(time.RFC3339), }, + "ensure_unique_name": true, }) if err != nil { return nil, fmt.Errorf("error creating '%v' collection: %s", collectionName, err) @@ -141,6 +144,12 @@ func (e *singularityExecutor) LoadImage(dockerImageID string, imageTarballPath s } if _, err := os.Stat(imageFilename); os.IsNotExist(err) { + // Make sure the docker image is readable, and error + // out if not. + if _, err := os.Stat(imageTarballPath); err != nil { + return err + } + e.logf("building singularity image") // "singularity build" does not accept a // docker-archive://... filename containing a ":" character, @@ -151,7 +160,22 @@ func (e *singularityExecutor) LoadImage(dockerImageID string, imageTarballPath s return err } + // Set up a cache and tmp dir for singularity build + err = os.Mkdir(e.tmpdir+"/cache", 0700) + if err != nil { + return err + } + defer os.RemoveAll(e.tmpdir + "/cache") + err = os.Mkdir(e.tmpdir+"/tmp", 0700) + if err != nil { + return err + } + defer os.RemoveAll(e.tmpdir + "/tmp") + build := exec.Command("singularity", "build", imageFilename, "docker-archive://"+e.tmpdir+"/image.tar") + build.Env = os.Environ() + build.Env = append(build.Env, "SINGULARITY_CACHEDIR="+e.tmpdir+"/cache") + build.Env = append(build.Env, "SINGULARITY_TMPDIR="+e.tmpdir+"/tmp") e.logf("%v", build.Args) out, err := build.CombinedOutput() // INFO: Starting build... @@ -218,7 +242,7 @@ func (e *singularityExecutor) Create(spec containerSpec) error { } func (e *singularityExecutor) Start() error { - args := []string{"singularity", "exec", "--containall", "--no-home", "--cleanenv", "--pwd", e.spec.WorkingDir} + args := []string{"singularity", "exec", "--containall", "--cleanenv", "--pwd", e.spec.WorkingDir} if !e.spec.EnableNetwork { args = append(args, "--net", "--network=none") } @@ -233,7 +257,12 @@ func (e *singularityExecutor) Start() error { sort.Strings(binds) for _, path := range binds { mount := e.spec.BindMounts[path] - args = append(args, "--bind", mount.HostPath+":"+path+":"+readonlyflag[mount.ReadOnly]) + if path == e.spec.Env["HOME"] { + // Singularity treates $HOME as special case + args = append(args, "--home", mount.HostPath+":"+path) + } else { + args = append(args, "--bind", mount.HostPath+":"+path+":"+readonlyflag[mount.ReadOnly]) + } } // This is for singularity 3.5.2. There are some behaviors @@ -243,11 +272,11 @@ func (e *singularityExecutor) Start() error { env := make([]string, 0, len(e.spec.Env)) for k, v := range e.spec.Env { if k == "HOME" { - // $HOME is a special case - args = append(args, "--home="+v) - } else { - env = append(env, "SINGULARITYENV_"+k+"="+v) + // Singularity treates $HOME as special case, this is handled + // with --home above + continue } + env = append(env, "SINGULARITYENV_"+k+"="+v) } args = append(args, e.imageFilename)