github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/runtime/engines/singularity/create.go (about) 1 // Copyright (c) 2018-2019, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package singularity 7 8 import ( 9 "fmt" 10 "net" 11 "net/rpc" 12 "os" 13 "path/filepath" 14 15 specs "github.com/opencontainers/runtime-spec/specs-go" 16 "github.com/sylabs/singularity/internal/pkg/buildcfg" 17 "github.com/sylabs/singularity/internal/pkg/runtime/engines/config" 18 singularityConfig "github.com/sylabs/singularity/internal/pkg/runtime/engines/singularity/config" 19 "github.com/sylabs/singularity/internal/pkg/runtime/engines/singularity/rpc/client" 20 ) 21 22 // CreateContainer creates a container 23 func (engine *EngineOperations) CreateContainer(pid int, rpcConn net.Conn) error { 24 if engine.CommonConfig.EngineName != singularityConfig.Name { 25 return fmt.Errorf("engineName configuration doesn't match runtime name") 26 } 27 28 if engine.EngineConfig.GetInstanceJoin() { 29 return nil 30 } 31 32 configurationFile := buildcfg.SYSCONFDIR + "/singularity/singularity.conf" 33 if err := config.Parser(configurationFile, engine.EngineConfig.File); err != nil { 34 return fmt.Errorf("Unable to parse singularity.conf file: %s", err) 35 } 36 37 rpcOps := &client.RPC{ 38 Client: rpc.NewClient(rpcConn), 39 Name: engine.CommonConfig.EngineName, 40 } 41 if rpcOps.Client == nil { 42 return fmt.Errorf("failed to initialiaze RPC client") 43 } 44 45 if engine.EngineConfig.GetInstance() { 46 namespaces := []struct { 47 nstype string 48 ns specs.LinuxNamespaceType 49 checkEnabled bool 50 }{ 51 {"pid", specs.PIDNamespace, false}, 52 {"uts", specs.UTSNamespace, false}, 53 {"ipc", specs.IPCNamespace, false}, 54 {"mnt", specs.MountNamespace, false}, 55 {"cgroup", specs.CgroupNamespace, false}, 56 {"net", specs.NetworkNamespace, false}, 57 {"user", specs.UserNamespace, true}, 58 } 59 60 path := fmt.Sprintf("/proc/%d/ns", pid) 61 ppid := os.Getpid() 62 63 for _, n := range namespaces { 64 has, err := rpcOps.HasNamespace(ppid, n.nstype) 65 if err == nil && (has || n.checkEnabled) { 66 enabled := false 67 if n.checkEnabled { 68 if engine.EngineConfig.OciConfig.Linux != nil { 69 for _, namespace := range engine.EngineConfig.OciConfig.Linux.Namespaces { 70 if n.ns == namespace.Type { 71 enabled = true 72 break 73 } 74 } 75 } 76 } 77 if has || enabled { 78 nspath := filepath.Join(path, n.nstype) 79 engine.EngineConfig.OciConfig.AddOrReplaceLinuxNamespace(string(n.ns), nspath) 80 } 81 } else if err != nil { 82 return fmt.Errorf("failed to check %s root and container namespace: %s", n.ns, err) 83 } 84 } 85 } 86 87 return create(engine, rpcOps, pid) 88 }