From bac579a9e5d238211da16a391adb9efcad8d4fc1 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sun, 2 Oct 2016 20:11:07 +1100 Subject: [PATCH] server: create pause rootfs manually without Docker This lessens the Docker requirement for creating sandboxes (with the requirement only existing for the actual image pulling that is done when adding a container to a pod). The interface was chosen to match the --conmon interface, so that the location of the pause binary can be chosen by a user. Signed-off-by: Aleksa Sarai --- cmd/server/main.go | 9 ++++++++- server/sandbox.go | 2 +- server/server.go | 4 +++- test/helpers.bash | 4 +++- utils/utils.go | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/cmd/server/main.go b/cmd/server/main.go index 4bc44a18..55d5c698 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -16,6 +16,7 @@ import ( const ( ocidRoot = "/var/lib/ocid" conmonPath = "/usr/libexec/ocid/conmon" + pausePath = "/usr/libexec/ocid/pause" ) func main() { @@ -30,6 +31,11 @@ func main() { Value: conmonPath, Usage: "path to the conmon executable", }, + cli.StringFlag{ + Name: "pause", + Value: pausePath, + Usage: "path to the pause executable", + }, cli.StringFlag{ Name: "root", Value: ocidRoot, @@ -110,7 +116,8 @@ func main() { containerDir := c.String("containerdir") sandboxDir := c.String("sandboxdir") - service, err := server.New(c.String("runtime"), c.String("root"), sandboxDir, containerDir, conmonPath) + pausePath := c.String("pause") + service, err := server.New(c.String("runtime"), c.String("root"), sandboxDir, containerDir, conmonPath, pausePath) if err != nil { logrus.Fatal(err) } diff --git a/server/sandbox.go b/server/sandbox.go index 0b84a246..5d37c1ca 100644 --- a/server/sandbox.go +++ b/server/sandbox.go @@ -194,7 +194,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest if _, err = os.Stat(podInfraRootfs); err != nil { if os.IsNotExist(err) { // TODO: Replace by rootfs creation API when it is ready - if err = utils.CreateFakeRootfs(podInfraRootfs, "docker://kubernetes/pause"); err != nil { + if err = utils.CreateInfraRootfs(podInfraRootfs, s.pausePath); err != nil { return nil, err } } else { diff --git a/server/server.go b/server/server.go index 9ed0814c..5c62f554 100644 --- a/server/server.go +++ b/server/server.go @@ -27,6 +27,7 @@ type Server struct { root string runtime *oci.Runtime sandboxDir string + pausePath string stateLock sync.Mutex state *serverState netPlugin ocicni.CNIPlugin @@ -107,7 +108,7 @@ func (s *Server) releasePodName(name string) { } // New creates a new Server with options provided -func New(runtimePath, root, sandboxDir, containerDir string, conmonPath string) (*Server, error) { +func New(runtimePath, root, sandboxDir, containerDir, conmonPath, pausePath string) (*Server, error) { // TODO: This will go away later when we have wrapper process or systemd acting as // subreaper. if err := utils.SetSubreaper(1); err != nil { @@ -139,6 +140,7 @@ func New(runtimePath, root, sandboxDir, containerDir string, conmonPath string) runtime: r, netPlugin: netPlugin, sandboxDir: sandboxDir, + pausePath: pausePath, state: &serverState{ sandboxes: sandboxes, containers: containers, diff --git a/test/helpers.bash b/test/helpers.bash index 01e4df8a..ddcc81f5 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -15,6 +15,8 @@ OCID_BINARY=${OCID_BINARY:-${OCID_ROOT}/cri-o/ocid} OCIC_BINARY=${OCIC_BINARY:-${OCID_ROOT}/cri-o/ocic} # Path of the conmon binary. CONMON_BINARY=${CONMON_BINARY:-${OCID_ROOT}/cri-o/conmon/conmon} +# Path of the pause binary. +PAUSE_BINARY=${PAUSE_BINARY:-${OCID_ROOT}/cri-o/pause/pause} # Path of the runc binary. RUNC_PATH=$(command -v runc || true) RUNC_BINARY=${RUNC_PATH:-/usr/local/sbin/runc} @@ -70,7 +72,7 @@ function wait_until_reachable() { # Start ocid. function start_ocid() { - "$OCID_BINARY" --conmon "$CONMON_BINARY" --debug --socket "$TESTDIR/ocid.sock" --runtime "$RUNC_BINARY" --root "$TESTDIR/ocid" --sandboxdir "$TESTDIR/sandboxes" --containerdir "$TESTDIR/ocid/containers" & OCID_PID=$! + "$OCID_BINARY" --conmon "$CONMON_BINARY" --pause "$PAUSE_BINARY" --debug --socket "$TESTDIR/ocid.sock" --runtime "$RUNC_BINARY" --root "$TESTDIR/ocid" --sandboxdir "$TESTDIR/sandboxes" --containerdir "$TESTDIR/ocid/containers" & OCID_PID=$! wait_until_reachable } diff --git a/utils/utils.go b/utils/utils.go index ca5d7f17..a37fd817 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -78,6 +78,38 @@ func CreateFakeRootfs(dir string, image string) error { return dockerExport(image[9:], rootfs) } +// CreateInfraRootfs creates a rootfs similar to CreateFakeRootfs, but only +// copies a single binary from the host into the rootfs. This is all done +// without Docker, and is only used currently for the pause container which is +// required for all sandboxes. +func CreateInfraRootfs(dir string, src string) error { + rootfs := filepath.Join(dir, "rootfs") + if err := os.MkdirAll(rootfs, 0755); err != nil { + return err + } + + dest := filepath.Join(rootfs, filepath.Base(src)) + logrus.Debugf("copying infra rootfs binary: %v -> %v", src, dest) + + in, err := os.OpenFile(src, os.O_RDONLY, 0755) + if err != nil { + return err + } + defer in.Close() + + out, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0755) + if err != nil { + return err + } + defer out.Close() + + if _, err := io.Copy(out, in); err != nil { + return err + } + + return out.Sync() +} + func dockerExport(image string, rootfs string) error { out, err := ExecCmd("docker", "create", image) if err != nil {