diff --git a/.gitignore b/.gitignore index 577a58f1..fda90951 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,7 @@ /ocic conmon/conmon conmon/conmon.o +pause/pause +pause/pause.o /docs/ocid.8 vendor/src/github.com/kubernetes-incubator/cri-o diff --git a/Makefile b/Makefile index 9abff264..a09f0e1a 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,9 @@ ${OCID_LINK}: conmon: make -C $@ +pause: + make -C $@ + ocid: ${OCID_LINK} go build -o ocid ./cmd/server/ @@ -44,6 +47,7 @@ clean: rm -f ocic ocid rm -f ${OCID_LINK} rm -f conmon/conmon.o conmon/conmon + rm -f pause/pause.o pause/pause rm -f docs/*.1 docs/*.8 find . -name \*~ -delete find . -name \#\* -delete @@ -64,7 +68,7 @@ integration: ocidimage localintegration: binaries ./test/test_runner.sh ${TESTFLAGS} -binaries: ${OCID_LINK} ocid ocic conmon +binaries: ${OCID_LINK} ocid ocic conmon pause MANPAGES_MD = $(wildcard docs/*.md) @@ -82,12 +86,13 @@ install: binaries docs install -D -m 755 ocid ${INSTALLDIR}/ocid install -D -m 755 ocic ${INSTALLDIR}/ocic install -D -m 755 conmon/conmon $(PREFIX)/libexec/ocid/conmon + install -D -m 755 pause/pause $(PREFIX)/libexec/ocid/pause install -d $(PREFIX)/share/man/man8 install -m 644 $(basename $(MANPAGES_MD)) $(PREFIX)/share/man/man8 uninstall: rm -f ${INSTALLDIR}/{ocid,ocic} - rm -f $(PREFIX)/libexec/ocid/conmon + rm -f $(PREFIX)/libexec/ocid/{conmon,pause} for i in $(basename $(MANPAGES_MD)); do \ rm -f $(PREFIX)/share/man/man8/$$(basename $${i}); \ done @@ -118,13 +123,14 @@ install.tools: .install.gitvalidation .install.gometalinter .install.md2man .PHONY: \ binaries \ + clean \ conmon \ default \ docs \ - ocid \ - ocic \ - clean \ - lint \ help \ install \ + lint \ + ocic \ + ocid \ + pause \ uninstall diff --git a/cmd/server/main.go b/cmd/server/main.go index 4bc44a18..d1f28aa1 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,9 @@ func main() { containerDir := c.String("containerdir") sandboxDir := c.String("sandboxdir") - service, err := server.New(c.String("runtime"), c.String("root"), sandboxDir, containerDir, conmonPath) + conmonPath := c.String("conmon") + 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/conmon/Makefile b/conmon/Makefile index 1df60a69..c8c7c4a9 100644 --- a/conmon/Makefile +++ b/conmon/Makefile @@ -5,7 +5,7 @@ override LIBS += $(shell pkg-config --libs glib-2.0) override CFLAGS += -Wall -Wextra $(shell pkg-config --cflags glib-2.0) conmon: $(obj) - $(CC) -o $@ $^ $(LIBS) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) .PHONY: clean clean: diff --git a/pause/.gitignore b/pause/.gitignore new file mode 100644 index 00000000..b7735d56 --- /dev/null +++ b/pause/.gitignore @@ -0,0 +1,3 @@ +/.container-* +/.push-* +/bin diff --git a/pause/Makefile b/pause/Makefile new file mode 100644 index 00000000..a6f886a6 --- /dev/null +++ b/pause/Makefile @@ -0,0 +1,13 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) + +override LIBS += +override CFLAGS += -Os -Wall -Wextra -static + +pause: $(obj) + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + strip $@ + +.PHONY: clean +clean: + rm -f $(obj) pause diff --git a/pause/pause.c b/pause/pause.c new file mode 100644 index 00000000..ffbceb69 --- /dev/null +++ b/pause/pause.c @@ -0,0 +1,36 @@ +/* +Copyright 2016 The Kubernetes Authors. + +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. +*/ + +#include +#include +#include +#include + +static void sigdown(int signo) { + psignal(signo, "shutting down, got signal"); + exit(0); +} + +int main() { + if (signal(SIGINT, sigdown) == SIG_ERR) + return 1; + if (signal(SIGTERM, sigdown) == SIG_ERR) + return 2; + signal(SIGKILL, sigdown); + for (;;) pause(); + fprintf(stderr, "error: infinite loop terminated\n"); + return 42; +} 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 {