1package garden 2 3import ( 4 "io" 5 "time" 6) 7 8//go:generate counterfeiter . Container 9 10type Container interface { 11 Handle() string 12 13 // Stop stops a container. 14 // 15 // If kill is false, garden stops a container by sending the processes running inside it the SIGTERM signal. 16 // It then waits for the processes to terminate before returning a response. 17 // If one or more processes do not terminate within 10 seconds, 18 // garden sends these processes the SIGKILL signal, killing them ungracefully. 19 // 20 // If kill is true, garden stops a container by sending the processing running inside it a SIGKILL signal. 21 // 22 // It is possible to copy files in to and out of a stopped container. 23 // It is only when a container is destroyed that its filesystem is cleaned up. 24 // 25 // Errors: 26 // * None. 27 Stop(kill bool) error 28 29 // Returns information about a container. 30 Info() (ContainerInfo, error) 31 32 // StreamIn streams data into a file in a container. 33 // 34 // Errors: 35 // * TODO. 36 StreamIn(spec StreamInSpec) error 37 38 // StreamOut streams a file out of a container. 39 // 40 // Errors: 41 // * TODO. 42 StreamOut(spec StreamOutSpec) (io.ReadCloser, error) 43 44 // Returns the current bandwidth limits set for the container. 45 CurrentBandwidthLimits() (BandwidthLimits, error) 46 47 // Returns the current CPU limts set for the container. 48 CurrentCPULimits() (CPULimits, error) 49 50 // Returns the current disk limts set for the container. 51 CurrentDiskLimits() (DiskLimits, error) 52 53 // Returns the current memory limts set for the container. 54 CurrentMemoryLimits() (MemoryLimits, error) 55 56 // Map a port on the host to a port in the container so that traffic to the 57 // host port is forwarded to the container port. This is deprecated in 58 // favour of passing NetIn configuration in the ContainerSpec at creation 59 // time. 60 // 61 // If a host port is not given, a port will be acquired from the server's port 62 // pool. 63 // 64 // If a container port is not given, the port will be the same as the 65 // host port. 66 // 67 // The resulting host and container ports are returned in that order. 68 // 69 // Errors: 70 // * When no port can be acquired from the server's port pool. 71 NetIn(hostPort, containerPort uint32) (uint32, uint32, error) 72 73 // Whitelist outbound network traffic. This is deprecated in favour of passing 74 // NetOut configuration in the ContainerSpec at creation time. 75 // 76 // If the configuration directive deny_networks is not used, 77 // all networks are already whitelisted and this command is effectively a no-op. 78 // 79 // Later NetOut calls take precedence over earlier calls, which is 80 // significant only in relation to logging. 81 // 82 // Errors: 83 // * An error is returned if the NetOut call fails. 84 NetOut(netOutRule NetOutRule) error 85 86 // A Bulk call for NetOut. This is deprecated in favour of passing 87 // NetOut configuration in the ContainerSpec at creation time. 88 // 89 // Errors: 90 // * An error is returned if any of the NetOut calls fail. 91 BulkNetOut(netOutRules []NetOutRule) error 92 93 // Run a script inside a container. 94 // 95 // The root user will be mapped to a non-root UID in the host unless the container (not this process) was created with 'privileged' true. 96 // 97 // Errors: 98 // * TODO. 99 Run(ProcessSpec, ProcessIO) (Process, error) 100 101 // Attach starts streaming the output back to the client from a specified process. 102 // 103 // Errors: 104 // * processID does not refer to a running process. 105 Attach(processID string, io ProcessIO) (Process, error) 106 107 // Metrics returns the current set of metrics for a container 108 Metrics() (Metrics, error) 109 110 // Sets the grace time. 111 SetGraceTime(graceTime time.Duration) error 112 113 // Properties returns the current set of properties 114 Properties() (Properties, error) 115 116 // Property returns the value of the property with the specified name. 117 // 118 // Errors: 119 // * When the property does not exist on the container. 120 Property(name string) (string, error) 121 122 // Set a named property on a container to a specified value. 123 // 124 // Errors: 125 // * None. 126 SetProperty(name string, value string) error 127 128 // Remove a property with the specified name from a container. 129 // 130 // Errors: 131 // * None. 132 RemoveProperty(name string) error 133} 134 135// ProcessSpec contains parameters for running a script inside a container. 136type ProcessSpec struct { 137 // ID for the process. If empty, an ID will be generated. 138 ID string `json:"id,omitempty"` 139 140 // Path to command to execute. 141 Path string `json:"path,omitempty"` 142 143 // Arguments to pass to command. 144 Args []string `json:"args,omitempty"` 145 146 // Environment variables. 147 Env []string `json:"env,omitempty"` 148 149 // Working directory (default: home directory). 150 Dir string `json:"dir,omitempty"` 151 152 // The name of a user in the container to run the process as. 153 // This must either be a username, or uid:gid. 154 User string `json:"user,omitempty"` 155 156 // Resource limits 157 Limits ResourceLimits `json:"rlimits,omitempty"` 158 159 // Limits to be applied to the newly created process 160 OverrideContainerLimits *ProcessLimits `json:"limits,omitempty"` 161 162 // Execute with a TTY for stdio. 163 TTY *TTYSpec `json:"tty,omitempty"` 164 165 // Execute process in own root filesystem, different from the other processes 166 // in the container. 167 Image ImageRef `json:"image,omitempty"` 168 169 // Bind mounts to be applied to the process's filesystem 170 // An error is returned if ProcessSpec.Image is not also set. 171 BindMounts []BindMount `json:"bind_mounts,omitempty"` 172} 173 174type TTYSpec struct { 175 WindowSize *WindowSize `json:"window_size,omitempty"` 176} 177 178type WindowSize struct { 179 Columns int `json:"columns,omitempty"` 180 Rows int `json:"rows,omitempty"` 181} 182 183type ProcessIO struct { 184 Stdin io.Reader 185 Stdout io.Writer 186 Stderr io.Writer 187} 188 189//go:generate counterfeiter . Process 190 191type Process interface { 192 ID() string 193 Wait() (int, error) 194 SetTTY(TTYSpec) error 195 Signal(Signal) error 196} 197 198type Signal int 199 200const ( 201 SignalTerminate Signal = iota 202 SignalKill 203) 204 205type PortMapping struct { 206 HostPort uint32 207 ContainerPort uint32 208} 209 210type StreamInSpec struct { 211 Path string 212 User string 213 TarStream io.Reader 214} 215 216type StreamOutSpec struct { 217 Path string 218 User string 219} 220 221// ContainerInfo holds information about a container. 222type ContainerInfo struct { 223 State string // Either "active" or "stopped". 224 Events []string // List of events that occurred for the container. It currently includes only "oom" (Out Of Memory) event if it occurred. 225 HostIP string // The IP address of the gateway which controls the host side of the container's virtual ethernet pair. 226 ContainerIP string // The IP address of the container side of the container's virtual ethernet pair. 227 ExternalIP string // 228 ContainerPath string // The path to the directory holding the container's files (both its control scripts and filesystem). 229 ProcessIDs []string // List of running processes. 230 Properties Properties // List of properties defined for the container. 231 MappedPorts []PortMapping // 232} 233 234type ContainerInfoEntry struct { 235 Info ContainerInfo 236 Err *Error 237} 238 239type Metrics struct { 240 MemoryStat ContainerMemoryStat 241 CPUStat ContainerCPUStat 242 DiskStat ContainerDiskStat 243 NetworkStat ContainerNetworkStat 244 PidStat ContainerPidStat 245 Age time.Duration 246 CPUEntitlement uint64 247} 248 249type ContainerMetricsEntry struct { 250 Metrics Metrics 251 Err *Error 252} 253 254type ContainerMemoryStat struct { 255 ActiveAnon uint64 `json:"active_anon"` 256 ActiveFile uint64 `json:"active_file"` 257 Cache uint64 `json:"cache"` 258 HierarchicalMemoryLimit uint64 `json:"hierarchical_memory_limit"` 259 InactiveAnon uint64 `json:"inactive_anon"` 260 InactiveFile uint64 `json:"inactive_file"` 261 MappedFile uint64 `json:"mapped_file"` 262 Pgfault uint64 `json:"pgfault"` 263 Pgmajfault uint64 `json:"pgmajfault"` 264 Pgpgin uint64 `json:"pgpgin"` 265 Pgpgout uint64 `json:"pgpgout"` 266 Rss uint64 `json:"rss"` 267 TotalActiveAnon uint64 `json:"total_active_anon"` 268 TotalActiveFile uint64 `json:"total_active_file"` 269 TotalCache uint64 `json:"total_cache"` 270 TotalInactiveAnon uint64 `json:"total_inactive_anon"` 271 TotalInactiveFile uint64 `json:"total_inactive_file"` 272 TotalMappedFile uint64 `json:"total_mapped_file"` 273 TotalPgfault uint64 `json:"total_pgfault"` 274 TotalPgmajfault uint64 `json:"total_pgmajfault"` 275 TotalPgpgin uint64 `json:"total_pgpgin"` 276 TotalPgpgout uint64 `json:"total_pgpgout"` 277 TotalRss uint64 `json:"total_rss"` 278 TotalUnevictable uint64 `json:"total_unevictable"` 279 Unevictable uint64 `json:"unevictable"` 280 Swap uint64 `json:"swap"` 281 HierarchicalMemswLimit uint64 `json:"hierarchical_memsw_limit"` 282 TotalSwap uint64 `json:"total_swap"` 283 // A memory usage total which reports memory usage in the same way that limits are enforced. 284 // This value includes memory consumed by nested containers. 285 TotalUsageTowardLimit uint64 286} 287 288type ContainerCPUStat struct { 289 Usage uint64 290 User uint64 291 System uint64 292} 293 294type ContainerPidStat struct { 295 Current uint64 296 Max uint64 297} 298 299type ContainerDiskStat struct { 300 TotalBytesUsed uint64 301 TotalInodesUsed uint64 302 ExclusiveBytesUsed uint64 303 ExclusiveInodesUsed uint64 304} 305 306type ContainerBandwidthStat struct { 307 InRate uint64 308 InBurst uint64 309 OutRate uint64 310 OutBurst uint64 311} 312 313type ContainerNetworkStat struct { 314 RxBytes uint64 315 TxBytes uint64 316} 317 318type BandwidthLimits struct { 319 RateInBytesPerSecond uint64 `json:"rate,omitempty"` 320 BurstRateInBytesPerSecond uint64 `json:"burst,omitempty"` 321} 322 323type ProcessLimits struct { 324 CPU CPULimits `json:"cpu_limits,omitempty"` 325 Memory MemoryLimits `json:"memory_limits,omitempty"` 326} 327 328type DiskLimits struct { 329 InodeSoft uint64 `json:"inode_soft,omitempty"` 330 InodeHard uint64 `json:"inode_hard,omitempty"` 331 332 ByteSoft uint64 `json:"byte_soft,omitempty"` 333 ByteHard uint64 `json:"byte_hard,omitempty"` 334 335 Scope DiskLimitScope `json:"scope,omitempty"` 336} 337 338type MemoryLimits struct { 339 // Memory usage limit in bytes. 340 LimitInBytes uint64 `json:"limit_in_bytes,omitempty"` 341} 342 343type CPULimits struct { 344 Weight uint64 `json:"weight,omitempty"` 345 // Deprecated: Use Weight instead. 346 LimitInShares uint64 `json:"limit_in_shares,omitempty"` 347} 348 349type PidLimits struct { 350 // Limits the number of pids a container may create before new forks or clones are disallowed to processes in the container. 351 // Note: this may only be enforced when a process attempts to fork, so it does not guarantee that a new container.Run(ProcessSpec) 352 // will not succeed even if the limit has been exceeded, but the process will not be able to spawn further processes or threads. 353 Max uint64 `json:"max,omitempty"` 354} 355 356// Resource limits. 357// 358// Please refer to the manual page of getrlimit for a description of the individual fields: 359// http://www.kernel.org/doc/man-pages/online/pages/man2/getrlimit.2.html 360type ResourceLimits struct { 361 As *uint64 `json:"as,omitempty"` 362 Core *uint64 `json:"core,omitempty"` 363 Cpu *uint64 `json:"cpu,omitempty"` 364 Data *uint64 `json:"data,omitempty"` 365 Fsize *uint64 `json:"fsize,omitempty"` 366 Locks *uint64 `json:"locks,omitempty"` 367 Memlock *uint64 `json:"memlock,omitempty"` 368 Msgqueue *uint64 `json:"msgqueue,omitempty"` 369 Nice *uint64 `json:"nice,omitempty"` 370 Nofile *uint64 `json:"nofile,omitempty"` 371 Nproc *uint64 `json:"nproc,omitempty"` 372 Rss *uint64 `json:"rss,omitempty"` 373 Rtprio *uint64 `json:"rtprio,omitempty"` 374 Sigpending *uint64 `json:"sigpending,omitempty"` 375 Stack *uint64 `json:"stack,omitempty"` 376} 377 378type DiskLimitScope uint8 379 380const DiskLimitScopeTotal DiskLimitScope = 0 381const DiskLimitScopeExclusive DiskLimitScope = 1 382