diff --git a/Gopkg.lock b/Gopkg.lock index 3413b682c..08118a215 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -49,6 +49,12 @@ packages = ["pkg/cover"] revision = "b0c4c6d0583aae4e3b5d12b6ec47767670548cc4" +[[projects]] + name = "github.com/docker/go-units" + packages = ["."] + revision = "47565b4f722fb6ceae66b95f853feed578a4a51c" + version = "v0.3.3" + [[projects]] name = "github.com/go-ini/ini" packages = ["."] @@ -93,7 +99,7 @@ "protocols/client", "protocols/grpc" ] - revision = "7aa11d8adef4aada89f6c68db025ff15a44eaf83" + revision = "04d58dd248a36404c33c9d12c499c60f1828060b" [[projects]] name = "github.com/kubernetes-incubator/cri-o" @@ -257,6 +263,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "cc11dcb278b249e203b53c823a9a27d5e5210b56fcaedab509651f25a5163d03" + inputs-digest = "976f719dc5f3fd1a56eb21237161c89b7f499a14e4b0638bc358698d4e0dbf8f" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index cf4e91362..f9f0b373f 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -60,7 +60,7 @@ [[constraint]] name = "github.com/kata-containers/agent" - revision = "7aa11d8adef4aada89f6c68db025ff15a44eaf83" + revision = "04d58dd248a36404c33c9d12c499c60f1828060b" [[constraint]] name = "github.com/containerd/cri-containerd" diff --git a/cli/main.go b/cli/main.go index 610145080..b84d6fff1 100644 --- a/cli/main.go +++ b/cli/main.go @@ -116,6 +116,7 @@ var runtimeCommands = []cli.Command{ specCLICommand, startCLICommand, stateCLICommand, + updateCLICommand, versionCLICommand, // Kata Containers specific extensions diff --git a/cli/update.go b/cli/update.go new file mode 100644 index 000000000..d1db024cf --- /dev/null +++ b/cli/update.go @@ -0,0 +1,261 @@ +// Copyright (c) 2016,2017 Docker, Inc. +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + "encoding/json" + "fmt" + "os" + "strconv" + + "github.com/docker/go-units" + vc "github.com/kata-containers/runtime/virtcontainers" + "github.com/opencontainers/runtime-spec/specs-go" + "github.com/urfave/cli" +) + +func i64Ptr(i int64) *int64 { return &i } +func u64Ptr(i uint64) *uint64 { return &i } +func u16Ptr(i uint16) *uint16 { return &i } + +var updateCLICommand = cli.Command{ + Name: "update", + Usage: "update container resource constraints", + ArgsUsage: ``, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "resources, r", + Value: "", + Usage: `path to the file containing the resources to update or '-' to read from the standard input + +The accepted format is as follow (unchanged values can be omitted): + +{ + "memory": { + "limit": 0, + "reservation": 0, + "swap": 0, + "kernel": 0, + "kernelTCP": 0 + }, + "cpu": { + "shares": 0, + "quota": 0, + "period": 0, + "realtimeRuntime": 0, + "realtimePeriod": 0, + "cpus": "", + "mems": "" + }, + "blockIO": { + "weight": 0 + }, + "pids": { + "limit": 0 + } +} + +Note: if data is to be read from a file or the standard input, all +other options are ignored. +`, + }, + + cli.IntFlag{ + Name: "blkio-weight", + Usage: "Specifies per cgroup weight, range is from 10 to 1000", + }, + cli.StringFlag{ + Name: "cpu-period", + Usage: "CPU CFS period to be used for hardcapping (in usecs). 0 to use system default", + }, + cli.StringFlag{ + Name: "cpu-quota", + Usage: "CPU CFS hardcap limit (in usecs). Allowed cpu time in a given period", + }, + cli.StringFlag{ + Name: "cpu-share", + Usage: "CPU shares (relative weight vs. other containers)", + }, + cli.StringFlag{ + Name: "cpu-rt-period", + Usage: "CPU realtime period to be used for hardcapping (in usecs). 0 to use system default", + }, + cli.StringFlag{ + Name: "cpu-rt-runtime", + Usage: "CPU realtime hardcap limit (in usecs). Allowed cpu time in a given period", + }, + cli.StringFlag{ + Name: "cpuset-cpus", + Usage: "CPU(s) to use", + }, + cli.StringFlag{ + Name: "cpuset-mems", + Usage: "Memory node(s) to use", + }, + cli.StringFlag{ + Name: "kernel-memory", + Usage: "Kernel memory limit (in bytes)", + }, + cli.StringFlag{ + Name: "kernel-memory-tcp", + Usage: "Kernel memory limit (in bytes) for tcp buffer", + }, + cli.StringFlag{ + Name: "memory", + Usage: "Memory limit (in bytes)", + }, + cli.StringFlag{ + Name: "memory-reservation", + Usage: "Memory reservation or soft_limit (in bytes)", + }, + cli.StringFlag{ + Name: "memory-swap", + Usage: "Total memory usage (memory + swap); set '-1' to enable unlimited swap", + }, + cli.IntFlag{ + Name: "pids-limit", + Usage: "Maximum number of pids allowed in the container", + }, + cli.StringFlag{ + Name: "l3-cache-schema", + Usage: "The string of Intel RDT/CAT L3 cache schema", + }, + }, + Action: func(context *cli.Context) error { + if context.Args().Present() == false { + return fmt.Errorf("Missing container ID, should at least provide one") + } + + containerID := context.Args().First() + status, sandboxID, err := getExistingContainerInfo(containerID) + if err != nil { + return err + } + + containerID = status.ID + // container MUST be running + if status.State.State != vc.StateRunning { + return fmt.Errorf("Container %s is not running", containerID) + } + + r := specs.LinuxResources{ + Memory: &specs.LinuxMemory{ + Limit: i64Ptr(0), + Reservation: i64Ptr(0), + Swap: i64Ptr(0), + Kernel: i64Ptr(0), + KernelTCP: i64Ptr(0), + }, + CPU: &specs.LinuxCPU{ + Shares: u64Ptr(0), + Quota: i64Ptr(0), + Period: u64Ptr(0), + RealtimeRuntime: i64Ptr(0), + RealtimePeriod: u64Ptr(0), + Cpus: "", + Mems: "", + }, + BlockIO: &specs.LinuxBlockIO{ + Weight: u16Ptr(0), + }, + Pids: &specs.LinuxPids{ + Limit: 0, + }, + } + + if in := context.String("resources"); in != "" { + var ( + f *os.File + err error + ) + switch in { + case "-": + f = os.Stdin + default: + f, err = os.Open(in) + if err != nil { + return err + } + } + err = json.NewDecoder(f).Decode(&r) + if err != nil { + return err + } + } else { + if val := context.Int("blkio-weight"); val != 0 { + r.BlockIO.Weight = u16Ptr(uint16(val)) + } + if val := context.String("cpuset-cpus"); val != "" { + r.CPU.Cpus = val + } + if val := context.String("cpuset-mems"); val != "" { + r.CPU.Mems = val + } + + for _, pair := range []struct { + opt string + dest *uint64 + }{ + + {"cpu-period", r.CPU.Period}, + {"cpu-rt-period", r.CPU.RealtimePeriod}, + {"cpu-share", r.CPU.Shares}, + } { + if val := context.String(pair.opt); val != "" { + var err error + *pair.dest, err = strconv.ParseUint(val, 10, 64) + if err != nil { + return fmt.Errorf("invalid value for %s: %s", pair.opt, err) + } + } + } + for _, pair := range []struct { + opt string + dest *int64 + }{ + + {"cpu-quota", r.CPU.Quota}, + {"cpu-rt-runtime", r.CPU.RealtimeRuntime}, + } { + if val := context.String(pair.opt); val != "" { + var err error + *pair.dest, err = strconv.ParseInt(val, 10, 64) + if err != nil { + return fmt.Errorf("invalid value for %s: %s", pair.opt, err) + } + } + } + for _, pair := range []struct { + opt string + dest *int64 + }{ + {"memory", r.Memory.Limit}, + {"memory-swap", r.Memory.Swap}, + {"kernel-memory", r.Memory.Kernel}, + {"kernel-memory-tcp", r.Memory.KernelTCP}, + {"memory-reservation", r.Memory.Reservation}, + } { + if val := context.String(pair.opt); val != "" { + var v int64 + + if val != "-1" { + v, err = units.RAMInBytes(val) + if err != nil { + return fmt.Errorf("invalid value for %s: %s", pair.opt, err) + } + } else { + v = -1 + } + *pair.dest = v + } + } + r.Pids.Limit = int64(context.Int("pids-limit")) + } + + return vci.UpdateContainer(sandboxID, containerID, r) + }, +} diff --git a/cli/update_test.go b/cli/update_test.go new file mode 100644 index 000000000..e2c2e38ce --- /dev/null +++ b/cli/update_test.go @@ -0,0 +1,205 @@ +// Copyright (c) 2018 Intel Corporation +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + "flag" + "io/ioutil" + "os" + "testing" + + vc "github.com/kata-containers/runtime/virtcontainers" + vcAnnotations "github.com/kata-containers/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/runtime/virtcontainers/pkg/vcmock" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/stretchr/testify/assert" + "github.com/urfave/cli" +) + +func TestUpdateCLIAction(t *testing.T) { + assert := assert.New(t) + + flagSet := flag.NewFlagSet("update", flag.ContinueOnError) + flagSet.Parse([]string{"resources"}) + + // create a new fake context + ctx := cli.NewContext(&cli.App{}, flagSet, nil) + + // get Action function + actionFunc, ok := updateCLICommand.Action.(func(ctx *cli.Context) error) + assert.True(ok) + + err := actionFunc(ctx) + assert.Error(err, "Missing container ID") +} + +func TestUpdateCLIFailure(t *testing.T) { + assert := assert.New(t) + + flagSet := flag.NewFlagSet("update", flag.ContinueOnError) + ctx := cli.NewContext(&cli.App{}, flagSet, nil) + + actionFunc, ok := updateCLICommand.Action.(func(ctx *cli.Context) error) + assert.True(ok) + + // missing container ID + err := actionFunc(ctx) + assert.Error(err) + + // container info + flagSet.Parse([]string{testContainerID}) + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) + + // not running + sandbox := &vcmock.Sandbox{ + MockID: testContainerID, + } + + sandbox.MockContainers = []*vcmock.Container{ + { + MockID: sandbox.ID(), + MockSandbox: sandbox, + }, + } + + path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) + assert.NoError(err) + defer os.RemoveAll(path) + + testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) { + return vc.ContainerStatus{ + ID: sandbox.ID(), + Annotations: map[string]string{ + vcAnnotations.ContainerTypeKey: string(vc.PodContainer), + }, + }, nil + } + + defer func() { + testingImpl.StatusContainerFunc = nil + }() + err = actionFunc(ctx) + assert.Error(err) + + // resources file does not exist + testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) { + return vc.ContainerStatus{ + ID: sandbox.ID(), + Annotations: map[string]string{ + vcAnnotations.ContainerTypeKey: string(vc.PodContainer), + }, + State: vc.State{ + State: vc.StateRunning, + }, + }, nil + } + testingImpl.UpdateContainerFunc = func(sandboxID, containerID string, resources specs.LinuxResources) error { + return nil + } + defer func() { + testingImpl.UpdateContainerFunc = nil + }() + flagSet.String("resources", "/abc/123/xyz/rgb", "") + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) + + // json decode error + f, err := ioutil.TempFile("", "resources") + assert.NoError(err) + assert.NotNil(f) + f.WriteString("no json") + f.Close() + flagSet.Set("resources", f.Name()) + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) + + // ParseUint Error + flagSet = flag.NewFlagSet("update", flag.ContinueOnError) + flagSet.Parse([]string{testContainerID}) + flagSet.String("cpu-period", "abcxyz", "") + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) + + // ParseInt Error + flagSet = flag.NewFlagSet("update", flag.ContinueOnError) + flagSet.Parse([]string{testContainerID}) + flagSet.String("cpu-quota", "abcxyz", "") + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) + + // RAMInBytes Error + flagSet = flag.NewFlagSet("update", flag.ContinueOnError) + flagSet.Parse([]string{testContainerID}) + flagSet.String("memory", "abcxyz", "") + ctx = cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.Error(err) +} + +func TestUpdateCLISuccessful(t *testing.T) { + assert := assert.New(t) + + sandbox := &vcmock.Sandbox{ + MockID: testContainerID, + } + + sandbox.MockContainers = []*vcmock.Container{ + { + MockID: sandbox.ID(), + MockSandbox: sandbox, + }, + } + + testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) { + return vc.ContainerStatus{ + ID: sandbox.ID(), + Annotations: map[string]string{ + vcAnnotations.ContainerTypeKey: string(vc.PodContainer), + }, + State: vc.State{ + State: vc.StateRunning, + }, + }, nil + } + testingImpl.UpdateContainerFunc = func(sandboxID, containerID string, resources specs.LinuxResources) error { + return nil + } + defer func() { + testingImpl.StatusContainerFunc = nil + testingImpl.UpdateContainerFunc = nil + }() + + path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID()) + assert.NoError(err) + defer os.RemoveAll(path) + actionFunc, ok := updateCLICommand.Action.(func(ctx *cli.Context) error) + assert.True(ok) + + flagSet := flag.NewFlagSet("update", flag.ContinueOnError) + flagSet.Parse([]string{testContainerID}) + flagSet.Int("blkio-weight", 20, "") + flagSet.String("cpuset-cpus", "0-5", "") + flagSet.String("cpuset-mems", "0-5", "") + flagSet.String("cpu-period", "1000", "") + flagSet.String("cpu-rt-period", "1000", "") + flagSet.String("cpu-share", "1000", "") + flagSet.String("cpu-quota", "1000", "") + flagSet.String("cpu-rt-runtime", "1000", "") + flagSet.String("memory", "100M", "") + flagSet.String("memory-swap", "100M", "") + flagSet.String("kernel-memory", "100M", "") + flagSet.String("kernel-memory-tcp", "100M", "") + flagSet.String("memory-reservation", "100M", "") + ctx := cli.NewContext(&cli.App{}, flagSet, nil) + err = actionFunc(ctx) + assert.NoError(err) +} diff --git a/vendor/github.com/docker/go-units/LICENSE b/vendor/github.com/docker/go-units/LICENSE new file mode 100644 index 000000000..b55b37bc3 --- /dev/null +++ b/vendor/github.com/docker/go-units/LICENSE @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + https://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2015 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go new file mode 100644 index 000000000..85f6ab071 --- /dev/null +++ b/vendor/github.com/docker/go-units/size.go @@ -0,0 +1,108 @@ +package units + +import ( + "fmt" + "regexp" + "strconv" + "strings" +) + +// See: http://en.wikipedia.org/wiki/Binary_prefix +const ( + // Decimal + + KB = 1000 + MB = 1000 * KB + GB = 1000 * MB + TB = 1000 * GB + PB = 1000 * TB + + // Binary + + KiB = 1024 + MiB = 1024 * KiB + GiB = 1024 * MiB + TiB = 1024 * GiB + PiB = 1024 * TiB +) + +type unitMap map[string]int64 + +var ( + decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB} + binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB} + sizeRegex = regexp.MustCompile(`^(\d+(\.\d+)*) ?([kKmMgGtTpP])?[iI]?[bB]?$`) +) + +var decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} +var binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} + +func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) { + i := 0 + unitsLimit := len(_map) - 1 + for size >= base && i < unitsLimit { + size = size / base + i++ + } + return size, _map[i] +} + +// CustomSize returns a human-readable approximation of a size +// using custom format. +func CustomSize(format string, size float64, base float64, _map []string) string { + size, unit := getSizeAndUnit(size, base, _map) + return fmt.Sprintf(format, size, unit) +} + +// HumanSizeWithPrecision allows the size to be in any precision, +// instead of 4 digit precision used in units.HumanSize. +func HumanSizeWithPrecision(size float64, precision int) string { + size, unit := getSizeAndUnit(size, 1000.0, decimapAbbrs) + return fmt.Sprintf("%.*g%s", precision, size, unit) +} + +// HumanSize returns a human-readable approximation of a size +// capped at 4 valid numbers (eg. "2.746 MB", "796 KB"). +func HumanSize(size float64) string { + return HumanSizeWithPrecision(size, 4) +} + +// BytesSize returns a human-readable size in bytes, kibibytes, +// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB"). +func BytesSize(size float64) string { + return CustomSize("%.4g%s", size, 1024.0, binaryAbbrs) +} + +// FromHumanSize returns an integer from a human-readable specification of a +// size using SI standard (eg. "44kB", "17MB"). +func FromHumanSize(size string) (int64, error) { + return parseSize(size, decimalMap) +} + +// RAMInBytes parses a human-readable string representing an amount of RAM +// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and +// returns the number of bytes, or -1 if the string is unparseable. +// Units are case-insensitive, and the 'b' suffix is optional. +func RAMInBytes(size string) (int64, error) { + return parseSize(size, binaryMap) +} + +// Parses the human-readable size string into the amount it represents. +func parseSize(sizeStr string, uMap unitMap) (int64, error) { + matches := sizeRegex.FindStringSubmatch(sizeStr) + if len(matches) != 4 { + return -1, fmt.Errorf("invalid size: '%s'", sizeStr) + } + + size, err := strconv.ParseFloat(matches[1], 64) + if err != nil { + return -1, err + } + + unitPrefix := strings.ToLower(matches[3]) + if mul, ok := uMap[unitPrefix]; ok { + size *= float64(mul) + } + + return int64(size), nil +} diff --git a/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go b/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go index d70011c1a..f4a4e1752 100644 --- a/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go +++ b/vendor/github.com/kata-containers/agent/protocols/grpc/agent.pb.go @@ -19,6 +19,7 @@ WaitProcessResponse ListProcessesRequest ListProcessesResponse + UpdateContainerRequest WriteStreamRequest WriteStreamResponse ReadStreamRequest @@ -384,6 +385,30 @@ func (m *ListProcessesResponse) GetProcessList() []byte { return nil } +type UpdateContainerRequest struct { + ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` + Resources *LinuxResources `protobuf:"bytes,2,opt,name=resources" json:"resources,omitempty"` +} + +func (m *UpdateContainerRequest) Reset() { *m = UpdateContainerRequest{} } +func (m *UpdateContainerRequest) String() string { return proto.CompactTextString(m) } +func (*UpdateContainerRequest) ProtoMessage() {} +func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{9} } + +func (m *UpdateContainerRequest) GetContainerId() string { + if m != nil { + return m.ContainerId + } + return "" +} + +func (m *UpdateContainerRequest) GetResources() *LinuxResources { + if m != nil { + return m.Resources + } + return nil +} + type WriteStreamRequest struct { ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` ExecId string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` @@ -393,7 +418,7 @@ type WriteStreamRequest struct { func (m *WriteStreamRequest) Reset() { *m = WriteStreamRequest{} } func (m *WriteStreamRequest) String() string { return proto.CompactTextString(m) } func (*WriteStreamRequest) ProtoMessage() {} -func (*WriteStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{9} } +func (*WriteStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{10} } func (m *WriteStreamRequest) GetContainerId() string { if m != nil { @@ -423,7 +448,7 @@ type WriteStreamResponse struct { func (m *WriteStreamResponse) Reset() { *m = WriteStreamResponse{} } func (m *WriteStreamResponse) String() string { return proto.CompactTextString(m) } func (*WriteStreamResponse) ProtoMessage() {} -func (*WriteStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{10} } +func (*WriteStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{11} } func (m *WriteStreamResponse) GetLen() uint32 { if m != nil { @@ -441,7 +466,7 @@ type ReadStreamRequest struct { func (m *ReadStreamRequest) Reset() { *m = ReadStreamRequest{} } func (m *ReadStreamRequest) String() string { return proto.CompactTextString(m) } func (*ReadStreamRequest) ProtoMessage() {} -func (*ReadStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{11} } +func (*ReadStreamRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{12} } func (m *ReadStreamRequest) GetContainerId() string { if m != nil { @@ -471,7 +496,7 @@ type ReadStreamResponse struct { func (m *ReadStreamResponse) Reset() { *m = ReadStreamResponse{} } func (m *ReadStreamResponse) String() string { return proto.CompactTextString(m) } func (*ReadStreamResponse) ProtoMessage() {} -func (*ReadStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{12} } +func (*ReadStreamResponse) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{13} } func (m *ReadStreamResponse) GetData() []byte { if m != nil { @@ -488,7 +513,7 @@ type CloseStdinRequest struct { func (m *CloseStdinRequest) Reset() { *m = CloseStdinRequest{} } func (m *CloseStdinRequest) String() string { return proto.CompactTextString(m) } func (*CloseStdinRequest) ProtoMessage() {} -func (*CloseStdinRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{13} } +func (*CloseStdinRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{14} } func (m *CloseStdinRequest) GetContainerId() string { if m != nil { @@ -514,7 +539,7 @@ type TtyWinResizeRequest struct { func (m *TtyWinResizeRequest) Reset() { *m = TtyWinResizeRequest{} } func (m *TtyWinResizeRequest) String() string { return proto.CompactTextString(m) } func (*TtyWinResizeRequest) ProtoMessage() {} -func (*TtyWinResizeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{14} } +func (*TtyWinResizeRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{15} } func (m *TtyWinResizeRequest) GetContainerId() string { if m != nil { @@ -554,7 +579,7 @@ type CreateSandboxRequest struct { func (m *CreateSandboxRequest) Reset() { *m = CreateSandboxRequest{} } func (m *CreateSandboxRequest) String() string { return proto.CompactTextString(m) } func (*CreateSandboxRequest) ProtoMessage() {} -func (*CreateSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{15} } +func (*CreateSandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{16} } func (m *CreateSandboxRequest) GetHostname() string { if m != nil { @@ -590,7 +615,7 @@ type DestroySandboxRequest struct { func (m *DestroySandboxRequest) Reset() { *m = DestroySandboxRequest{} } func (m *DestroySandboxRequest) String() string { return proto.CompactTextString(m) } func (*DestroySandboxRequest) ProtoMessage() {} -func (*DestroySandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{16} } +func (*DestroySandboxRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{17} } type IPAddress struct { Family IPFamily `protobuf:"varint,1,opt,name=family,proto3,enum=grpc.IPFamily" json:"family,omitempty"` @@ -601,7 +626,7 @@ type IPAddress struct { func (m *IPAddress) Reset() { *m = IPAddress{} } func (m *IPAddress) String() string { return proto.CompactTextString(m) } func (*IPAddress) ProtoMessage() {} -func (*IPAddress) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{17} } +func (*IPAddress) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{18} } func (m *IPAddress) GetFamily() IPFamily { if m != nil { @@ -635,7 +660,7 @@ type Interface struct { func (m *Interface) Reset() { *m = Interface{} } func (m *Interface) String() string { return proto.CompactTextString(m) } func (*Interface) ProtoMessage() {} -func (*Interface) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{18} } +func (*Interface) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{19} } func (m *Interface) GetDevice() string { if m != nil { @@ -683,7 +708,7 @@ type Route struct { func (m *Route) Reset() { *m = Route{} } func (m *Route) String() string { return proto.CompactTextString(m) } func (*Route) ProtoMessage() {} -func (*Route) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{19} } +func (*Route) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{20} } func (m *Route) GetDest() string { if m != nil { @@ -727,7 +752,7 @@ type Routes struct { func (m *Routes) Reset() { *m = Routes{} } func (m *Routes) String() string { return proto.CompactTextString(m) } func (*Routes) ProtoMessage() {} -func (*Routes) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{20} } +func (*Routes) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{21} } func (m *Routes) GetRoutes() []*Route { if m != nil { @@ -743,7 +768,7 @@ type UpdateInterfaceRequest struct { func (m *UpdateInterfaceRequest) Reset() { *m = UpdateInterfaceRequest{} } func (m *UpdateInterfaceRequest) String() string { return proto.CompactTextString(m) } func (*UpdateInterfaceRequest) ProtoMessage() {} -func (*UpdateInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{21} } +func (*UpdateInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{22} } func (m *UpdateInterfaceRequest) GetInterface() *Interface { if m != nil { @@ -759,7 +784,7 @@ type AddInterfaceRequest struct { func (m *AddInterfaceRequest) Reset() { *m = AddInterfaceRequest{} } func (m *AddInterfaceRequest) String() string { return proto.CompactTextString(m) } func (*AddInterfaceRequest) ProtoMessage() {} -func (*AddInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{22} } +func (*AddInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{23} } func (m *AddInterfaceRequest) GetInterface() *Interface { if m != nil { @@ -775,7 +800,7 @@ type RemoveInterfaceRequest struct { func (m *RemoveInterfaceRequest) Reset() { *m = RemoveInterfaceRequest{} } func (m *RemoveInterfaceRequest) String() string { return proto.CompactTextString(m) } func (*RemoveInterfaceRequest) ProtoMessage() {} -func (*RemoveInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{23} } +func (*RemoveInterfaceRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{24} } func (m *RemoveInterfaceRequest) GetInterface() *Interface { if m != nil { @@ -791,7 +816,7 @@ type UpdateRoutesRequest struct { func (m *UpdateRoutesRequest) Reset() { *m = UpdateRoutesRequest{} } func (m *UpdateRoutesRequest) String() string { return proto.CompactTextString(m) } func (*UpdateRoutesRequest) ProtoMessage() {} -func (*UpdateRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{24} } +func (*UpdateRoutesRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{25} } func (m *UpdateRoutesRequest) GetRoutes() *Routes { if m != nil { @@ -812,7 +837,7 @@ type OnlineCPUMemRequest struct { func (m *OnlineCPUMemRequest) Reset() { *m = OnlineCPUMemRequest{} } func (m *OnlineCPUMemRequest) String() string { return proto.CompactTextString(m) } func (*OnlineCPUMemRequest) ProtoMessage() {} -func (*OnlineCPUMemRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{25} } +func (*OnlineCPUMemRequest) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{26} } func (m *OnlineCPUMemRequest) GetWait() bool { if m != nil { @@ -861,7 +886,7 @@ type Storage struct { func (m *Storage) Reset() { *m = Storage{} } func (m *Storage) String() string { return proto.CompactTextString(m) } func (*Storage) ProtoMessage() {} -func (*Storage) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{26} } +func (*Storage) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{27} } func (m *Storage) GetDriver() string { if m != nil { @@ -944,7 +969,7 @@ type Device struct { func (m *Device) Reset() { *m = Device{} } func (m *Device) String() string { return proto.CompactTextString(m) } func (*Device) ProtoMessage() {} -func (*Device) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{27} } +func (*Device) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{28} } func (m *Device) GetId() string { if m != nil { @@ -990,7 +1015,7 @@ type StringUser struct { func (m *StringUser) Reset() { *m = StringUser{} } func (m *StringUser) String() string { return proto.CompactTextString(m) } func (*StringUser) ProtoMessage() {} -func (*StringUser) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{28} } +func (*StringUser) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{29} } func (m *StringUser) GetUid() string { if m != nil { @@ -1023,6 +1048,7 @@ func init() { proto.RegisterType((*WaitProcessResponse)(nil), "grpc.WaitProcessResponse") proto.RegisterType((*ListProcessesRequest)(nil), "grpc.ListProcessesRequest") proto.RegisterType((*ListProcessesResponse)(nil), "grpc.ListProcessesResponse") + proto.RegisterType((*UpdateContainerRequest)(nil), "grpc.UpdateContainerRequest") proto.RegisterType((*WriteStreamRequest)(nil), "grpc.WriteStreamRequest") proto.RegisterType((*WriteStreamResponse)(nil), "grpc.WriteStreamResponse") proto.RegisterType((*ReadStreamRequest)(nil), "grpc.ReadStreamRequest") @@ -1071,6 +1097,7 @@ type AgentServiceClient interface { SignalProcess(ctx context.Context, in *SignalProcessRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) WaitProcess(ctx context.Context, in *WaitProcessRequest, opts ...grpc1.CallOption) (*WaitProcessResponse, error) ListProcesses(ctx context.Context, in *ListProcessesRequest, opts ...grpc1.CallOption) (*ListProcessesResponse, error) + UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) // stdio WriteStdin(ctx context.Context, in *WriteStreamRequest, opts ...grpc1.CallOption) (*WriteStreamResponse, error) ReadStdout(ctx context.Context, in *ReadStreamRequest, opts ...grpc1.CallOption) (*ReadStreamResponse, error) @@ -1159,6 +1186,15 @@ func (c *agentServiceClient) ListProcesses(ctx context.Context, in *ListProcesse return out, nil } +func (c *agentServiceClient) UpdateContainer(ctx context.Context, in *UpdateContainerRequest, opts ...grpc1.CallOption) (*google_protobuf2.Empty, error) { + out := new(google_protobuf2.Empty) + err := grpc1.Invoke(ctx, "/grpc.AgentService/UpdateContainer", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *agentServiceClient) WriteStdin(ctx context.Context, in *WriteStreamRequest, opts ...grpc1.CallOption) (*WriteStreamResponse, error) { out := new(WriteStreamResponse) err := grpc1.Invoke(ctx, "/grpc.AgentService/WriteStdin", in, out, c.cc, opts...) @@ -1284,6 +1320,7 @@ type AgentServiceServer interface { SignalProcess(context.Context, *SignalProcessRequest) (*google_protobuf2.Empty, error) WaitProcess(context.Context, *WaitProcessRequest) (*WaitProcessResponse, error) ListProcesses(context.Context, *ListProcessesRequest) (*ListProcessesResponse, error) + UpdateContainer(context.Context, *UpdateContainerRequest) (*google_protobuf2.Empty, error) // stdio WriteStdin(context.Context, *WriteStreamRequest) (*WriteStreamResponse, error) ReadStdout(context.Context, *ReadStreamRequest) (*ReadStreamResponse, error) @@ -1431,6 +1468,24 @@ func _AgentService_ListProcesses_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _AgentService_UpdateContainer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateContainerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AgentServiceServer).UpdateContainer(ctx, in) + } + info := &grpc1.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.AgentService/UpdateContainer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AgentServiceServer).UpdateContainer(ctx, req.(*UpdateContainerRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _AgentService_WriteStdin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) { in := new(WriteStreamRequest) if err := dec(in); err != nil { @@ -1679,6 +1734,10 @@ var _AgentService_serviceDesc = grpc1.ServiceDesc{ MethodName: "ListProcesses", Handler: _AgentService_ListProcesses_Handler, }, + { + MethodName: "UpdateContainer", + Handler: _AgentService_UpdateContainer_Handler, + }, { MethodName: "WriteStdin", Handler: _AgentService_WriteStdin_Handler, @@ -2066,6 +2125,40 @@ func (m *ListProcessesResponse) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *UpdateContainerRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UpdateContainerRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.ContainerId) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintAgent(dAtA, i, uint64(len(m.ContainerId))) + i += copy(dAtA[i:], m.ContainerId) + } + if m.Resources != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintAgent(dAtA, i, uint64(m.Resources.Size())) + n5, err := m.Resources.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n5 + } + return i, nil +} + func (m *WriteStreamRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -2517,11 +2610,11 @@ func (m *UpdateInterfaceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintAgent(dAtA, i, uint64(m.Interface.Size())) - n5, err := m.Interface.MarshalTo(dAtA[i:]) + n6, err := m.Interface.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n5 + i += n6 } return i, nil } @@ -2545,11 +2638,11 @@ func (m *AddInterfaceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintAgent(dAtA, i, uint64(m.Interface.Size())) - n6, err := m.Interface.MarshalTo(dAtA[i:]) + n7, err := m.Interface.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n6 + i += n7 } return i, nil } @@ -2573,11 +2666,11 @@ func (m *RemoveInterfaceRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintAgent(dAtA, i, uint64(m.Interface.Size())) - n7, err := m.Interface.MarshalTo(dAtA[i:]) + n8, err := m.Interface.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n7 + i += n8 } return i, nil } @@ -2601,11 +2694,11 @@ func (m *UpdateRoutesRequest) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintAgent(dAtA, i, uint64(m.Routes.Size())) - n8, err := m.Routes.MarshalTo(dAtA[i:]) + n9, err := m.Routes.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n8 + i += n9 } return i, nil } @@ -2975,6 +3068,20 @@ func (m *ListProcessesResponse) Size() (n int) { return n } +func (m *UpdateContainerRequest) Size() (n int) { + var l int + _ = l + l = len(m.ContainerId) + if l > 0 { + n += 1 + l + sovAgent(uint64(l)) + } + if m.Resources != nil { + l = m.Resources.Size() + n += 1 + l + sovAgent(uint64(l)) + } + return n +} + func (m *WriteStreamRequest) Size() (n int) { var l int _ = l @@ -4431,6 +4538,118 @@ func (m *ListProcessesResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *UpdateContainerRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UpdateContainerRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UpdateContainerRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContainerId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Resources", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAgent + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAgent + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Resources == nil { + m.Resources = &LinuxResources{} + } + if err := m.Resources.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAgent(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthAgent + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *WriteStreamRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -6975,91 +7194,93 @@ var ( func init() { proto.RegisterFile("agent.proto", fileDescriptorAgent) } var fileDescriptorAgent = []byte{ - // 1367 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0x5f, 0x6f, 0x1b, 0xc5, - 0x16, 0xbf, 0x1b, 0x3b, 0x4e, 0x7c, 0x6c, 0x27, 0xe9, 0x24, 0x4d, 0xf6, 0xba, 0x55, 0x6f, 0xba, - 0xf7, 0xde, 0x36, 0x20, 0x35, 0x15, 0x01, 0x81, 0x54, 0x84, 0x4a, 0xea, 0x96, 0x10, 0x09, 0x14, - 0x6b, 0x4c, 0x54, 0xde, 0xac, 0xc9, 0xee, 0xc4, 0x59, 0xf0, 0xee, 0x2c, 0x33, 0xb3, 0x49, 0x43, - 0xdf, 0x79, 0xe0, 0x99, 0x8f, 0xc1, 0x1b, 0x5f, 0x82, 0x47, 0x3e, 0x02, 0xea, 0xa7, 0xe0, 0x11, - 0xcd, 0xbf, 0xb5, 0xd7, 0x59, 0x17, 0xd1, 0x46, 0xe2, 0x69, 0xe7, 0x9c, 0x33, 0x7b, 0xce, 0x6f, - 0xce, 0x9c, 0x39, 0xe7, 0x07, 0x2d, 0x32, 0xa2, 0xa9, 0xdc, 0xcd, 0x38, 0x93, 0x0c, 0xd5, 0x47, - 0x3c, 0x0b, 0xbb, 0x4d, 0x16, 0xc6, 0x46, 0xd1, 0xbd, 0x35, 0x62, 0x6c, 0x34, 0xa6, 0x0f, 0xb5, - 0x74, 0x92, 0x9f, 0x3e, 0xa4, 0x49, 0x26, 0x2f, 0x8d, 0x31, 0xf8, 0xc3, 0x83, 0xcd, 0x1e, 0xa7, - 0x44, 0xd2, 0x1e, 0x4b, 0x25, 0x89, 0x53, 0xca, 0x31, 0xfd, 0x2e, 0xa7, 0x42, 0xa2, 0xbb, 0xd0, - 0x0e, 0x9d, 0x6e, 0x18, 0x47, 0xbe, 0xb7, 0xed, 0xed, 0x34, 0x71, 0xab, 0xd0, 0x1d, 0x46, 0x68, - 0x0b, 0x96, 0xe8, 0x0b, 0x1a, 0x2a, 0xeb, 0x82, 0xb6, 0x36, 0x94, 0x78, 0x18, 0xa1, 0xf7, 0xa0, - 0x25, 0x24, 0x8f, 0xd3, 0xd1, 0x30, 0x17, 0x94, 0xfb, 0xb5, 0x6d, 0x6f, 0xa7, 0xb5, 0xb7, 0xb6, - 0xab, 0xa0, 0xed, 0x0e, 0xb4, 0xe1, 0x58, 0x50, 0x8e, 0x41, 0x14, 0x6b, 0x74, 0x0f, 0x96, 0x22, - 0x7a, 0x1e, 0x87, 0x54, 0xf8, 0xf5, 0xed, 0xda, 0x4e, 0x6b, 0xaf, 0x6d, 0xb6, 0x3f, 0xd5, 0x4a, - 0xec, 0x8c, 0xe8, 0x1d, 0x58, 0x16, 0x92, 0x71, 0x32, 0xa2, 0xc2, 0x5f, 0xd4, 0x1b, 0x3b, 0xce, - 0xaf, 0xd6, 0xe2, 0xc2, 0x8c, 0x6e, 0x43, 0xed, 0xa8, 0x77, 0xe8, 0x37, 0x74, 0x74, 0xb0, 0xbb, - 0x32, 0x1a, 0x62, 0xa5, 0x0e, 0x1e, 0xc1, 0xcd, 0x81, 0x24, 0x5c, 0xbe, 0xc1, 0xc1, 0x83, 0x63, - 0xd8, 0xc4, 0x34, 0x61, 0xe7, 0x6f, 0x94, 0x35, 0x1f, 0x96, 0x64, 0x9c, 0x50, 0x96, 0x4b, 0x9d, - 0xb5, 0x0e, 0x76, 0x62, 0xf0, 0xb3, 0x07, 0xe8, 0xd9, 0x0b, 0x1a, 0xf6, 0x39, 0x0b, 0xa9, 0x10, - 0xff, 0xd0, 0x4d, 0xdc, 0x87, 0xa5, 0xcc, 0x00, 0xf0, 0xeb, 0x7a, 0xbb, 0x4d, 0xb0, 0x43, 0xe5, - 0xac, 0xc1, 0x37, 0xb0, 0x31, 0x88, 0x47, 0x29, 0x19, 0x5f, 0x23, 0xde, 0x4d, 0x68, 0x08, 0xed, - 0x53, 0x43, 0xed, 0x60, 0x2b, 0x05, 0x7d, 0x40, 0xcf, 0x49, 0x2c, 0xaf, 0x2f, 0x52, 0xf0, 0x00, - 0xd6, 0x4b, 0x1e, 0x45, 0xc6, 0x52, 0x41, 0x35, 0x00, 0x49, 0x64, 0x2e, 0xb4, 0xb3, 0x45, 0x6c, - 0xa5, 0x80, 0xc2, 0xc6, 0x17, 0xb1, 0x70, 0xdb, 0xe9, 0xdf, 0x81, 0xb0, 0x09, 0x8d, 0x53, 0xc6, - 0x13, 0x22, 0x1d, 0x02, 0x23, 0x21, 0x04, 0x75, 0xc2, 0x47, 0xc2, 0xaf, 0x6d, 0xd7, 0x76, 0x9a, - 0x58, 0xaf, 0x55, 0x55, 0xce, 0x84, 0xb1, 0xb8, 0xee, 0x42, 0xdb, 0xe6, 0x7d, 0x38, 0x8e, 0x85, - 0xd4, 0x71, 0xda, 0xb8, 0x65, 0x75, 0xea, 0x9f, 0x20, 0x02, 0xf4, 0x9c, 0xc7, 0x92, 0x0e, 0x24, - 0xa7, 0x24, 0xb9, 0x8e, 0xdb, 0x40, 0x50, 0x8f, 0x88, 0x24, 0xfa, 0x2e, 0xda, 0x58, 0xaf, 0x83, - 0xfb, 0xb0, 0x5e, 0x8a, 0x62, 0xf1, 0xad, 0x41, 0x6d, 0x4c, 0x53, 0xed, 0xbd, 0x83, 0xd5, 0x32, - 0x20, 0x70, 0x03, 0x53, 0x12, 0x5d, 0x1f, 0x1a, 0x1b, 0xa2, 0x36, 0x09, 0xb1, 0x03, 0x68, 0x3a, - 0x84, 0x85, 0xe2, 0x50, 0x7b, 0x53, 0xa8, 0x8f, 0xe0, 0x46, 0x6f, 0xcc, 0x04, 0x1d, 0xc8, 0x28, - 0x4e, 0xaf, 0xa3, 0x7c, 0x5e, 0xc2, 0xfa, 0x57, 0xf2, 0xf2, 0xb9, 0x72, 0x26, 0xe2, 0xef, 0xe9, - 0x35, 0x9d, 0x8f, 0xb3, 0x0b, 0x77, 0x3e, 0xce, 0x2e, 0x54, 0xe5, 0x84, 0x6c, 0x9c, 0x27, 0xa9, - 0x7e, 0x89, 0x1d, 0x6c, 0xa5, 0xe0, 0x27, 0x0f, 0x36, 0x4c, 0xdb, 0x1e, 0x90, 0x34, 0x3a, 0x61, - 0x2f, 0x5c, 0xf8, 0x2e, 0x2c, 0x9f, 0x31, 0x21, 0x53, 0x92, 0x50, 0x1b, 0xba, 0x90, 0x95, 0xfb, - 0x28, 0x15, 0xfe, 0x82, 0xae, 0x36, 0xb5, 0x2c, 0xf5, 0xd2, 0xda, 0xeb, 0x7b, 0xe9, 0x7f, 0xa1, - 0x23, 0x4c, 0xa8, 0x61, 0x16, 0x2b, 0x37, 0x0a, 0xd0, 0x32, 0x6e, 0x5b, 0x65, 0x5f, 0xe9, 0x82, - 0x2d, 0xb8, 0xf9, 0x94, 0x0a, 0xc9, 0xd9, 0x65, 0x19, 0x56, 0x40, 0xa0, 0x79, 0xd8, 0xdf, 0x8f, - 0x22, 0x4e, 0x85, 0x40, 0xf7, 0xa0, 0x71, 0x4a, 0x92, 0x78, 0x7c, 0xa9, 0x11, 0xae, 0xec, 0xad, - 0x98, 0x98, 0x87, 0xfd, 0xcf, 0xb4, 0x16, 0x5b, 0xab, 0xea, 0x93, 0xc4, 0xfc, 0x62, 0xf3, 0xe4, - 0x44, 0x75, 0xc1, 0x09, 0x11, 0xdf, 0xea, 0x4c, 0x35, 0xb1, 0x5e, 0xab, 0x94, 0x34, 0x0f, 0x53, - 0x49, 0xf9, 0x29, 0x09, 0xf5, 0x2b, 0x36, 0x03, 0xc3, 0x66, 0xc1, 0x4a, 0xea, 0x4f, 0x9d, 0x1b, - 0xe3, 0x50, 0xaf, 0x55, 0x8b, 0x2c, 0xc0, 0x15, 0x89, 0x58, 0x75, 0xa0, 0xac, 0x01, 0x4f, 0xef, - 0x51, 0xa9, 0x4c, 0x64, 0xae, 0x73, 0x50, 0xc7, 0x6a, 0xa9, 0x02, 0x9e, 0x5d, 0xa8, 0x0d, 0xfe, - 0xa2, 0x09, 0x68, 0xa4, 0xe0, 0x25, 0x2c, 0x62, 0x96, 0x4b, 0x53, 0x94, 0xd4, 0xbe, 0xdb, 0x26, - 0xd6, 0x6b, 0x75, 0xc2, 0x11, 0x91, 0xf4, 0x82, 0x5c, 0xba, 0x13, 0x5a, 0x71, 0x0a, 0x7f, 0xad, - 0x84, 0x5f, 0x75, 0x27, 0x96, 0xf3, 0x90, 0xea, 0xd8, 0x4d, 0x6c, 0x25, 0xb4, 0x01, 0x8b, 0x22, - 0x64, 0x19, 0xd5, 0xd1, 0x3b, 0xd8, 0x08, 0xc1, 0x03, 0x68, 0xe8, 0xe0, 0xea, 0xfa, 0xec, 0xca, - 0xf7, 0xf4, 0xf1, 0x5a, 0xe6, 0x78, 0x5a, 0x87, 0xad, 0x29, 0x38, 0x80, 0xcd, 0xe3, 0x2c, 0x22, - 0x92, 0x16, 0x79, 0x74, 0x65, 0xf5, 0x00, 0x9a, 0xb1, 0xd3, 0xe9, 0x13, 0x4c, 0x12, 0x54, 0x6c, - 0x9d, 0xec, 0x08, 0x9e, 0xc2, 0xfa, 0x7e, 0x14, 0xbd, 0xad, 0x97, 0x03, 0x37, 0x64, 0xdf, 0xd6, - 0xd1, 0xc7, 0xb0, 0x6e, 0xce, 0x65, 0xce, 0xe9, 0xbc, 0xfc, 0x0f, 0x1a, 0xdc, 0xe5, 0xc4, 0x9b, - 0x10, 0x0e, 0xbb, 0xc9, 0xda, 0x82, 0x27, 0xb0, 0x7e, 0x94, 0x8e, 0xe3, 0x94, 0xf6, 0xfa, 0xc7, - 0x5f, 0xd2, 0xa2, 0x8f, 0x21, 0xa8, 0x5f, 0x90, 0xd8, 0x5c, 0xe7, 0x32, 0xd6, 0x6b, 0xf5, 0xb0, - 0xd3, 0x93, 0x61, 0x98, 0xe5, 0xc2, 0x0e, 0xf6, 0x46, 0x7a, 0xd2, 0xcb, 0x72, 0x11, 0xfc, 0xe2, - 0xc1, 0x92, 0x7d, 0x52, 0xfa, 0x66, 0x79, 0x7c, 0x4e, 0x79, 0x51, 0x99, 0x5a, 0x42, 0xff, 0x87, - 0x15, 0xb3, 0x1a, 0xb2, 0x4c, 0xc6, 0xac, 0x78, 0xa8, 0x1d, 0xa3, 0x3d, 0x32, 0xca, 0xa9, 0x02, - 0xa8, 0x95, 0x0a, 0x40, 0xcd, 0x18, 0x21, 0x2f, 0xb3, 0xa2, 0x30, 0x8c, 0xa4, 0x4a, 0xcc, 0xf9, - 0x5b, 0xd4, 0xfe, 0x9c, 0x88, 0xfe, 0x03, 0xad, 0x84, 0xe5, 0xa9, 0x1c, 0x66, 0x2c, 0x4e, 0xa5, - 0x66, 0x49, 0x4d, 0x0c, 0x5a, 0xd5, 0x57, 0x9a, 0xe0, 0x07, 0x0f, 0x1a, 0x86, 0x7d, 0xa1, 0x15, - 0x58, 0x28, 0x7a, 0xd9, 0x42, 0xac, 0xe7, 0x82, 0x8e, 0x65, 0x9f, 0x91, 0x8e, 0xb4, 0x05, 0x4b, - 0xe7, 0xc9, 0x30, 0x23, 0xf2, 0xcc, 0x41, 0x3b, 0x4f, 0xfa, 0x44, 0x9e, 0xa9, 0x93, 0x4d, 0x5a, - 0xa2, 0xb6, 0x1b, 0x88, 0x9d, 0x42, 0xab, 0xb7, 0xcd, 0x45, 0x1a, 0x7c, 0x0d, 0x30, 0xa1, 0x2a, - 0xea, 0xed, 0xe5, 0x05, 0x18, 0xb5, 0x54, 0x9a, 0x51, 0xd1, 0x4c, 0xd5, 0x12, 0xdd, 0x83, 0x15, - 0x12, 0x45, 0xb1, 0xfa, 0x9d, 0x8c, 0x0f, 0xe2, 0xc8, 0xcd, 0xd8, 0x19, 0xed, 0xbb, 0x5d, 0x58, - 0x76, 0x6d, 0x07, 0x35, 0x60, 0xe1, 0xfc, 0x83, 0xb5, 0x7f, 0xe9, 0xef, 0x87, 0x6b, 0xde, 0xde, - 0x8f, 0x00, 0xed, 0x7d, 0x45, 0xac, 0x07, 0x94, 0xeb, 0x24, 0x1c, 0xc0, 0xea, 0x0c, 0x55, 0x46, - 0xb7, 0x4d, 0xc9, 0x54, 0x33, 0xe8, 0xee, 0xe6, 0xae, 0xa1, 0xde, 0xbb, 0x8e, 0x7a, 0xef, 0x3e, - 0x53, 0xd4, 0x1b, 0x3d, 0x83, 0x95, 0x32, 0xf3, 0x44, 0xb7, 0x5c, 0xdb, 0xad, 0xe0, 0xa3, 0x73, - 0xdd, 0x1c, 0xc0, 0xea, 0x0c, 0x09, 0x75, 0x78, 0xaa, 0xb9, 0xe9, 0x5c, 0x47, 0x8f, 0xa1, 0x35, - 0xc5, 0x3a, 0x91, 0x6f, 0x9c, 0x5c, 0x25, 0xa2, 0x73, 0x1d, 0xf4, 0xa0, 0x53, 0x22, 0x82, 0xa8, - 0x6b, 0xcf, 0x53, 0xc1, 0x0e, 0xe7, 0x3a, 0x79, 0x02, 0xad, 0x29, 0x3e, 0xe6, 0x50, 0x5c, 0x25, - 0x7d, 0xdd, 0x7f, 0x57, 0x58, 0xec, 0xe4, 0xff, 0x1c, 0x3a, 0x25, 0xf6, 0xe4, 0x80, 0x54, 0x31, - 0xb7, 0xee, 0xad, 0x4a, 0x9b, 0xf5, 0xb4, 0x0f, 0x60, 0x59, 0x4e, 0x14, 0xa7, 0x05, 0x98, 0x2b, - 0xec, 0xaa, 0x00, 0x53, 0xc1, 0x88, 0x1e, 0x03, 0x18, 0x72, 0x12, 0xb1, 0x5c, 0xa2, 0x2d, 0x77, - 0x35, 0x33, 0x8c, 0xa8, 0xeb, 0x5f, 0x35, 0x5c, 0x71, 0x40, 0x39, 0x7f, 0x13, 0x07, 0x9f, 0x00, - 0x4c, 0x48, 0x8f, 0x73, 0x70, 0x85, 0x06, 0xcd, 0xbd, 0x91, 0x7d, 0x68, 0x4f, 0x53, 0x1c, 0x64, - 0xcf, 0x5a, 0x41, 0x7b, 0xe6, 0xba, 0x78, 0x04, 0xed, 0xe9, 0x49, 0xe0, 0x5c, 0x54, 0x4c, 0x87, - 0xee, 0x6c, 0x07, 0x47, 0x9f, 0xc2, 0xea, 0xcc, 0x38, 0x72, 0xf5, 0x5d, 0x3d, 0xa5, 0x2a, 0x3d, - 0xcc, 0x4c, 0x90, 0xf2, 0x0b, 0xf9, 0x6b, 0x0f, 0x1f, 0x41, 0x7b, 0x7a, 0x74, 0x38, 0xfc, 0x15, - 0xe3, 0xa4, 0x5b, 0x1a, 0x1f, 0xea, 0x49, 0x94, 0x08, 0x9a, 0xab, 0xc4, 0x2a, 0xd6, 0xf6, 0xba, - 0x46, 0x51, 0xe6, 0x53, 0xae, 0x51, 0x54, 0xb2, 0xac, 0xd7, 0xdd, 0xe3, 0xf4, 0x08, 0x73, 0x87, - 0xa8, 0x18, 0x6b, 0xf3, 0x5c, 0x3c, 0x69, 0xff, 0xfa, 0xea, 0x8e, 0xf7, 0xdb, 0xab, 0x3b, 0xde, - 0xef, 0xaf, 0xee, 0x78, 0x27, 0x0d, 0x6d, 0x7d, 0xff, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x42, - 0x3f, 0x03, 0x5f, 0x79, 0x10, 0x00, 0x00, + // 1403 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xdd, 0x6e, 0x1b, 0xb7, + 0x12, 0x3e, 0x6b, 0xc9, 0xb2, 0x35, 0x92, 0x6c, 0x87, 0x76, 0x6c, 0x1d, 0x25, 0xc8, 0x71, 0xf6, + 0x9c, 0x93, 0xb8, 0x05, 0xe2, 0xa0, 0x6e, 0xd1, 0x02, 0x29, 0x8a, 0xd4, 0x51, 0x52, 0xd7, 0x40, + 0x0a, 0x0b, 0x54, 0x8d, 0xf4, 0x4e, 0xa0, 0xb5, 0xb4, 0xcc, 0x56, 0x5a, 0x6e, 0x49, 0xae, 0x7f, + 0x9a, 0xfb, 0x3e, 0x41, 0x1f, 0xa3, 0x77, 0x7d, 0x89, 0x5e, 0x16, 0xe8, 0x0b, 0x14, 0x79, 0x8a, + 0x5e, 0x16, 0xfc, 0x5b, 0x69, 0xe5, 0x95, 0xdb, 0x3a, 0x06, 0x7a, 0xb5, 0x9c, 0x19, 0xee, 0xcc, + 0x37, 0x43, 0x72, 0xe6, 0x83, 0x1a, 0x19, 0xd0, 0x58, 0x6d, 0x27, 0x82, 0x2b, 0x8e, 0xca, 0x03, + 0x91, 0xf4, 0x5b, 0x55, 0xde, 0x67, 0x56, 0xd1, 0xba, 0x33, 0xe0, 0x7c, 0x30, 0xa4, 0x8f, 0x8d, + 0x74, 0x94, 0x1e, 0x3f, 0xa6, 0xa3, 0x44, 0x5d, 0x58, 0x63, 0xf8, 0x7b, 0x00, 0xeb, 0x6d, 0x41, + 0x89, 0xa2, 0x6d, 0x1e, 0x2b, 0xc2, 0x62, 0x2a, 0x30, 0xfd, 0x36, 0xa5, 0x52, 0xa1, 0xfb, 0x50, + 0xef, 0x7b, 0x5d, 0x8f, 0x45, 0xcd, 0x60, 0x33, 0xd8, 0xaa, 0xe2, 0x5a, 0xa6, 0xdb, 0x8f, 0xd0, + 0x06, 0x2c, 0xd0, 0x73, 0xda, 0xd7, 0xd6, 0x39, 0x63, 0xad, 0x68, 0x71, 0x3f, 0x42, 0xef, 0x41, + 0x4d, 0x2a, 0xc1, 0xe2, 0x41, 0x2f, 0x95, 0x54, 0x34, 0x4b, 0x9b, 0xc1, 0x56, 0x6d, 0x67, 0x65, + 0x5b, 0x43, 0xdb, 0xee, 0x1a, 0xc3, 0xa1, 0xa4, 0x02, 0x83, 0xcc, 0xd6, 0xe8, 0x01, 0x2c, 0x44, + 0xf4, 0x94, 0xf5, 0xa9, 0x6c, 0x96, 0x37, 0x4b, 0x5b, 0xb5, 0x9d, 0xba, 0xdd, 0xfe, 0xdc, 0x28, + 0xb1, 0x37, 0xa2, 0x77, 0x60, 0x51, 0x2a, 0x2e, 0xc8, 0x80, 0xca, 0xe6, 0xbc, 0xd9, 0xd8, 0xf0, + 0x7e, 0x8d, 0x16, 0x67, 0x66, 0x74, 0x17, 0x4a, 0x07, 0xed, 0xfd, 0x66, 0xc5, 0x44, 0x07, 0xb7, + 0x2b, 0xa1, 0x7d, 0xac, 0xd5, 0xe1, 0x13, 0xb8, 0xdd, 0x55, 0x44, 0xa8, 0x6b, 0x24, 0x1e, 0x1e, + 0xc2, 0x3a, 0xa6, 0x23, 0x7e, 0x7a, 0xad, 0xaa, 0x35, 0x61, 0x41, 0xb1, 0x11, 0xe5, 0xa9, 0x32, + 0x55, 0x6b, 0x60, 0x2f, 0x86, 0x3f, 0x06, 0x80, 0x5e, 0x9c, 0xd3, 0x7e, 0x47, 0xf0, 0x3e, 0x95, + 0xf2, 0x1f, 0x3a, 0x89, 0x87, 0xb0, 0x90, 0x58, 0x00, 0xcd, 0xb2, 0xd9, 0xee, 0x0a, 0xec, 0x51, + 0x79, 0x6b, 0xf8, 0x35, 0xac, 0x75, 0xd9, 0x20, 0x26, 0xc3, 0x1b, 0xc4, 0xbb, 0x0e, 0x15, 0x69, + 0x7c, 0x1a, 0xa8, 0x0d, 0xec, 0xa4, 0xb0, 0x03, 0xe8, 0x15, 0x61, 0xea, 0xe6, 0x22, 0x85, 0x8f, + 0x60, 0x35, 0xe7, 0x51, 0x26, 0x3c, 0x96, 0xd4, 0x00, 0x50, 0x44, 0xa5, 0xd2, 0x38, 0x9b, 0xc7, + 0x4e, 0x0a, 0x29, 0xac, 0xbd, 0x64, 0xd2, 0x6f, 0xa7, 0x7f, 0x07, 0xc2, 0x3a, 0x54, 0x8e, 0xb9, + 0x18, 0x11, 0xe5, 0x11, 0x58, 0x09, 0x21, 0x28, 0x13, 0x31, 0x90, 0xcd, 0xd2, 0x66, 0x69, 0xab, + 0x8a, 0xcd, 0x5a, 0xdf, 0xca, 0xa9, 0x30, 0x0e, 0xd7, 0x7d, 0xa8, 0xbb, 0xba, 0xf7, 0x86, 0x4c, + 0x2a, 0x13, 0xa7, 0x8e, 0x6b, 0x4e, 0xa7, 0xff, 0x09, 0x39, 0xac, 0x1f, 0x26, 0xd1, 0x35, 0xdf, + 0xf2, 0x0e, 0x54, 0x05, 0x95, 0x3c, 0x15, 0xfa, 0x05, 0xce, 0x99, 0x73, 0x5f, 0xb3, 0xe7, 0xfe, + 0x92, 0xc5, 0xe9, 0x39, 0xf6, 0x36, 0x3c, 0xde, 0x16, 0x46, 0x80, 0x5e, 0x09, 0xa6, 0x68, 0x57, + 0x09, 0x4a, 0x46, 0x37, 0x71, 0xfc, 0x08, 0xca, 0x11, 0x51, 0xc4, 0x1c, 0x7e, 0x1d, 0x9b, 0x75, + 0xf8, 0x10, 0x56, 0x73, 0x51, 0x5c, 0x41, 0x56, 0xa0, 0x34, 0xa4, 0xb1, 0xf1, 0xde, 0xc0, 0x7a, + 0x19, 0x12, 0xb8, 0x85, 0x29, 0x89, 0x6e, 0x0e, 0x8d, 0x0b, 0x51, 0x1a, 0x87, 0xd8, 0x02, 0x34, + 0x19, 0xc2, 0x41, 0xf1, 0xa8, 0x83, 0x09, 0xd4, 0x07, 0x70, 0xab, 0x3d, 0xe4, 0x92, 0x76, 0x55, + 0xc4, 0xe2, 0x9b, 0xb8, 0xaf, 0xaf, 0x61, 0xf5, 0x4b, 0x75, 0xf1, 0x4a, 0x3b, 0x93, 0xec, 0x3b, + 0x7a, 0x43, 0xf9, 0x09, 0x7e, 0xe6, 0xf3, 0x13, 0xfc, 0x4c, 0x5f, 0xd5, 0x3e, 0x1f, 0xa6, 0xa3, + 0xd8, 0x3c, 0xfd, 0x06, 0x76, 0x52, 0xf8, 0x43, 0x00, 0x6b, 0x76, 0x4e, 0x74, 0x49, 0x1c, 0x1d, + 0xf1, 0x73, 0x1f, 0xbe, 0x05, 0x8b, 0x27, 0x5c, 0xaa, 0x98, 0x8c, 0xa8, 0x0b, 0x9d, 0xc9, 0xda, + 0x7d, 0x14, 0xeb, 0xcb, 0xa4, 0xaf, 0xb7, 0x5e, 0xe6, 0x9a, 0x77, 0xe9, 0xea, 0xe6, 0xfd, 0x5f, + 0x68, 0x48, 0x1b, 0xaa, 0x97, 0x30, 0xed, 0x46, 0x03, 0x5a, 0xc4, 0x75, 0xa7, 0xec, 0x68, 0x5d, + 0xb8, 0x01, 0xb7, 0x9f, 0x53, 0xa9, 0x04, 0xbf, 0xc8, 0xc3, 0x0a, 0x09, 0x54, 0xf7, 0x3b, 0xbb, + 0x51, 0x24, 0xa8, 0x94, 0xe8, 0x01, 0x54, 0x8e, 0xc9, 0x88, 0x0d, 0x2f, 0x0c, 0xc2, 0xa5, 0x9d, + 0x25, 0x1b, 0x73, 0xbf, 0xf3, 0x99, 0xd1, 0x62, 0x67, 0xd5, 0x8d, 0x99, 0xd8, 0x5f, 0x5c, 0x9d, + 0xbc, 0xa8, 0x0f, 0x78, 0x44, 0xe4, 0x37, 0xa6, 0x52, 0x55, 0x6c, 0xd6, 0xba, 0x24, 0xd5, 0xfd, + 0x58, 0x51, 0x71, 0x4c, 0xfa, 0xa6, 0x6d, 0xd8, 0x09, 0xe5, 0xaa, 0xe0, 0x24, 0xfd, 0xa7, 0xa9, + 0x8d, 0x75, 0x68, 0xd6, 0xba, 0x27, 0x67, 0xe0, 0xb2, 0x42, 0x2c, 0x7b, 0x50, 0xce, 0x80, 0x27, + 0xf7, 0xe8, 0x52, 0x8e, 0x54, 0x6a, 0x6a, 0x50, 0xc6, 0x7a, 0xa9, 0x03, 0x9e, 0x9c, 0xe9, 0x0d, + 0xcd, 0x79, 0x1b, 0xd0, 0x4a, 0xe1, 0x6b, 0x98, 0xc7, 0x3c, 0x55, 0xf6, 0x52, 0x52, 0xd7, 0x28, + 0xaa, 0xd8, 0xac, 0x75, 0x86, 0x03, 0xa2, 0xe8, 0x19, 0xb9, 0xf0, 0x19, 0x3a, 0x71, 0x02, 0x7f, + 0x29, 0x87, 0x5f, 0xb7, 0x43, 0xf3, 0xda, 0x4d, 0xec, 0x2a, 0x76, 0x12, 0x5a, 0x83, 0x79, 0xd9, + 0xe7, 0x09, 0x35, 0xd1, 0x1b, 0xd8, 0x0a, 0xe1, 0x23, 0xa8, 0x98, 0xe0, 0xfa, 0xf8, 0xdc, 0xaa, + 0x19, 0x98, 0xf4, 0x6a, 0x36, 0x3d, 0xa3, 0xc3, 0xce, 0x14, 0xee, 0xf9, 0x86, 0x95, 0xd5, 0xd1, + 0x5f, 0xab, 0x47, 0x50, 0x65, 0x5e, 0x67, 0x32, 0x18, 0x17, 0x28, 0xdb, 0x3a, 0xde, 0x11, 0x3e, + 0x87, 0xd5, 0xdd, 0x28, 0x7a, 0x5b, 0x2f, 0x7b, 0x7e, 0xaa, 0xbf, 0xad, 0xa3, 0x8f, 0x61, 0xd5, + 0xe6, 0x65, 0xf3, 0xf4, 0x5e, 0xfe, 0x07, 0x15, 0xe1, 0x6b, 0x12, 0x8c, 0x19, 0x8e, 0xdb, 0xe4, + 0x6c, 0xe1, 0x33, 0x58, 0x3d, 0x88, 0x87, 0x2c, 0xa6, 0xed, 0xce, 0xe1, 0x17, 0x34, 0xeb, 0x63, + 0x08, 0xca, 0x67, 0x84, 0xd9, 0xe3, 0x5c, 0xc4, 0x66, 0xad, 0x1f, 0x76, 0x7c, 0xd4, 0xeb, 0x27, + 0xa9, 0x74, 0x4c, 0xa2, 0x12, 0x1f, 0xb5, 0x93, 0x54, 0x86, 0x3f, 0x05, 0xb0, 0xe0, 0x9e, 0x94, + 0x39, 0x59, 0xc1, 0x4e, 0xa9, 0xc8, 0x6e, 0xa6, 0x91, 0xd0, 0xff, 0x61, 0xc9, 0xae, 0x7a, 0x3c, + 0x51, 0x8c, 0x67, 0x0f, 0xb5, 0x61, 0xb5, 0x07, 0x56, 0x39, 0x71, 0x01, 0x4a, 0xb9, 0x0b, 0xa0, + 0x87, 0x9a, 0x54, 0x17, 0x49, 0x76, 0x31, 0xac, 0xa4, 0xaf, 0x98, 0xf7, 0x37, 0x6f, 0xfc, 0x79, + 0x11, 0xfd, 0x07, 0x6a, 0x23, 0x9e, 0xc6, 0xaa, 0x97, 0x70, 0x16, 0x2b, 0x43, 0xcb, 0xaa, 0x18, + 0x8c, 0xaa, 0xa3, 0x35, 0xe1, 0xf7, 0x01, 0x54, 0x2c, 0xdd, 0x43, 0x4b, 0x30, 0x97, 0xf5, 0xb2, + 0x39, 0x66, 0xe6, 0x82, 0x89, 0xe5, 0x9e, 0x91, 0x89, 0xb4, 0x01, 0x0b, 0xa7, 0xa3, 0x5e, 0x42, + 0xd4, 0x89, 0x87, 0x76, 0x3a, 0xea, 0x10, 0x75, 0xa2, 0x33, 0x1b, 0xb7, 0x44, 0x63, 0xb7, 0x10, + 0x1b, 0x99, 0xd6, 0x6c, 0x9b, 0x89, 0x34, 0xfc, 0x0a, 0x60, 0xcc, 0x8d, 0xf4, 0xdb, 0x4b, 0x33, + 0x30, 0x7a, 0xa9, 0x35, 0x83, 0xac, 0x99, 0xea, 0x25, 0x7a, 0x00, 0x4b, 0x24, 0x8a, 0x98, 0xfe, + 0x9d, 0x0c, 0xf7, 0x58, 0xe4, 0x87, 0xfa, 0x94, 0xf6, 0xdd, 0x16, 0x2c, 0xfa, 0xb6, 0x83, 0x2a, + 0x30, 0x77, 0xfa, 0xc1, 0xca, 0xbf, 0xcc, 0xf7, 0xc3, 0x95, 0x60, 0xe7, 0x57, 0x80, 0xfa, 0xae, + 0x66, 0xf2, 0x5d, 0x2a, 0x4c, 0x11, 0xf6, 0x60, 0x79, 0x8a, 0x9b, 0xa3, 0xbb, 0xf6, 0xca, 0x14, + 0x53, 0xf6, 0xd6, 0xfa, 0xb6, 0xe5, 0xfa, 0xdb, 0x9e, 0xeb, 0x6f, 0xbf, 0xd0, 0x5c, 0x1f, 0xbd, + 0x80, 0xa5, 0x3c, 0xd5, 0x45, 0x77, 0x7c, 0xdb, 0x2d, 0x20, 0xc0, 0x33, 0xdd, 0xec, 0xc1, 0xf2, + 0x14, 0xeb, 0xf5, 0x78, 0x8a, 0xc9, 0xf0, 0x4c, 0x47, 0x4f, 0xa1, 0x36, 0x41, 0x73, 0x51, 0xd3, + 0x3a, 0xb9, 0xcc, 0x7c, 0x67, 0x3a, 0x68, 0x43, 0x23, 0xc7, 0x3c, 0x51, 0xcb, 0xe5, 0x53, 0x40, + 0x47, 0x67, 0x3a, 0x79, 0x06, 0xb5, 0x09, 0x02, 0xe8, 0x51, 0x5c, 0x66, 0x99, 0xad, 0x7f, 0x17, + 0x58, 0xdc, 0xe4, 0xff, 0x1c, 0x1a, 0x39, 0xba, 0xe6, 0x81, 0x14, 0x51, 0xc5, 0xd6, 0x9d, 0x42, + 0x9b, 0xf3, 0xb4, 0x07, 0xcb, 0x53, 0xe4, 0xcd, 0x17, 0xb7, 0x98, 0xd3, 0xcd, 0x4c, 0x6b, 0x17, + 0xc0, 0xd1, 0xa5, 0x88, 0xc5, 0x59, 0x56, 0x97, 0x68, 0x5a, 0x96, 0x55, 0x01, 0xb5, 0x7a, 0x0a, + 0x60, 0x59, 0x4e, 0xc4, 0x53, 0x85, 0x36, 0xfc, 0x19, 0x4f, 0x51, 0xab, 0x56, 0xf3, 0xb2, 0xe1, + 0x92, 0x03, 0x2a, 0xc4, 0x75, 0x1c, 0x7c, 0x02, 0x30, 0x66, 0x4f, 0xde, 0xc1, 0x25, 0x3e, 0x75, + 0x45, 0x0d, 0xea, 0x93, 0x5c, 0x09, 0xb9, 0x5c, 0x0b, 0xf8, 0xd3, 0x4c, 0x17, 0x4f, 0xa0, 0x3e, + 0x39, 0x52, 0xbc, 0x8b, 0x82, 0x31, 0xd3, 0x9a, 0x1e, 0x05, 0xe8, 0x53, 0x7f, 0x96, 0x63, 0x55, + 0xee, 0x2c, 0xff, 0x92, 0x87, 0xa9, 0x51, 0x94, 0x7f, 0x6a, 0x7f, 0xee, 0xe1, 0x23, 0xa8, 0x4f, + 0xce, 0x20, 0x8f, 0xbf, 0x60, 0x2e, 0xb5, 0x72, 0x73, 0x48, 0xbf, 0xad, 0x1c, 0xd3, 0xf3, 0x57, + 0xba, 0x88, 0xfe, 0x5d, 0xd5, 0x71, 0xf2, 0xc4, 0xcc, 0x77, 0x9c, 0x42, 0xba, 0x76, 0xd5, 0x39, + 0x4e, 0xce, 0x42, 0x9f, 0x44, 0xc1, 0x7c, 0x9c, 0xe5, 0xe2, 0x59, 0xfd, 0xe7, 0x37, 0xf7, 0x82, + 0x5f, 0xde, 0xdc, 0x0b, 0x7e, 0x7b, 0x73, 0x2f, 0x38, 0xaa, 0x18, 0xeb, 0xfb, 0x7f, 0x04, 0x00, + 0x00, 0xff, 0xff, 0xac, 0xf3, 0x61, 0xb8, 0x33, 0x11, 0x00, 0x00, } diff --git a/vendor/github.com/kata-containers/agent/protocols/grpc/utils.go b/vendor/github.com/kata-containers/agent/protocols/grpc/utils.go index 931f9bc32..ea59a3cef 100644 --- a/vendor/github.com/kata-containers/agent/protocols/grpc/utils.go +++ b/vendor/github.com/kata-containers/agent/protocols/grpc/utils.go @@ -267,3 +267,23 @@ func ProcessGRPCtoOCI(grpcProcess *Process) (*specs.Process, error) { return s, err } + +// ResourcesOCItoGRPC converts an OCI LinuxResources specification into its gRPC +// representation +func ResourcesOCItoGRPC(ociResources *specs.LinuxResources) (*LinuxResources, error) { + s := &LinuxResources{} + + err := copyStruct(s, ociResources) + + return s, err +} + +// ResourcesGRPCtoOCI converts an gRPC LinuxResources specification into its OCI +// representation +func ResourcesGRPCtoOCI(grpcResources *LinuxResources) (*specs.LinuxResources, error) { + s := &specs.LinuxResources{} + + err := copyStruct(s, grpcResources) + + return s, err +} diff --git a/virtcontainers/agent.go b/virtcontainers/agent.go index 568708e3b..a787ade7b 100644 --- a/virtcontainers/agent.go +++ b/virtcontainers/agent.go @@ -10,6 +10,7 @@ import ( "syscall" "github.com/mitchellh/mapstructure" + specs "github.com/opencontainers/runtime-spec/specs-go" ) // AgentType describes the type of guest agent a Sandbox should run. @@ -183,6 +184,9 @@ type agent interface { // processListContainer will list the processes running inside the container processListContainer(sandbox *Sandbox, c Container, options ProcessListOptions) (ProcessList, error) + // updateContainer will update the resources of a running container + updateContainer(sandbox *Sandbox, c Container, resources specs.LinuxResources) error + // waitProcess will wait for the exit code of a process waitProcess(c *Container, processID string) (int32, error) diff --git a/virtcontainers/api.go b/virtcontainers/api.go index 72687bda6..5cfb5a23f 100644 --- a/virtcontainers/api.go +++ b/virtcontainers/api.go @@ -11,6 +11,7 @@ import ( "syscall" deviceApi "github.com/kata-containers/runtime/virtcontainers/device/api" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -602,3 +603,28 @@ func ProcessListContainer(sandboxID, containerID string, options ProcessListOpti return c.processList(options) } + +// UpdateContainer is the virtcontainers entry point to update +// container's resources. +func UpdateContainer(sandboxID, containerID string, resources specs.LinuxResources) error { + if sandboxID == "" { + return errNeedSandboxID + } + + if containerID == "" { + return errNeedContainerID + } + + lockFile, err := rLockSandbox(sandboxID) + if err != nil { + return err + } + defer unlockSandbox(lockFile) + + s, err := fetchSandbox(sandboxID) + if err != nil { + return err + } + + return s.UpdateContainer(containerID, resources) +} diff --git a/virtcontainers/api_test.go b/virtcontainers/api_test.go index 2ea03c095..0a009f53e 100644 --- a/virtcontainers/api_test.go +++ b/virtcontainers/api_test.go @@ -17,6 +17,7 @@ import ( "testing" "github.com/kata-containers/runtime/virtcontainers/pkg/mock" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/stretchr/testify/assert" ) @@ -2286,3 +2287,48 @@ func TestReleaseSandbox(t *testing.T) { err = s.Release() assert.Nil(t, err, "sandbox release failed: %v", err) } + +func TestUpdateContainer(t *testing.T) { + if os.Geteuid() != 0 { + t.Skip(testDisabledAsNonRoot) + } + + cleanUp() + + period := uint64(1000) + quota := int64(2000) + assert := assert.New(t) + resources := specs.LinuxResources{ + CPU: &specs.LinuxCPU{ + Period: &period, + Quota: "a, + }, + } + err := UpdateContainer("", "", resources) + assert.Error(err) + + err = UpdateContainer("abc", "", resources) + assert.Error(err) + + contID := "100" + config := newTestSandboxConfigNoop() + + s, sandboxDir, err := createAndStartSandbox(config) + assert.NoError(err) + assert.NotNil(s) + + contConfig := newTestContainerConfigNoop(contID) + _, c, err := CreateContainer(s.ID(), contConfig) + assert.NoError(err) + assert.NotNil(c) + + contDir := filepath.Join(sandboxDir, contID) + _, err = os.Stat(contDir) + assert.NoError(err) + + _, err = StartContainer(s.ID(), contID) + assert.NoError(err) + + err = UpdateContainer(s.ID(), contID, resources) + assert.NoError(err) +} diff --git a/virtcontainers/container.go b/virtcontainers/container.go index c4574fe5e..f96cc61d3 100644 --- a/virtcontainers/container.go +++ b/virtcontainers/container.go @@ -14,6 +14,7 @@ import ( "syscall" "time" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -787,6 +788,33 @@ func (c *Container) processList(options ProcessListOptions) (ProcessList, error) return c.sandbox.agent.processListContainer(c.sandbox, *c, options) } +func (c *Container) update(resources specs.LinuxResources) error { + if err := c.checkSandboxRunning("update"); err != nil { + return err + } + + if c.state.State != StateRunning { + return fmt.Errorf("Container not running, impossible to update") + } + + // fetch current configuration + currentConfig, err := c.sandbox.storage.fetchContainerConfig(c.sandbox.id, c.id) + if err != nil { + return err + } + + newResources := ContainerResources{ + CPUPeriod: *resources.CPU.Period, + CPUQuota: *resources.CPU.Quota, + } + + if err := c.updateResources(currentConfig.Resources, newResources); err != nil { + return err + } + + return c.sandbox.agent.updateContainer(c.sandbox, *c, resources) +} + func (c *Container) hotplugDrive() error { dev, err := getDeviceForPath(c.rootFs) @@ -939,3 +967,45 @@ func (c *Container) removeResources() error { return nil } + +func (c *Container) updateResources(oldResources, newResources ContainerResources) error { + //TODO add support for memory, Issue: https://github.com/containers/virtcontainers/issues/578 + var vCPUs uint + oldVCPUs := utils.ConstraintsToVCPUs(oldResources.CPUQuota, oldResources.CPUPeriod) + newVCPUs := utils.ConstraintsToVCPUs(newResources.CPUQuota, newResources.CPUPeriod) + + // Update vCPUs is not possible if period and/or quota are not set or + // oldVCPUs and newVCPUs are equal. + // Don't fail, the constraint still can be applied in the cgroup. + if newVCPUs == 0 || oldVCPUs == newVCPUs { + c.Logger().WithFields(logrus.Fields{ + "old-vcpus": fmt.Sprintf("%d", oldVCPUs), + "new-vcpus": fmt.Sprintf("%d", newVCPUs), + }).Debug("the actual number of vCPUs will not be modified") + return nil + } + + if oldVCPUs < newVCPUs { + // hot add vCPUs + vCPUs = newVCPUs - oldVCPUs + virtLog.Debugf("hot adding %d vCPUs", vCPUs) + if err := c.sandbox.hypervisor.hotplugAddDevice(uint32(vCPUs), cpuDev); err != nil { + return err + } + } else { + // hot remove vCPUs + vCPUs = oldVCPUs - newVCPUs + virtLog.Debugf("hot removing %d vCPUs", vCPUs) + if err := c.sandbox.hypervisor.hotplugRemoveDevice(uint32(vCPUs), cpuDev); err != nil { + return err + } + } + + // Set and save container's config + c.config.Resources = newResources + if err := c.storeContainer(); err != nil { + return err + } + + return c.sandbox.agent.onlineCPUMem(uint32(vCPUs)) +} diff --git a/virtcontainers/hyperstart_agent.go b/virtcontainers/hyperstart_agent.go index 8e8e635da..6c8202577 100644 --- a/virtcontainers/hyperstart_agent.go +++ b/virtcontainers/hyperstart_agent.go @@ -19,6 +19,7 @@ import ( "github.com/kata-containers/runtime/virtcontainers/pkg/hyperstart" ns "github.com/kata-containers/runtime/virtcontainers/pkg/nsenter" "github.com/kata-containers/runtime/virtcontainers/utils" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" @@ -608,6 +609,11 @@ func (h *hyper) processListContainer(sandbox *Sandbox, c Container, options Proc return h.processListOneContainer(sandbox.id, c.id, options) } +func (h *hyper) updateContainer(sandbox *Sandbox, c Container, resources specs.LinuxResources) error { + // hyperstart-agent does not support update + return nil +} + func (h *hyper) processListOneContainer(sandboxID, cID string, options ProcessListOptions) (ProcessList, error) { psCmd := hyperstart.PsCommand{ Container: cID, diff --git a/virtcontainers/implementation.go b/virtcontainers/implementation.go index 229feca7d..dba32c506 100644 --- a/virtcontainers/implementation.go +++ b/virtcontainers/implementation.go @@ -12,6 +12,7 @@ package virtcontainers import ( "syscall" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -114,3 +115,8 @@ func (impl *VCImpl) KillContainer(sandboxID, containerID string, signal syscall. func (impl *VCImpl) ProcessListContainer(sandboxID, containerID string, options ProcessListOptions) (ProcessList, error) { return ProcessListContainer(sandboxID, containerID, options) } + +// UpdateContainer implements the VC function of the same name. +func (impl *VCImpl) UpdateContainer(sandboxID, containerID string, resources specs.LinuxResources) error { + return UpdateContainer(sandboxID, containerID, resources) +} diff --git a/virtcontainers/interfaces.go b/virtcontainers/interfaces.go index fe2b2bb46..c86736232 100644 --- a/virtcontainers/interfaces.go +++ b/virtcontainers/interfaces.go @@ -9,6 +9,7 @@ import ( "io" "syscall" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -35,6 +36,7 @@ type VC interface { StatusContainer(sandboxID, containerID string) (ContainerStatus, error) StopContainer(sandboxID, containerID string) (VCContainer, error) ProcessListContainer(sandboxID, containerID string, options ProcessListOptions) (ProcessList, error) + UpdateContainer(sandboxID, containerID string, resources specs.LinuxResources) error } // VCSandbox is the Sandbox interface @@ -58,6 +60,7 @@ type VCSandbox interface { StartContainer(containerID string) (VCContainer, error) StatusContainer(containerID string) (ContainerStatus, error) EnterContainer(containerID string, cmd Cmd) (VCContainer, *Process, error) + UpdateContainer(containerID string, resources specs.LinuxResources) error WaitProcess(containerID, processID string) (int32, error) SignalProcess(containerID, processID string, signal syscall.Signal, all bool) error WinsizeProcess(containerID, processID string, height, width uint32) error diff --git a/virtcontainers/kata_agent.go b/virtcontainers/kata_agent.go index 155b4130b..4e835200f 100644 --- a/virtcontainers/kata_agent.go +++ b/virtcontainers/kata_agent.go @@ -911,6 +911,21 @@ func (k *kataAgent) processListContainer(sandbox *Sandbox, c Container, options return processList.ProcessList, nil } +func (k *kataAgent) updateContainer(sandbox *Sandbox, c Container, resources specs.LinuxResources) error { + grpcResources, err := grpc.ResourcesOCItoGRPC(&resources) + if err != nil { + return err + } + + req := &grpc.UpdateContainerRequest{ + ContainerId: c.id, + Resources: grpcResources, + } + + _, err = k.sendReq(req) + return err +} + func (k *kataAgent) onlineCPUMem(cpus uint32) error { req := &grpc.OnlineCPUMemRequest{ Wait: false, @@ -1034,6 +1049,9 @@ func (k *kataAgent) installReqFunc(c *kataclient.AgentClient) { k.reqHandlers["grpc.ListProcessesRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { return k.client.ListProcesses(ctx, req.(*grpc.ListProcessesRequest), opts...) } + k.reqHandlers["grpc.UpdateContainerRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { + return k.client.UpdateContainer(ctx, req.(*grpc.UpdateContainerRequest), opts...) + } k.reqHandlers["grpc.WaitProcessRequest"] = func(ctx context.Context, req interface{}, opts ...golangGrpc.CallOption) (interface{}, error) { return k.client.WaitProcess(ctx, req.(*grpc.WaitProcessRequest), opts...) } diff --git a/virtcontainers/kata_agent_test.go b/virtcontainers/kata_agent_test.go index 2ddb33b8c..df87ffa73 100644 --- a/virtcontainers/kata_agent_test.go +++ b/virtcontainers/kata_agent_test.go @@ -143,6 +143,10 @@ func (p *gRPCProxy) ListProcesses(ctx context.Context, req *pb.ListProcessesRequ return &pb.ListProcessesResponse{}, nil } +func (p *gRPCProxy) UpdateContainer(ctx context.Context, req *pb.UpdateContainerRequest) (*gpb.Empty, error) { + return emptyResp, nil +} + func (p *gRPCProxy) RemoveContainer(ctx context.Context, req *pb.RemoveContainerRequest) (*gpb.Empty, error) { return emptyResp, nil } diff --git a/virtcontainers/noop_agent.go b/virtcontainers/noop_agent.go index c6905f809..e437e62c5 100644 --- a/virtcontainers/noop_agent.go +++ b/virtcontainers/noop_agent.go @@ -7,6 +7,8 @@ package virtcontainers import ( "syscall" + + specs "github.com/opencontainers/runtime-spec/specs-go" ) // noopAgent a.k.a. NO-OP Agent is an empty Agent implementation, for testing and @@ -74,6 +76,11 @@ func (n *noopAgent) processListContainer(sandbox *Sandbox, c Container, options return nil, nil } +// updateContainer is the Noop agent Container update implementation. It does nothing. +func (n *noopAgent) updateContainer(sandbox *Sandbox, c Container, resources specs.LinuxResources) error { + return nil +} + // onlineCPUMem is the Noop agent Container online CPU and Memory implementation. It does nothing. func (n *noopAgent) onlineCPUMem(cpus uint32) error { return nil diff --git a/virtcontainers/pkg/vcmock/mock.go b/virtcontainers/pkg/vcmock/mock.go index a494014ef..df9e0170f 100644 --- a/virtcontainers/pkg/vcmock/mock.go +++ b/virtcontainers/pkg/vcmock/mock.go @@ -20,6 +20,7 @@ import ( "syscall" vc "github.com/kata-containers/runtime/virtcontainers" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -195,3 +196,12 @@ func (m *VCMock) ProcessListContainer(sandboxID, containerID string, options vc. return nil, fmt.Errorf("%s: %s (%+v): sandboxID: %v, containerID: %v", mockErrorPrefix, getSelf(), m, sandboxID, containerID) } + +// UpdateContainer implements the VC function of the same name. +func (m *VCMock) UpdateContainer(sandboxID, containerID string, resources specs.LinuxResources) error { + if m.UpdateContainerFunc != nil { + return m.UpdateContainerFunc(sandboxID, containerID, resources) + } + + return fmt.Errorf("%s: %s (%+v): sandboxID: %v, containerID: %v", mockErrorPrefix, getSelf(), m, sandboxID, containerID) +} diff --git a/virtcontainers/pkg/vcmock/sandbox.go b/virtcontainers/pkg/vcmock/sandbox.go index 720e2d3af..25a44c94f 100644 --- a/virtcontainers/pkg/vcmock/sandbox.go +++ b/virtcontainers/pkg/vcmock/sandbox.go @@ -10,6 +10,7 @@ import ( "syscall" vc "github.com/kata-containers/runtime/virtcontainers" + specs "github.com/opencontainers/runtime-spec/specs-go" ) // ID implements the VCSandbox function of the same name. @@ -108,6 +109,11 @@ func (p *Sandbox) Monitor() (chan error, error) { return nil, nil } +// UpdateContainer implements the VCSandbox function of the same name. +func (p *Sandbox) UpdateContainer(containerID string, resources specs.LinuxResources) error { + return nil +} + // WaitProcess implements the VCSandbox function of the same name. func (p *Sandbox) WaitProcess(containerID, processID string) (int32, error) { return 0, nil diff --git a/virtcontainers/pkg/vcmock/types.go b/virtcontainers/pkg/vcmock/types.go index cf67b1425..36a6eb38e 100644 --- a/virtcontainers/pkg/vcmock/types.go +++ b/virtcontainers/pkg/vcmock/types.go @@ -9,6 +9,7 @@ import ( "syscall" vc "github.com/kata-containers/runtime/virtcontainers" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" ) @@ -55,4 +56,5 @@ type VCMock struct { StatusContainerFunc func(sandboxID, containerID string) (vc.ContainerStatus, error) StopContainerFunc func(sandboxID, containerID string) (vc.VCContainer, error) ProcessListContainerFunc func(sandboxID, containerID string, options vc.ProcessListOptions) (vc.ProcessList, error) + UpdateContainerFunc func(sandboxID, containerID string, resources specs.LinuxResources) error } diff --git a/virtcontainers/sandbox.go b/virtcontainers/sandbox.go index 89ae78551..823f4bbe4 100644 --- a/virtcontainers/sandbox.go +++ b/virtcontainers/sandbox.go @@ -14,6 +14,7 @@ import ( "sync" "syscall" + specs "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "github.com/kata-containers/runtime/virtcontainers/device/api" @@ -1089,6 +1090,17 @@ func (s *Sandbox) EnterContainer(containerID string, cmd Cmd) (VCContainer, *Pro return c, process, nil } +// UpdateContainer update a running container. +func (s *Sandbox) UpdateContainer(containerID string, resources specs.LinuxResources) error { + // Fetch the container. + c, err := s.findContainer(containerID) + if err != nil { + return err + } + + return c.update(resources) +} + // createContainers registers all containers to the proxy, create the // containers in the guest and starts one shim per container. func (s *Sandbox) createContainers() error {