2017-06-27 13:45:25 +00:00
package main
import (
2017-08-28 18:05:03 +00:00
"os"
2017-09-28 18:44:48 +00:00
"reflect"
"regexp"
2017-08-15 20:53:17 +00:00
"strings"
2017-06-27 13:45:25 +00:00
is "github.com/containers/image/storage"
"github.com/containers/storage"
2017-08-15 20:53:17 +00:00
"github.com/fatih/camelcase"
2017-07-25 19:16:43 +00:00
"github.com/kubernetes-incubator/cri-o/libkpod"
2017-09-06 14:28:59 +00:00
"github.com/kubernetes-incubator/cri-o/libpod"
2017-08-28 18:05:03 +00:00
"github.com/kubernetes-incubator/cri-o/server"
2017-09-06 14:28:59 +00:00
"github.com/pkg/errors"
2017-06-27 13:45:25 +00:00
"github.com/urfave/cli"
)
2017-08-17 14:23:54 +00:00
var (
stores = make ( map [ storage . Store ] struct { } )
)
2017-07-27 17:18:07 +00:00
func getStore ( c * libkpod . Config ) ( storage . Store , error ) {
2017-06-27 13:45:25 +00:00
options := storage . DefaultStoreOptions
2017-07-27 17:18:07 +00:00
options . GraphRoot = c . Root
options . RunRoot = c . RunRoot
options . GraphDriverName = c . Storage
options . GraphDriverOptions = c . StorageOptions
2017-06-30 19:10:57 +00:00
2017-06-27 13:45:25 +00:00
store , err := storage . GetStore ( options )
if err != nil {
return nil , err
}
is . Transport . SetStore ( store )
2017-08-17 14:23:54 +00:00
stores [ store ] = struct { } { }
2017-06-27 13:45:25 +00:00
return store , nil
}
2017-07-25 19:16:43 +00:00
2017-09-06 14:28:59 +00:00
func getRuntime ( c * cli . Context ) ( * libpod . Runtime , error ) {
config , err := getConfig ( c )
if err != nil {
return nil , errors . Wrapf ( err , "could not get config" )
}
options := storage . DefaultStoreOptions
options . GraphRoot = config . Root
options . RunRoot = config . RunRoot
options . GraphDriverName = config . Storage
options . GraphDriverOptions = config . StorageOptions
return libpod . NewRuntime ( libpod . WithStorageConfig ( options ) )
}
2017-08-17 14:23:54 +00:00
func shutdownStores ( ) {
for store := range stores {
if _ , err := store . Shutdown ( false ) ; err != nil {
break
}
}
}
2017-07-25 19:16:43 +00:00
func getConfig ( c * cli . Context ) ( * libkpod . Config , error ) {
config := libkpod . DefaultConfig ( )
2017-08-28 18:05:03 +00:00
var configFile string
2017-07-25 19:16:43 +00:00
if c . GlobalIsSet ( "config" ) {
2017-08-28 18:05:03 +00:00
configFile = c . GlobalString ( "config" )
} else if _ , err := os . Stat ( server . CrioConfigPath ) ; err == nil {
configFile = server . CrioConfigPath
}
// load and merge the configfile from the commandline or use
// the default crio config file
if configFile != "" {
err := config . UpdateFromFile ( configFile )
2017-07-25 19:16:43 +00:00
if err != nil {
return config , err
}
}
if c . GlobalIsSet ( "root" ) {
config . Root = c . GlobalString ( "root" )
}
if c . GlobalIsSet ( "runroot" ) {
config . RunRoot = c . GlobalString ( "runroot" )
}
if c . GlobalIsSet ( "storage-driver" ) {
config . Storage = c . GlobalString ( "storage-driver" )
}
if c . GlobalIsSet ( "storage-opt" ) {
opts := c . GlobalStringSlice ( "storage-opt" )
if len ( opts ) > 0 {
config . StorageOptions = opts
}
}
2017-08-14 17:30:24 +00:00
if c . GlobalIsSet ( "runtime" ) {
config . Runtime = c . GlobalString ( "runtime" )
}
2017-07-25 19:16:43 +00:00
return config , nil
}
2017-08-15 20:53:17 +00:00
func splitCamelCase ( src string ) string {
entries := camelcase . Split ( src )
return strings . Join ( entries , " " )
}
2017-09-28 18:44:48 +00:00
// validateFlags searches for StringFlags or StringSlice flags that never had
// a value set. This commonly occurs when the CLI mistakenly takes the next
// option and uses it as a value.
func validateFlags ( c * cli . Context , flags [ ] cli . Flag ) error {
for _ , flag := range flags {
switch reflect . TypeOf ( flag ) . String ( ) {
case "cli.StringSliceFlag" :
{
f := flag . ( cli . StringSliceFlag )
name := strings . Split ( f . Name , "," )
val := c . StringSlice ( name [ 0 ] )
for _ , v := range val {
if ok , _ := regexp . MatchString ( "^-.+" , v ) ; ok {
return errors . Errorf ( "option --%s requires a value" , name [ 0 ] )
}
}
}
case "cli.StringFlag" :
{
f := flag . ( cli . StringFlag )
name := strings . Split ( f . Name , "," )
val := c . String ( name [ 0 ] )
if ok , _ := regexp . MatchString ( "^-.+" , val ) ; ok {
return errors . Errorf ( "option --%s requires a value" , name [ 0 ] )
}
}
}
}
return nil
}
2017-10-09 20:35:59 +00:00
// Common flags shared between commands
var createFlags = [ ] cli . Flag {
cli . StringSliceFlag {
Name : "add-host" ,
Usage : "Add a custom host-to-IP mapping (host:ip) (default [])" ,
} ,
cli . StringSliceFlag {
Name : "attach, a" ,
Usage : "Attach to STDIN, STDOUT or STDERR (default [])" ,
} ,
cli . Int64Flag {
Name : "blkio-weight" ,
Usage : "Block IO weight (relative weight) accepts a weight value between 10 and 1000." ,
} ,
cli . StringSliceFlag {
Name : "blkio-weight-device" ,
Usage : "Block IO weight (relative device weight, format: `DEVICE_NAME:WEIGHT`)" ,
} ,
cli . StringSliceFlag {
Name : "cap-add" ,
Usage : "Add capabilities to the container" ,
} ,
cli . StringSliceFlag {
Name : "cap-drop" ,
Usage : "Drop capabilities from the container" ,
} ,
cli . StringFlag {
Name : "cgroup-parent" ,
Usage : "Optional parent cgroup for the container" ,
} ,
cli . Int64Flag {
Name : "cpu-count" ,
Usage : "Limit the number of CPUs available for execution by the container." ,
} ,
cli . StringFlag {
Name : "cid-file" ,
Usage : "Write the container ID to the file" ,
} ,
cli . Int64Flag {
Name : "cpu-period" ,
Usage : "Limit the CPU CFS (Completely Fair Scheduler) period" ,
} ,
cli . Int64Flag {
Name : "cpu-quota" ,
Usage : "Limit the CPU CFS (Completely Fair Scheduler) quota" ,
} ,
cli . Int64Flag {
Name : "cpu-rt-period" ,
Usage : "Limit the CPU real-time period in microseconds" ,
} ,
cli . Int64Flag {
Name : "cpu-rt-runtime" ,
Usage : "Limit the CPU real-time runtime in microseconds" ,
} ,
cli . Int64Flag {
Name : "cpu-shares" ,
Usage : "CPU shares (relative weight)" ,
} ,
cli . StringFlag {
Name : "cpus" ,
Usage : "Number of CPUs. The default is 0.000 which means no limit" ,
} ,
cli . StringFlag {
Name : "cpuset-cpus" ,
Usage : "CPUs in which to allow execution (0-3, 0,1)" ,
} ,
cli . StringFlag {
Name : "cpuset-mems" ,
Usage : "Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems." ,
} ,
cli . BoolFlag {
Name : "detach, d" ,
Usage : "Run container in background and print container ID" ,
} ,
cli . StringFlag {
Name : "detach-keys" ,
Usage : "Override the key sequence for detaching a container. Format is a single character `[a-Z]` or `ctrl-<value>` where `<value>` is one of: `a-z`, `@`, `^`, `[`, `,` or `_`" ,
} ,
cli . StringSliceFlag {
Name : "device" ,
Usage : "Add a host device to the container (default [])" ,
} ,
cli . StringSliceFlag {
Name : "device-read-bps" ,
Usage : "Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb)" ,
} ,
cli . StringSliceFlag {
Name : "device-read-iops" ,
Usage : "Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000)" ,
} ,
cli . StringSliceFlag {
Name : "device-write-bps" ,
Usage : "Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb)" ,
} ,
cli . StringSliceFlag {
Name : "device-write-iops" ,
Usage : "Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000)" ,
} ,
cli . StringSliceFlag {
Name : "dns" ,
Usage : "Set custom DNS servers" ,
} ,
cli . StringSliceFlag {
Name : "dns-opt" ,
Usage : "Set custom DNS options" ,
} ,
cli . StringSliceFlag {
Name : "dns-search" ,
Usage : "Set custom DNS search domains" ,
} ,
cli . StringFlag {
Name : "entrypoint" ,
Usage : "Overwrite the default ENTRYPOINT of the image" ,
} ,
cli . StringSliceFlag {
Name : "env, e" ,
Usage : "Set environment variables in container" ,
} ,
cli . StringSliceFlag {
Name : "env-file" ,
Usage : "Read in a file of environment variables" ,
} ,
cli . StringSliceFlag {
Name : "expose" ,
Usage : "Expose a port or a range of ports (default [])" ,
} ,
cli . StringSliceFlag {
Name : "group-add" ,
Usage : "Add additional groups to join (default [])" ,
} ,
cli . StringFlag {
Name : "hostname" ,
Usage : "Set container hostname" ,
} ,
cli . BoolFlag {
Name : "interactive, i" ,
Usage : "Keep STDIN open even if not attached" ,
} ,
cli . StringFlag {
Name : "ip" ,
Usage : "Container IPv4 address (e.g. 172.23.0.9)" ,
} ,
cli . StringFlag {
Name : "ip6" ,
Usage : "Container IPv6 address (e.g. 2001:db8::1b99)" ,
} ,
cli . StringFlag {
Name : "ipc" ,
Usage : "IPC Namespace to use" ,
} ,
cli . StringFlag {
Name : "kernel-memory" ,
Usage : "Kernel memory limit (format: `<number>[<unit>]`, where unit = b, k, m or g)" ,
} ,
cli . StringSliceFlag {
Name : "label" ,
Usage : "Set metadata on container (default [])" ,
} ,
cli . StringSliceFlag {
Name : "label-file" ,
Usage : "Read in a line delimited file of labels (default [])" ,
} ,
cli . StringSliceFlag {
Name : "link-local-ip" ,
Usage : "Container IPv4/IPv6 link-local addresses (default [])" ,
} ,
cli . StringFlag {
Name : "log-driver" ,
Usage : "Logging driver for the container" ,
} ,
cli . StringSliceFlag {
Name : "log-opt" ,
Usage : "Logging driver options (default [])" ,
} ,
cli . StringFlag {
Name : "mac-address" ,
Usage : "Container MAC address (e.g. 92:d0:c6:0a:29:33)" ,
} ,
cli . StringFlag {
Name : "memory, m" ,
Usage : "Memory limit (format: <number>[<unit>], where unit = b, k, m or g)" ,
} ,
cli . StringFlag {
Name : "memory-reservation" ,
Usage : "Memory soft limit (format: <number>[<unit>], where unit = b, k, m or g)" ,
} ,
cli . StringFlag {
Name : "memory-swap" ,
Usage : "Swap limit equal to memory plus swap: '-1' to enable unlimited swap" ,
} ,
cli . StringFlag {
Name : "memory-swappiness" ,
Usage : "Tune container memory swappiness (0 to 100) (default -1)" ,
} ,
cli . StringFlag {
Name : "name" ,
Usage : "Assign a name to the container" ,
} ,
cli . StringFlag {
Name : "net" ,
Usage : "Setup the network namespace" ,
} ,
cli . StringFlag {
Name : "network" ,
Usage : "Connect a container to a network (default 'default')" ,
} ,
cli . StringSliceFlag {
Name : "network-alias" ,
Usage : "Add network-scoped alias for the container (default [])" ,
} ,
cli . BoolFlag {
Name : "oom-kill-disable" ,
Usage : "Disable OOM Killer" ,
} ,
cli . StringFlag {
Name : "oom-score-adj" ,
Usage : "Tune the host's OOM preferences (-1000 to 1000)" ,
} ,
cli . StringFlag {
Name : "pid" ,
Usage : "PID Namespace to use" ,
} ,
cli . Int64Flag {
Name : "pids-limit" ,
Usage : "Tune container pids limit (set -1 for unlimited)" ,
} ,
cli . StringFlag {
Name : "pod" ,
Usage : "Run container in an existing pod" ,
} ,
cli . BoolFlag {
Name : "privileged" ,
Usage : "Give extended privileges to container" ,
} ,
cli . StringSliceFlag {
Name : "publish, p" ,
Usage : "Publish a container's port, or a range of ports, to the host (default [])" ,
} ,
cli . BoolFlag {
Name : "publish-all, P" ,
Usage : "Publish all exposed ports to random ports on the host interface" ,
} ,
cli . BoolFlag {
Name : "read-only" ,
Usage : "Make containers root filesystem read-only" ,
} ,
cli . BoolFlag {
Name : "rm" ,
Usage : "Remove container (and pod if created) after exit" ,
} ,
cli . StringSliceFlag {
Name : "security-opt" ,
Usage : "Security Options (default [])" ,
} ,
cli . StringFlag {
Name : "shm-size" ,
Usage : "Size of `/dev/shm`. The format is `<number><unit>`. default is 64 MB" ,
} ,
cli . BoolFlag {
Name : "sig-proxy" ,
Usage : "Proxy received signals to the process (default true)" ,
} ,
cli . StringFlag {
Name : "stop-signal" ,
Usage : "Signal to stop a container. Default is SIGTERM" ,
} ,
cli . IntFlag {
Name : "stop-timeout" ,
Usage : "Timeout (in seconds) to stop a container. Default is 10" ,
} ,
cli . StringSliceFlag {
Name : "storage-opt" ,
Usage : "Storage driver options per container (default [])" ,
} ,
cli . StringSliceFlag {
Name : "sysctl" ,
Usage : "Sysctl options (default [])" ,
} ,
cli . StringSliceFlag {
Name : "tmpfs" ,
Usage : "Mount a temporary filesystem (`tmpfs`) into a container (default [])" ,
} ,
cli . BoolFlag {
Name : "tty, t" ,
Usage : "Allocate a pseudo-TTY for container" ,
} ,
cli . StringSliceFlag {
Name : "ulimit" ,
Usage : "Ulimit options (default [])" ,
} ,
cli . StringFlag {
Name : "user, u" ,
Usage : "Username or UID (format: <name|uid>[:<group|gid>])" ,
} ,
cli . StringFlag {
Name : "userns" ,
Usage : "User namespace to use" ,
} ,
cli . StringFlag {
Name : "uts" ,
Usage : "UTS namespace to use" ,
} ,
cli . StringSliceFlag {
Name : "volume, v" ,
Usage : "Bind mount a volume into the container (default [])" ,
} ,
cli . StringSliceFlag {
Name : "volumes-from" ,
Usage : "Mount volumes from the specified container(s) (default [])" ,
} ,
cli . StringFlag {
Name : "workdir, w" ,
Usage : "Working `directory inside the container" ,
Value : "/" ,
} ,
}