diff options
-rwxr-xr-x | API.md | 216 | ||||
-rw-r--r-- | docs/varlink/apidoc.go | 2 | ||||
-rwxr-xr-x | hack/get_ci_vm.sh | 10 | ||||
-rw-r--r-- | libpod/container_top_linux.go | 5 | ||||
-rw-r--r-- | libpod/pod_top_linux.go | 4 | ||||
-rw-r--r-- | vendor.conf | 2 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/internal/proc/ns.go | 41 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/internal/process/process.go | 4 | ||||
-rw-r--r-- | vendor/github.com/containers/psgo/psgo.go | 127 |
9 files changed, 287 insertions, 124 deletions
@@ -147,7 +147,7 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func RestartPod(name: string) string](#RestartPod) -[func SearchImages(query: string, limit: , filter: ImageSearchFilter) ImageSearchResult](#SearchImages) +[func SearchImages(query: string, limit: ?int, filter: ImageSearchFilter) ImageSearchResult](#SearchImages) [func SendFile(type: string, length: int) string](#SendFile) @@ -1012,7 +1012,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.RestartPod '{"name": "135 ### <a name="SearchImages"></a>func SearchImages <div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;"> -method SearchImages(query: [string](https://godoc.org/builtin#string), limit: [](#), filter: [ImageSearchFilter](#ImageSearchFilter)) [ImageSearchResult](#ImageSearchResult)</div> +method SearchImages(query: [string](https://godoc.org/builtin#string), limit: [?int](#?int), filter: [ImageSearchFilter](#ImageSearchFilter)) [ImageSearchResult](#ImageSearchResult)</div> SearchImages searches available registries for images that contain the contents of "query" in their name. If "limit" is given, limits the amount of search results per registry. @@ -1352,197 +1352,197 @@ Create is an input structure for creating containers. args [[]string](#[]string) -addHost [](#) +addHost [?[]string](#?[]string) -annotation [](#) +annotation [?[]string](#?[]string) -attach [](#) +attach [?[]string](#?[]string) -blkioWeight [](#) +blkioWeight [?string](#?string) -blkioWeightDevice [](#) +blkioWeightDevice [?[]string](#?[]string) -capAdd [](#) +capAdd [?[]string](#?[]string) -capDrop [](#) +capDrop [?[]string](#?[]string) -cgroupParent [](#) +cgroupParent [?string](#?string) -cidFile [](#) +cidFile [?string](#?string) -conmonPidfile [](#) +conmonPidfile [?string](#?string) -command [](#) +command [?[]string](#?[]string) -cpuPeriod [](#) +cpuPeriod [?int](#?int) -cpuQuota [](#) +cpuQuota [?int](#?int) -cpuRtPeriod [](#) +cpuRtPeriod [?int](#?int) -cpuRtRuntime [](#) +cpuRtRuntime [?int](#?int) -cpuShares [](#) +cpuShares [?int](#?int) -cpus [](#) +cpus [?float](#?float) -cpuSetCpus [](#) +cpuSetCpus [?string](#?string) -cpuSetMems [](#) +cpuSetMems [?string](#?string) -detach [](#) +detach [?bool](#?bool) -detachKeys [](#) +detachKeys [?string](#?string) -device [](#) +device [?[]string](#?[]string) -deviceReadBps [](#) +deviceReadBps [?[]string](#?[]string) -deviceReadIops [](#) +deviceReadIops [?[]string](#?[]string) -deviceWriteBps [](#) +deviceWriteBps [?[]string](#?[]string) -deviceWriteIops [](#) +deviceWriteIops [?[]string](#?[]string) -dns [](#) +dns [?[]string](#?[]string) -dnsOpt [](#) +dnsOpt [?[]string](#?[]string) -dnsSearch [](#) +dnsSearch [?[]string](#?[]string) -dnsServers [](#) +dnsServers [?[]string](#?[]string) -entrypoint [](#) +entrypoint [?string](#?string) -env [](#) +env [?[]string](#?[]string) -envFile [](#) +envFile [?[]string](#?[]string) -expose [](#) +expose [?[]string](#?[]string) -gidmap [](#) +gidmap [?[]string](#?[]string) -groupadd [](#) +groupadd [?[]string](#?[]string) -healthcheckCommand [](#) +healthcheckCommand [?string](#?string) -healthcheckInterval [](#) +healthcheckInterval [?string](#?string) -healthcheckRetries [](#) +healthcheckRetries [?int](#?int) -healthcheckStartPeriod [](#) +healthcheckStartPeriod [?string](#?string) -healthcheckTimeout [](#) +healthcheckTimeout [?string](#?string) -hostname [](#) +hostname [?string](#?string) -imageVolume [](#) +imageVolume [?string](#?string) -init [](#) +init [?bool](#?bool) -initPath [](#) +initPath [?string](#?string) -interactive [](#) +interactive [?bool](#?bool) -ip [](#) +ip [?string](#?string) -ipc [](#) +ipc [?string](#?string) -kernelMemory [](#) +kernelMemory [?string](#?string) -label [](#) +label [?[]string](#?[]string) -labelFile [](#) +labelFile [?[]string](#?[]string) -logDriver [](#) +logDriver [?string](#?string) -logOpt [](#) +logOpt [?[]string](#?[]string) -macAddress [](#) +macAddress [?string](#?string) -memory [](#) +memory [?string](#?string) -memoryReservation [](#) +memoryReservation [?string](#?string) -memorySwap [](#) +memorySwap [?string](#?string) -memorySwappiness [](#) +memorySwappiness [?int](#?int) -name [](#) +name [?string](#?string) -net [](#) +net [?string](#?string) -network [](#) +network [?string](#?string) -noHosts [](#) +noHosts [?bool](#?bool) -oomKillDisable [](#) +oomKillDisable [?bool](#?bool) -oomScoreAdj [](#) +oomScoreAdj [?int](#?int) -pid [](#) +pid [?string](#?string) -pidsLimit [](#) +pidsLimit [?int](#?int) -pod [](#) +pod [?string](#?string) -privileged [](#) +privileged [?bool](#?bool) -publish [](#) +publish [?[]string](#?[]string) -publishAll [](#) +publishAll [?bool](#?bool) -quiet [](#) +quiet [?bool](#?bool) -readonly [](#) +readonly [?bool](#?bool) -readonlytmpfs [](#) +readonlytmpfs [?bool](#?bool) -restart [](#) +restart [?string](#?string) -rm [](#) +rm [?bool](#?bool) -rootfs [](#) +rootfs [?bool](#?bool) -securityOpt [](#) +securityOpt [?[]string](#?[]string) -shmSize [](#) +shmSize [?string](#?string) -stopSignal [](#) +stopSignal [?string](#?string) -stopTimeout [](#) +stopTimeout [?int](#?int) -storageOpt [](#) +storageOpt [?[]string](#?[]string) -subuidname [](#) +subuidname [?string](#?string) -subgidname [](#) +subgidname [?string](#?string) -sysctl [](#) +sysctl [?[]string](#?[]string) -systemd [](#) +systemd [?bool](#?bool) -tmpfs [](#) +tmpfs [?[]string](#?[]string) -tty [](#) +tty [?bool](#?bool) -uidmap [](#) +uidmap [?[]string](#?[]string) -ulimit [](#) +ulimit [?[]string](#?[]string) -user [](#) +user [?string](#?string) -userns [](#) +userns [?string](#?string) -uts [](#) +uts [?string](#?string) -mount [](#) +mount [?[]string](#?[]string) -volume [](#) +volume [?[]string](#?[]string) -volumesFrom [](#) +volumesFrom [?[]string](#?[]string) -workDir [](#) +workDir [?string](#?string) ### <a name="DiffInfo"></a>type DiffInfo @@ -1628,9 +1628,9 @@ compress [bool](https://godoc.org/builtin#bool) -is_official [](#) +is_official [?bool](#?bool) -is_automated [](#) +is_automated [?bool](#?bool) star_count [int](https://godoc.org/builtin#int) ### <a name="ImageSearchResult"></a>type ImageSearchResult @@ -1882,21 +1882,21 @@ mounts [string](https://godoc.org/builtin#string) all [bool](https://godoc.org/builtin#bool) -filters [](#) +filters [?[]string](#?[]string) -last [](#) +last [?int](#?int) -latest [](#) +latest [?bool](#?bool) -noTrunc [](#) +noTrunc [?bool](#?bool) -pod [](#) +pod [?bool](#?bool) -quiet [](#) +quiet [?bool](#?bool) -sort [](#) +sort [?string](#?string) -sync [](#) +sync [?bool](#?bool) ### <a name="Runlabel"></a>type Runlabel Runlabel describes the required input for container runlabel diff --git a/docs/varlink/apidoc.go b/docs/varlink/apidoc.go index 7f1d60bc8..884ce54fe 100644 --- a/docs/varlink/apidoc.go +++ b/docs/varlink/apidoc.go @@ -44,6 +44,8 @@ func typeToString(input *idl.Type) string { return "map[string]" case idl.TypeInt: return "int" + case idl.TypeMaybe: + return fmt.Sprintf("?%s", typeToString(input.ElementType)) } return "" } diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index 370cd8a5e..aed0042fb 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -231,10 +231,10 @@ then "$HOME/.config/gcloud/configurations/config_default" fi -# Couldn't make rsync work with gcloud's ssh wrapper :( +# Couldn't make rsync work with gcloud's ssh wrapper because ssh-keys generated on the fly TARBALL=$VMNAME.tar.bz2 -echo -e "\n${YEL}Packing up repository into a tarball $VMNAME.${NOR}" -showrun --background tar cjf $TMPDIR/$TARBALL --warning=no-file-changed -C $LIBPODROOT . +echo -e "\n${YEL}Packing up local repository into a tarball.${NOR}" +showrun --background tar cjf $TMPDIR/$TARBALL --warning=no-file-changed --exclude-vcs-ignores -C $LIBPODROOT . trap delvm INT # Allow deleting VM if CTRL-C during create # This fails if VM already exists: permit this usage to re-init @@ -275,7 +275,9 @@ showrun $SSH_CMD --command "rm -f /tmp/$TARBALL" echo -e "\n${YEL}Executing environment setup${NOR}" showrun $SSH_CMD --command "$SETUP_CMD" -echo -e "\n${YEL}Connecting to $VMNAME\n${RED}(option to delete VM upon logout).${NOR}\n" +VMIP=$($PGCLOUD compute instances describe $VMNAME --format='get(networkInterfaces[0].accessConfigs[0].natIP)') + +echo -e "\n${YEL}Connecting to $VMNAME${NOR}\nPublic IP Address: $VMIP\n${RED}(option to delete VM upon logout).${NOR}\n" if [[ -n "$ROOTLESS_USER" ]] then echo "Re-chowning source files after transfer" diff --git a/libpod/container_top_linux.go b/libpod/container_top_linux.go index 392a7029e..2e0e83c05 100644 --- a/libpod/container_top_linux.go +++ b/libpod/container_top_linux.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/containers/libpod/pkg/rootless" "github.com/containers/psgo" "github.com/pkg/errors" ) @@ -47,7 +48,9 @@ func (c *Container) GetContainerPidInformation(descriptors []string) ([]string, // filters on the data. We need to change the API here and the // varlink API to return a [][]string if we want to make use of // filtering. - psgoOutput, err := psgo.JoinNamespaceAndProcessInfo(pid, descriptors) + opts := psgo.JoinNamespaceOpts{FillMappings: rootless.IsRootless()} + + psgoOutput, err := psgo.JoinNamespaceAndProcessInfoWithOptions(pid, descriptors, &opts) if err != nil { return nil, err } diff --git a/libpod/pod_top_linux.go b/libpod/pod_top_linux.go index f49e28c9d..e08e5e83a 100644 --- a/libpod/pod_top_linux.go +++ b/libpod/pod_top_linux.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" + "github.com/containers/libpod/pkg/rootless" "github.com/containers/psgo" ) @@ -43,7 +44,8 @@ func (p *Pod) GetPodPidInformation(descriptors []string) ([]string, error) { // filters on the data. We need to change the API here and the // varlink API to return a [][]string if we want to make use of // filtering. - output, err := psgo.JoinNamespaceAndProcessInfoByPids(pids, descriptors) + opts := psgo.JoinNamespaceOpts{FillMappings: rootless.IsRootless()} + output, err := psgo.JoinNamespaceAndProcessInfoByPidsWithOptions(pids, descriptors, &opts) if err != nil { return nil, err } diff --git a/vendor.conf b/vendor.conf index f9b7b128d..5c41d6908 100644 --- a/vendor.conf +++ b/vendor.conf @@ -20,7 +20,7 @@ github.com/vbauerster/mpb v3.3.4 github.com/mattn/go-isatty v0.0.4 github.com/VividCortex/ewma v1.1.1 github.com/containers/storage v1.12.7 -github.com/containers/psgo v1.2.1 +github.com/containers/psgo v1.3.0 github.com/coreos/go-systemd v14 github.com/coreos/pkg v4 github.com/cri-o/ocicni 0c180f981b27ef6036fa5be29bcb4dd666e406eb diff --git a/vendor/github.com/containers/psgo/internal/proc/ns.go b/vendor/github.com/containers/psgo/internal/proc/ns.go index 5d5ef2814..53e5ebda0 100644 --- a/vendor/github.com/containers/psgo/internal/proc/ns.go +++ b/vendor/github.com/containers/psgo/internal/proc/ns.go @@ -15,10 +15,20 @@ package proc import ( + "bufio" "fmt" + "io" "os" + + "github.com/pkg/errors" ) +type IDMap struct { + ContainerID int + HostID int + Size int +} + // ParsePIDNamespace returns the content of /proc/$pid/ns/pid. func ParsePIDNamespace(pid string) (string, error) { pidNS, err := os.Readlink(fmt.Sprintf("/proc/%s/ns/pid", pid)) @@ -36,3 +46,34 @@ func ParseUserNamespace(pid string) (string, error) { } return userNS, nil } + +// ReadMappings reads the user namespace mappings at the specified path +func ReadMappings(path string) ([]IDMap, error) { + file, err := os.Open(path) + if err != nil { + return nil, errors.Wrapf(err, "cannot open %s", path) + } + defer file.Close() + + mappings := []IDMap{} + + buf := bufio.NewReader(file) + for { + line, _, err := buf.ReadLine() + if err != nil { + if err == io.EOF { + return mappings, nil + } + return nil, errors.Wrapf(err, "cannot read line from %s", path) + } + if line == nil { + return mappings, nil + } + + containerID, hostID, size := 0, 0, 0 + if _, err := fmt.Sscanf(string(line), "%d %d %d", &containerID, &hostID, &size); err != nil { + return nil, errors.Wrapf(err, "cannot parse %s", string(line)) + } + mappings = append(mappings, IDMap{ContainerID: containerID, HostID: hostID, Size: size}) + } +} diff --git a/vendor/github.com/containers/psgo/internal/process/process.go b/vendor/github.com/containers/psgo/internal/process/process.go index 2aebfe9cc..68241264e 100644 --- a/vendor/github.com/containers/psgo/internal/process/process.go +++ b/vendor/github.com/containers/psgo/internal/process/process.go @@ -45,7 +45,7 @@ type Process struct { Hgroup string } -// LookupGID returns the textual group ID, if it can be optained, or the +// LookupGID returns the textual group ID, if it can be obtained, or the // decimal representation otherwise. func LookupGID(gid string) (string, error) { gidNum, err := strconv.Atoi(gid) @@ -59,7 +59,7 @@ func LookupGID(gid string) (string, error) { return g.Name, nil } -// LookupUID return the textual user ID, if it can be optained, or the decimal +// LookupUID return the textual user ID, if it can be obtained, or the decimal // representation otherwise. func LookupUID(uid string) (string, error) { uidNum, err := strconv.Atoi(uid) diff --git a/vendor/github.com/containers/psgo/psgo.go b/vendor/github.com/containers/psgo/psgo.go index f1936f917..4986c9c71 100644 --- a/vendor/github.com/containers/psgo/psgo.go +++ b/vendor/github.com/containers/psgo/psgo.go @@ -28,6 +28,7 @@ package psgo import ( "fmt" + "io/ioutil" "os" "runtime" "sort" @@ -43,6 +44,31 @@ import ( "golang.org/x/sys/unix" ) +// IDMap specifies a mapping range from the host to the container IDs. +type IDMap struct { + // ContainerID is the first ID in the container. + ContainerID int + // HostID is the first ID in the host. + HostID int + // Size specifies how long is the range. e.g. 1 means a single user + // is mapped. + Size int +} + +// JoinNamespaceOpts specifies different options for joining the specified namespaces. +type JoinNamespaceOpts struct { + // UIDMap specifies a mapping for UIDs in the container. If specified + // huser will perform the reverse mapping. + UIDMap []IDMap + // GIDMap specifies a mapping for GIDs in the container. If specified + // hgroup will perform the reverse mapping. + GIDMap []IDMap + + // FillMappings specified whether UIDMap and GIDMap must be initialized + // with the current user namespace. + FillMappings bool +} + type psContext struct { // Processes in the container. containersProcesses []*process.Process @@ -50,6 +76,8 @@ type psContext struct { hostProcesses []*process.Process // tty and pty devices. ttys *[]dev.TTY + // Various options + opts *JoinNamespaceOpts } // processFunc is used to map a given aixFormatDescriptor to a corresponding @@ -69,10 +97,36 @@ type aixFormatDescriptor struct { // onHost controls if data of the corresponding host processes will be // extracted as well. onHost bool - // procFN points to the corresponding method to etract the desired data. + // procFN points to the corresponding method to extract the desired data. procFn processFunc } +// findID converts the specified id to the host mapping +func findID(idStr string, mapping []IDMap, lookupFunc func(uid string) (string, error), overflowFile string) (string, error) { + if len(mapping) == 0 { + return idStr, nil + } + + id, err := strconv.ParseInt(idStr, 10, 0) + if err != nil { + return "", errors.Wrapf(err, "cannot parse %s", idStr) + } + for _, m := range mapping { + if int(id) >= m.ContainerID && int(id) < m.ContainerID+m.Size { + user := fmt.Sprintf("%d", m.HostID+(int(id)-m.ContainerID)) + + return lookupFunc(user) + } + } + + // User not found, read the overflow + overflow, err := ioutil.ReadFile(overflowFile) + if err != nil { + return "", errors.Wrapf(err, "cannot read %s", overflowFile) + } + return string(overflow), nil +} + // translateDescriptors parses the descriptors and returns a correspodning slice of // aixFormatDescriptors. Descriptors can be specified in the normal and in the // code form (if supported). If the descriptors slice is empty, the @@ -272,6 +326,46 @@ func ListDescriptors() (list []string) { // JoinNamespaceAndProcessInfo has the same semantics as ProcessInfo but joins // the mount namespace of the specified pid before extracting data from `/proc`. func JoinNamespaceAndProcessInfo(pid string, descriptors []string) ([][]string, error) { + return JoinNamespaceAndProcessInfoWithOptions(pid, descriptors, &JoinNamespaceOpts{}) +} + +func readMappings(path string) ([]IDMap, error) { + mappings, err := proc.ReadMappings(path) + if err != nil { + return nil, err + } + var res []IDMap + for _, i := range mappings { + m := IDMap{ContainerID: i.ContainerID, HostID: i.HostID, Size: i.Size} + res = append(res, m) + } + return res, nil +} + +func contextFromOptions(options *JoinNamespaceOpts) (*psContext, error) { + ctx := new(psContext) + ctx.opts = options + if ctx.opts != nil && ctx.opts.FillMappings { + uidMappings, err := readMappings("/proc/self/uid_map") + if err != nil { + return nil, err + } + + gidMappings, err := readMappings("/proc/self/gid_map") + if err != nil { + return nil, err + } + ctx.opts.UIDMap = uidMappings + ctx.opts.GIDMap = gidMappings + + ctx.opts.FillMappings = false + } + return ctx, nil +} + +// JoinNamespaceAndProcessInfoWithOptions has the same semantics as ProcessInfo but joins +// the mount namespace of the specified pid before extracting data from `/proc`. +func JoinNamespaceAndProcessInfoWithOptions(pid string, descriptors []string, options *JoinNamespaceOpts) ([][]string, error) { var ( data [][]string dataErr error @@ -283,7 +377,10 @@ func JoinNamespaceAndProcessInfo(pid string, descriptors []string) ([][]string, return nil, err } - ctx := new(psContext) + ctx, err := contextFromOptions(options) + if err != nil { + return nil, err + } // extract data from host processes only on-demand / when at least one // of the specified descriptors requires host data @@ -356,10 +453,10 @@ func JoinNamespaceAndProcessInfo(pid string, descriptors []string) ([][]string, return data, dataErr } -// JoinNamespaceAndProcessInfoByPids has similar semantics to +// JoinNamespaceAndProcessInfoByPidsWithOptions has similar semantics to // JoinNamespaceAndProcessInfo and avoids duplicate entries by joining a giving -// PID namepsace only once. -func JoinNamespaceAndProcessInfoByPids(pids []string, descriptors []string) ([][]string, error) { +// PID namespace only once. +func JoinNamespaceAndProcessInfoByPidsWithOptions(pids []string, descriptors []string, options *JoinNamespaceOpts) ([][]string, error) { // Extracting data from processes that share the same PID namespace // would yield duplicate results. Avoid that by extracting data only // from the first process in `pids` from a given PID namespace. @@ -385,7 +482,7 @@ func JoinNamespaceAndProcessInfoByPids(pids []string, descriptors []string) ([][ data := [][]string{} for i, pid := range pidList { - pidData, err := JoinNamespaceAndProcessInfo(pid, descriptors) + pidData, err := JoinNamespaceAndProcessInfoWithOptions(pid, descriptors, options) if os.IsNotExist(errors.Cause(err)) { // catch race conditions continue @@ -402,6 +499,13 @@ func JoinNamespaceAndProcessInfoByPids(pids []string, descriptors []string) ([][ return data, nil } +// JoinNamespaceAndProcessInfoByPids has similar semantics to +// JoinNamespaceAndProcessInfo and avoids duplicate entries by joining a giving +// PID namespace only once. +func JoinNamespaceAndProcessInfoByPids(pids []string, descriptors []string) ([][]string, error) { + return JoinNamespaceAndProcessInfoByPidsWithOptions(pids, descriptors, &JoinNamespaceOpts{}) +} + // ProcessInfo returns the process information of all processes in the current // mount namespace. The input format must be a comma-separated list of // supported AIX format descriptors. If the input string is empty, the @@ -425,7 +529,10 @@ func ProcessInfoByPids(pids []string, descriptors []string) ([][]string, error) return nil, err } - ctx := new(psContext) + ctx, err := contextFromOptions(nil) + if err != nil { + return nil, err + } ctx.containersProcesses, err = process.FromPIDs(pids, false) if err != nil { return nil, err @@ -725,6 +832,9 @@ func processHPID(p *process.Process, ctx *psContext) (string, error) { // of the (container) or "?" if no corresponding process could be found. func processHUSER(p *process.Process, ctx *psContext) (string, error) { if hp := findHostProcess(p, ctx); hp != nil { + if ctx.opts != nil && len(ctx.opts.UIDMap) > 0 { + return findID(p.Status.Uids[1], ctx.opts.UIDMap, process.LookupUID, "/proc/sys/fs/overflowuid") + } return hp.Huser, nil } return "?", nil @@ -735,6 +845,9 @@ func processHUSER(p *process.Process, ctx *psContext) (string, error) { // found. func processHGROUP(p *process.Process, ctx *psContext) (string, error) { if hp := findHostProcess(p, ctx); hp != nil { + if ctx.opts != nil && len(ctx.opts.GIDMap) > 0 { + return findID(p.Status.Gids[1], ctx.opts.GIDMap, process.LookupGID, "/proc/sys/fs/overflowgid") + } return hp.Hgroup, nil } return "?", nil |