github.com/apptainer/singularity@v3.1.1+incompatible/cmd/internal/cli/action_flags.go (about) 1 // Copyright (c) 2018, 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 cli 7 8 import ( 9 "log" 10 "os" 11 12 "github.com/spf13/pflag" 13 "github.com/sylabs/singularity/internal/pkg/util/user" 14 ) 15 16 // actionflags.go contains flag variables for action-like commands to draw from 17 var ( 18 AppName string 19 BindPaths []string 20 HomePath string 21 OverlayPath []string 22 ScratchPath []string 23 WorkdirPath string 24 PwdPath string 25 ShellPath string 26 Hostname string 27 Network string 28 NetworkArgs []string 29 DNS string 30 Security []string 31 CgroupsPath string 32 ContainLibsPath []string 33 34 IsBoot bool 35 IsFakeroot bool 36 IsCleanEnv bool 37 IsContained bool 38 IsContainAll bool 39 IsWritable bool 40 IsWritableTmpfs bool 41 Nvidia bool 42 NoHome bool 43 NoInit bool 44 NoNvidia bool 45 46 NetNamespace bool 47 UtsNamespace bool 48 UserNamespace bool 49 PidNamespace bool 50 IpcNamespace bool 51 52 AllowSUID bool 53 KeepPrivs bool 54 NoPrivs bool 55 AddCaps string 56 DropCaps string 57 ) 58 59 var actionFlags = pflag.NewFlagSet("ActionFlags", pflag.ExitOnError) 60 61 func getHomeDir() string { 62 user, err := user.GetPwUID(uint32(os.Getuid())) 63 if err != nil { 64 log.Fatal(err) 65 return "" 66 } 67 68 return user.Dir 69 } 70 71 func init() { 72 initPathVars() 73 initBoolVars() 74 initNamespaceVars() 75 initPrivilegeVars() 76 } 77 78 // initPathVars initializes flags that take a string argument 79 func initPathVars() { 80 // --app 81 actionFlags.StringVar(&AppName, "app", "", "set an application to run inside a container") 82 actionFlags.SetAnnotation("app", "envkey", []string{"APP", "APPNAME"}) 83 84 // -B|--bind 85 actionFlags.StringSliceVarP(&BindPaths, "bind", "B", []string{}, "a user-bind path specification. spec has the format src[:dest[:opts]], where src and dest are outside and inside paths. If dest is not given, it is set equal to src. Mount options ('opts') may be specified as 'ro' (read-only) or 'rw' (read/write, which is the default). Multiple bind paths can be given by a comma separated list.") 86 actionFlags.SetAnnotation("bind", "argtag", []string{"<spec>"}) 87 actionFlags.SetAnnotation("bind", "envkey", []string{"BIND", "BINDPATH"}) 88 89 // -H|--home 90 actionFlags.StringVarP(&HomePath, "home", "H", getHomeDir(), "a home directory specification. spec can either be a src path or src:dest pair. src is the source path of the home directory outside the container and dest overrides the home directory within the container.") 91 actionFlags.SetAnnotation("home", "argtag", []string{"<spec>"}) 92 actionFlags.SetAnnotation("home", "envkey", []string{"HOME"}) 93 94 // -o|--overlay 95 actionFlags.StringSliceVarP(&OverlayPath, "overlay", "o", []string{}, "use an overlayFS image for persistent data storage or as read-only layer of container") 96 actionFlags.SetAnnotation("overlay", "argtag", []string{"<path>"}) 97 actionFlags.SetAnnotation("overlay", "envkey", []string{"OVERLAY", "OVERLAYIMAGE"}) 98 99 // -S|--scratch 100 actionFlags.StringSliceVarP(&ScratchPath, "scratch", "S", []string{}, "include a scratch directory within the container that is linked to a temporary dir (use -W to force location)") 101 actionFlags.SetAnnotation("scratch", "argtag", []string{"<path>"}) 102 actionFlags.SetAnnotation("scratch", "envkey", []string{"SCRATCH", "SCRATCHDIR"}) 103 104 // -W|--workdir 105 actionFlags.StringVarP(&WorkdirPath, "workdir", "W", "", "working directory to be used for /tmp, /var/tmp and $HOME (if -c/--contain was also used)") 106 actionFlags.SetAnnotation("workdir", "argtag", []string{"<path>"}) 107 actionFlags.SetAnnotation("workdir", "envkey", []string{"WORKDIR"}) 108 109 // -s|--shell 110 actionFlags.StringVarP(&ShellPath, "shell", "s", "", "path to program to use for interactive shell") 111 actionFlags.SetAnnotation("shell", "argtag", []string{"<path>"}) 112 actionFlags.SetAnnotation("shell", "envkey", []string{"SHELL"}) 113 114 // --pwd 115 actionFlags.StringVar(&PwdPath, "pwd", "", "initial working directory for payload process inside the container") 116 actionFlags.SetAnnotation("pwd", "argtag", []string{"<path>"}) 117 actionFlags.SetAnnotation("pwd", "envkey", []string{"PWD", "TARGET_PWD"}) 118 119 // --hostname 120 actionFlags.StringVar(&Hostname, "hostname", "", "set container hostname") 121 actionFlags.SetAnnotation("hostname", "argtag", []string{"<name>"}) 122 actionFlags.SetAnnotation("hostname", "envkey", []string{"HOSTNAME"}) 123 124 // --network 125 actionFlags.StringVar(&Network, "network", "bridge", "specify desired network type separated by commas, each network will bring up a dedicated interface inside container") 126 actionFlags.SetAnnotation("network", "argtag", []string{"<name>"}) 127 actionFlags.SetAnnotation("network", "envkey", []string{"NETWORK"}) 128 129 // --network-args 130 actionFlags.StringSliceVar(&NetworkArgs, "network-args", []string{}, "specify network arguments to pass to CNI plugins") 131 actionFlags.SetAnnotation("network-args", "argtag", []string{"<name>"}) 132 actionFlags.SetAnnotation("network-args", "envkey", []string{"NETWORK_ARGS"}) 133 134 // --dns 135 actionFlags.StringVar(&DNS, "dns", "", "list of DNS server separated by commas to add in resolv.conf") 136 actionFlags.SetAnnotation("dns", "envkey", []string{"DNS"}) 137 138 // --security 139 actionFlags.StringSliceVar(&Security, "security", []string{}, "enable security features (SELinux, Apparmor, Seccomp)") 140 actionFlags.SetAnnotation("security", "argtag", []string{""}) 141 actionFlags.SetAnnotation("security", "envkey", []string{"SECURITY"}) 142 143 // --apply-cgroups 144 actionFlags.StringVar(&CgroupsPath, "apply-cgroups", "", "apply cgroups from file for container processes (root only)") 145 actionFlags.SetAnnotation("apply-cgroups", "argtag", []string{"<path>"}) 146 actionFlags.SetAnnotation("apply-cgroups", "envkey", []string{"APPLY_CGROUPS"}) 147 148 // hidden flag to handle SINGULARITY_CONTAINLIBS environment variable 149 actionFlags.StringSliceVar(&ContainLibsPath, "containlibs", []string{}, "") 150 actionFlags.Lookup("containlibs").Hidden = true 151 actionFlags.SetAnnotation("containlibs", "envkey", []string{"CONTAINLIBS"}) 152 153 // hidden flags to handle docker credentials 154 actionFlags.StringVar(&dockerUsername, "docker-username", "", "specify a username for docker authentication") 155 actionFlags.Lookup("docker-username").Hidden = true 156 actionFlags.SetAnnotation("docker-username", "envkey", []string{"DOCKER_USERNAME"}) 157 158 actionFlags.StringVar(&dockerPassword, "docker-password", "", "specify a password for docker authentication") 159 actionFlags.Lookup("docker-password").Hidden = true 160 actionFlags.SetAnnotation("docker-password", "envkey", []string{"DOCKER_PASSWORD"}) 161 162 // hidden flag to handle SINGULARITY_TMPDIR environment variable 163 actionFlags.StringVar(&tmpDir, "tmpdir", "", "specify a temporary directory to use for build") 164 actionFlags.Lookup("tmpdir").Hidden = true 165 actionFlags.SetAnnotation("tmpdir", "envkey", []string{"TMPDIR"}) 166 } 167 168 // initBoolVars initializes flags that take a boolean argument 169 func initBoolVars() { 170 // --boot 171 actionFlags.BoolVar(&IsBoot, "boot", false, "execute /sbin/init to boot container (root only)") 172 actionFlags.SetAnnotation("boot", "envkey", []string{"BOOT"}) 173 174 // -f|--fakeroot 175 actionFlags.BoolVarP(&IsFakeroot, "fakeroot", "f", false, "run container in new user namespace as uid 0 (experimental)") 176 actionFlags.Lookup("fakeroot").Hidden = true 177 actionFlags.SetAnnotation("fakeroot", "envkey", []string{"FAKEROOT"}) 178 179 // -e|--cleanenv 180 actionFlags.BoolVarP(&IsCleanEnv, "cleanenv", "e", false, "clean environment before running container") 181 actionFlags.SetAnnotation("cleanenv", "envkey", []string{"CLEANENV"}) 182 183 // -c|--contain 184 actionFlags.BoolVarP(&IsContained, "contain", "c", false, "use minimal /dev and empty other directories (e.g. /tmp and $HOME) instead of sharing filesystems from your host") 185 actionFlags.SetAnnotation("contain", "envkey", []string{"CONTAIN"}) 186 187 // -C|--containall 188 actionFlags.BoolVarP(&IsContainAll, "containall", "C", false, "contain not only file systems, but also PID, IPC, and environment") 189 actionFlags.SetAnnotation("containall", "envkey", []string{"CONTAINALL"}) 190 191 // --nv 192 actionFlags.BoolVar(&Nvidia, "nv", false, "enable experimental Nvidia support") 193 actionFlags.SetAnnotation("nv", "envkey", []string{"NV"}) 194 195 // -w|--writable 196 actionFlags.BoolVarP(&IsWritable, "writable", "w", false, "by default all Singularity containers are available as read only. This option makes the file system accessible as read/write.") 197 actionFlags.SetAnnotation("writable", "envkey", []string{"WRITABLE"}) 198 199 // --writable-tmpfs 200 actionFlags.BoolVar(&IsWritableTmpfs, "writable-tmpfs", false, "makes the file system accessible as read-write with non persistent data (with overlay support only)") 201 actionFlags.SetAnnotation("writable-tmpfs", "envkey", []string{"WRITABLE_TMPFS"}) 202 203 // --no-home 204 actionFlags.BoolVar(&NoHome, "no-home", false, "do NOT mount users home directory if home is not the current working directory") 205 actionFlags.SetAnnotation("no-home", "envkey", []string{"NO_HOME"}) 206 207 // --no-init 208 actionFlags.BoolVar(&NoInit, "no-init", false, "do NOT start shim process with --pid") 209 actionFlags.SetAnnotation("no-init", "envkey", []string{"NO_INIT", "NOSHIMINIT"}) 210 211 // --nohttps 212 actionFlags.BoolVar(&noHTTPS, "nohttps", false, "do NOT use HTTPS, for communicating with local docker registry") 213 actionFlags.SetAnnotation("nohttps", "envkey", []string{"NOHTTPS"}) 214 215 // --docker-login 216 actionFlags.BoolVar(&dockerLogin, "docker-login", false, "interactive prompt for docker authentication") 217 actionFlags.SetAnnotation("docker-login", "envkey", []string{"DOCKER_LOGIN"}) 218 219 // hidden flag to disable nvidia bindings when 'always use nv = yes' 220 actionFlags.BoolVar(&NoNvidia, "no-nv", false, "") 221 actionFlags.Lookup("no-nv").Hidden = true 222 actionFlags.SetAnnotation("no-nv", "envkey", []string{"NV_OFF", "NO_NV"}) 223 224 } 225 226 // initNamespaceVars initializes flags that take toggle namespace support 227 func initNamespaceVars() { 228 // -p|--pid 229 actionFlags.BoolVarP(&PidNamespace, "pid", "p", false, "run container in a new PID namespace") 230 actionFlags.SetAnnotation("pid", "envkey", []string{"PID", "UNSHARE_PID"}) 231 232 // -i|--ipc 233 actionFlags.BoolVarP(&IpcNamespace, "ipc", "i", false, "run container in a new IPC namespace") 234 actionFlags.SetAnnotation("ipc", "envkey", []string{"IPC", "UNSHARE_IPC"}) 235 236 // -n|--net 237 actionFlags.BoolVarP(&NetNamespace, "net", "n", false, "run container in a new network namespace (sets up a bridge network interface by default)") 238 actionFlags.SetAnnotation("net", "envkey", []string{"NET", "UNSHARE_NET"}) 239 240 // --uts 241 actionFlags.BoolVar(&UtsNamespace, "uts", false, "run container in a new UTS namespace") 242 actionFlags.SetAnnotation("uts", "envkey", []string{"UTS", "UNSHARE_UTS"}) 243 244 // -u|--userns 245 actionFlags.BoolVarP(&UserNamespace, "userns", "u", false, "run container in a new user namespace, allowing Singularity to run completely unprivileged on recent kernels. This disables some features of Singularity, for example it only works with sandbox images.") 246 actionFlags.SetAnnotation("userns", "envkey", []string{"USERNS", "UNSHARE_USERNS"}) 247 } 248 249 // initPrivilegeVars initializes flags that manipulate privileges 250 func initPrivilegeVars() { 251 // --keep-privs 252 actionFlags.BoolVar(&KeepPrivs, "keep-privs", false, "let root user keep privileges in container (root only)") 253 actionFlags.SetAnnotation("keep-privs", "envkey", []string{"KEEP_PRIVS"}) 254 255 // --no-privs 256 actionFlags.BoolVar(&NoPrivs, "no-privs", false, "drop all privileges from root user in container") 257 actionFlags.SetAnnotation("no-privs", "envkey", []string{"NO_PRIVS"}) 258 259 // --add-caps 260 actionFlags.StringVar(&AddCaps, "add-caps", "", "a comma separated capability list to add") 261 actionFlags.SetAnnotation("add-caps", "envkey", []string{"ADD_CAPS"}) 262 263 // --drop-caps 264 actionFlags.StringVar(&DropCaps, "drop-caps", "", "a comma separated capability list to drop") 265 actionFlags.SetAnnotation("drop-caps", "envkey", []string{"DROP_CAPS"}) 266 267 // --allow-setuid 268 actionFlags.BoolVar(&AllowSUID, "allow-setuid", false, "allow setuid binaries in container (root only)") 269 actionFlags.SetAnnotation("allow-setuid", "envkey", []string{"ALLOW_SETUID"}) 270 }