summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFabricio Voznika <fvoznika@google.com>2018-06-20 13:00:21 -0700
committerShentubot <shentubot@google.com>2018-06-20 13:01:16 -0700
commitaf6f9f56f80027a89ee517b79502ca6183094a39 (patch)
tree765f81e0d3789857de53ef9b30e92de174e8393f
parent4e9f0e91d724b547e1ecaeeb210017f4c0b3fd0d (diff)
Add tool to configure runtime settings in docker
This will be used with the upcoming e2e image tests. PiperOrigin-RevId: 201400832 Change-Id: I49509314e16ea54655ea8060dbf511a04a7a8f79
-rw-r--r--runsc/tools/dockercfg/BUILD12
-rw-r--r--runsc/tools/dockercfg/dockercfg.go189
2 files changed, 201 insertions, 0 deletions
diff --git a/runsc/tools/dockercfg/BUILD b/runsc/tools/dockercfg/BUILD
new file mode 100644
index 000000000..5abb0c90a
--- /dev/null
+++ b/runsc/tools/dockercfg/BUILD
@@ -0,0 +1,12 @@
+package(licenses = ["notice"]) # Apache 2.0
+
+load("@io_bazel_rules_go//go:def.bzl", "go_binary")
+
+go_binary(
+ name = "dockercfg",
+ srcs = ["dockercfg.go"],
+ visibility = [
+ "//runsc/test:__subpackages__",
+ ],
+ deps = ["@com_github_google_subcommands//:go_default_library"],
+)
diff --git a/runsc/tools/dockercfg/dockercfg.go b/runsc/tools/dockercfg/dockercfg.go
new file mode 100644
index 000000000..0bd6cad93
--- /dev/null
+++ b/runsc/tools/dockercfg/dockercfg.go
@@ -0,0 +1,189 @@
+// Copyright 2018 Google 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
+//
+// http://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.
+
+// Helper tool to configure Docker daemon.
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+
+ "context"
+ "flag"
+ "github.com/google/subcommands"
+)
+
+var (
+ configFile = flag.String("config_file", "/etc/docker/daemon.json", "path to Docker daemon config file")
+)
+
+func main() {
+ subcommands.Register(subcommands.HelpCommand(), "")
+ subcommands.Register(subcommands.FlagsCommand(), "")
+ subcommands.Register(&runtimeAdd{}, "")
+ subcommands.Register(&runtimeRemove{}, "")
+
+ // All subcommands must be registered before flag parsing.
+ flag.Parse()
+
+ exitCode := subcommands.Execute(context.Background())
+ os.Exit(int(exitCode))
+}
+
+type runtime struct {
+ Path string `json:"path,omitempty"`
+ RuntimeArgs []string `json:"runtimeArgs,omitempty"`
+}
+
+// runtimeAdd implements subcommands.Command.
+type runtimeAdd struct {
+}
+
+// Name implements subcommands.Command.Name.
+func (*runtimeAdd) Name() string {
+ return "runtime-add"
+}
+
+// Synopsis implements subcommands.Command.Synopsis.
+func (*runtimeAdd) Synopsis() string {
+ return "adds a runtime to docker daemon configuration"
+}
+
+// Usage implements subcommands.Command.Usage.
+func (*runtimeAdd) Usage() string {
+ return `runtime-add [flags] <name> <path> [args...] -- if provided, args are passed as arguments to the runtime
+`
+}
+
+// SetFlags implements subcommands.Command.SetFlags.
+func (*runtimeAdd) SetFlags(*flag.FlagSet) {
+}
+
+// Execute implements subcommands.Command.Execute.
+func (r *runtimeAdd) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
+ if f.NArg() < 2 {
+ f.Usage()
+ return subcommands.ExitUsageError
+ }
+ name := f.Arg(0)
+ path := f.Arg(1)
+ runtimeArgs := f.Args()[2:]
+
+ fmt.Printf("Adding runtime %q to file %q\n", name, *configFile)
+ c, err := readConfig(*configFile)
+ if err != nil {
+ log.Fatalf("Error reading config file %q: %v", *configFile, err)
+ }
+
+ var rts map[string]interface{}
+ if i, ok := c["runtimes"]; ok {
+ rts = i.(map[string]interface{})
+ } else {
+ rts = make(map[string]interface{})
+ c["runtimes"] = rts
+ }
+ rts[name] = runtime{Path: path, RuntimeArgs: runtimeArgs}
+
+ if err := writeConfig(c, *configFile); err != nil {
+ log.Fatalf("Error writing config file %q: %v", *configFile, err)
+ }
+ return subcommands.ExitSuccess
+}
+
+// runtimeRemove implements subcommands.Command.
+type runtimeRemove struct {
+}
+
+// Name implements subcommands.Command.Name.
+func (*runtimeRemove) Name() string {
+ return "runtime-rm"
+}
+
+// Synopsis implements subcommands.Command.Synopsis.
+func (*runtimeRemove) Synopsis() string {
+ return "removes a runtime from docker daemon configuration"
+}
+
+// Usage implements subcommands.Command.Usage.
+func (*runtimeRemove) Usage() string {
+ return `runtime-rm [flags] <name>
+`
+}
+
+// SetFlags implements subcommands.Command.SetFlags.
+func (*runtimeRemove) SetFlags(*flag.FlagSet) {
+}
+
+// Execute implements subcommands.Command.Execute.
+func (r *runtimeRemove) Execute(_ context.Context, f *flag.FlagSet, args ...interface{}) subcommands.ExitStatus {
+ if f.NArg() != 1 {
+ f.Usage()
+ return subcommands.ExitUsageError
+ }
+ name := f.Arg(0)
+
+ fmt.Printf("Removing runtime %q from file %q\n", name, *configFile)
+ c, err := readConfig(*configFile)
+ if err != nil {
+ log.Fatalf("Error reading config file %q: %v", *configFile, err)
+ }
+
+ var rts map[string]interface{}
+ if i, ok := c["runtimes"]; ok {
+ rts = i.(map[string]interface{})
+ } else {
+ log.Fatalf("runtime %q not found", name)
+ }
+ if _, ok := rts[name]; !ok {
+ log.Fatalf("runtime %q not found", name)
+ }
+ delete(rts, name)
+
+ if err := writeConfig(c, *configFile); err != nil {
+ log.Fatalf("Error writing config file %q: %v", *configFile, err)
+ }
+ return subcommands.ExitSuccess
+}
+
+func readConfig(path string) (map[string]interface{}, error) {
+ configBytes, err := ioutil.ReadFile(path)
+ if err != nil && !os.IsNotExist(err) {
+ return nil, err
+ }
+ c := make(map[string]interface{})
+ if len(configBytes) > 0 {
+ if err := json.Unmarshal(configBytes, &c); err != nil {
+ return nil, err
+ }
+ }
+ return c, nil
+}
+
+func writeConfig(c map[string]interface{}, path string) error {
+ b, err := json.MarshalIndent(c, "", " ")
+ if err != nil {
+ return err
+ }
+
+ if err := os.Rename(path, path+"~"); err != nil && !os.IsNotExist(err) {
+ return fmt.Errorf("error renaming config file %q: %v", path, err)
+ }
+ if err := ioutil.WriteFile(path, b, 0644); err != nil {
+ return fmt.Errorf("error writing config file %q: %v", path, err)
+ }
+ return nil
+}