1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
|
package buildah
import (
"fmt"
"io"
"github.com/opencontainers/runtime-spec/specs-go"
)
const (
// runUsingRuntimeCommand is a command we use as a key for reexec
runUsingRuntimeCommand = Package + "-oci-runtime"
)
// TerminalPolicy takes the value DefaultTerminal, WithoutTerminal, or WithTerminal.
type TerminalPolicy int
const (
// DefaultTerminal indicates that this Run invocation should be
// connected to a pseudoterminal if we're connected to a terminal.
DefaultTerminal TerminalPolicy = iota
// WithoutTerminal indicates that this Run invocation should NOT be
// connected to a pseudoterminal.
WithoutTerminal
// WithTerminal indicates that this Run invocation should be connected
// to a pseudoterminal.
WithTerminal
)
// String converts a TerminalPolicy into a string.
func (t TerminalPolicy) String() string {
switch t {
case DefaultTerminal:
return "DefaultTerminal"
case WithoutTerminal:
return "WithoutTerminal"
case WithTerminal:
return "WithTerminal"
}
return fmt.Sprintf("unrecognized terminal setting %d", t)
}
// NamespaceOption controls how we set up a namespace when launching processes.
type NamespaceOption struct {
// Name specifies the type of namespace, typically matching one of the
// ...Namespace constants defined in
// github.com/opencontainers/runtime-spec/specs-go.
Name string
// Host is used to force our processes to use the host's namespace of
// this type.
Host bool
// Path is the path of the namespace to attach our process to, if Host
// is not set. If Host is not set and Path is also empty, a new
// namespace will be created for the process that we're starting.
// If Name is specs.NetworkNamespace, if Path doesn't look like an
// absolute path, it is treated as a comma-separated list of CNI
// configuration names which will be selected from among all of the CNI
// network configurations which we find.
Path string
}
// NamespaceOptions provides some helper methods for a slice of NamespaceOption
// structs.
type NamespaceOptions []NamespaceOption
// IDMappingOptions controls how we set up UID/GID mapping when we set up a
// user namespace.
type IDMappingOptions struct {
HostUIDMapping bool
HostGIDMapping bool
UIDMap []specs.LinuxIDMapping
GIDMap []specs.LinuxIDMapping
}
// Isolation provides a way to specify whether we're supposed to use a proper
// OCI runtime, or some other method for running commands.
type Isolation int
const (
// IsolationDefault is whatever we think will work best.
IsolationDefault Isolation = iota
// IsolationOCI is a proper OCI runtime.
IsolationOCI
// IsolationChroot is a more chroot-like environment: less isolation,
// but with fewer requirements.
IsolationChroot
// IsolationOCIRootless is a proper OCI runtime in rootless mode.
IsolationOCIRootless
)
// String converts a Isolation into a string.
func (i Isolation) String() string {
switch i {
case IsolationDefault:
return "IsolationDefault"
case IsolationOCI:
return "IsolationOCI"
case IsolationChroot:
return "IsolationChroot"
case IsolationOCIRootless:
return "IsolationOCIRootless"
}
return fmt.Sprintf("unrecognized isolation type %d", i)
}
// RunOptions can be used to alter how a command is run in the container.
type RunOptions struct {
// Hostname is the hostname we set for the running container.
Hostname string
// Isolation is either IsolationDefault, IsolationOCI, IsolationChroot, or IsolationOCIRootless.
Isolation Isolation
// Runtime is the name of the runtime to run. It should accept the
// same arguments that runc does, and produce similar output.
Runtime string
// Args adds global arguments for the runtime.
Args []string
// NoPivot adds the --no-pivot runtime flag.
NoPivot bool
// Mounts are additional mount points which we want to provide.
Mounts []specs.Mount
// Env is additional environment variables to set.
Env []string
// User is the user as whom to run the command.
User string
// WorkingDir is an override for the working directory.
WorkingDir string
// Shell is default shell to run in a container.
Shell string
// Cmd is an override for the configured default command.
Cmd []string
// Entrypoint is an override for the configured entry point.
Entrypoint []string
// NamespaceOptions controls how we set up the namespaces for the process.
NamespaceOptions NamespaceOptions
// ConfigureNetwork controls whether or not network interfaces and
// routing are configured for a new network namespace (i.e., when not
// joining another's namespace and not just using the host's
// namespace), effectively deciding whether or not the process has a
// usable network.
ConfigureNetwork NetworkConfigurationPolicy
// CNIPluginPath is the location of CNI plugin helpers, if they should be
// run from a location other than the default location.
CNIPluginPath string
// CNIConfigDir is the location of CNI configuration files, if the files in
// the default configuration directory shouldn't be used.
CNIConfigDir string
// Terminal provides a way to specify whether or not the command should
// be run with a pseudoterminal. By default (DefaultTerminal), a
// terminal is used if os.Stdout is connected to a terminal, but that
// decision can be overridden by specifying either WithTerminal or
// WithoutTerminal.
Terminal TerminalPolicy
// TerminalSize provides a way to set the number of rows and columns in
// a pseudo-terminal, if we create one, and Stdin/Stdout/Stderr aren't
// connected to a terminal.
TerminalSize *specs.Box
// The stdin/stdout/stderr descriptors to use. If set to nil, the
// corresponding files in the "os" package are used as defaults.
Stdin io.Reader `json:"-"`
Stdout io.Writer `json:"-"`
Stderr io.Writer `json:"-"`
// Quiet tells the run to turn off output to stdout.
Quiet bool
// AddCapabilities is a list of capabilities to add to the default set.
AddCapabilities []string
// DropCapabilities is a list of capabilities to remove from the default set,
// after processing the AddCapabilities set. If a capability appears in both
// lists, it will be dropped.
DropCapabilities []string
// Devices are the additional devices to add to the containers
Devices ContainerDevices
}
// Find the configuration for the namespace of the given type. If there are
// duplicates, find the _last_ one of the type, since we assume it was appended
// more recently.
func (n *NamespaceOptions) Find(namespace string) *NamespaceOption {
for i := range *n {
j := len(*n) - 1 - i
if (*n)[j].Name == namespace {
return &((*n)[j])
}
}
return nil
}
// AddOrReplace either adds or replaces the configuration for a given namespace.
func (n *NamespaceOptions) AddOrReplace(options ...NamespaceOption) {
nextOption:
for _, option := range options {
for i := range *n {
j := len(*n) - 1 - i
if (*n)[j].Name == option.Name {
(*n)[j] = option
continue nextOption
}
}
*n = append(*n, option)
}
}
|