From 54d6ddb5afd63e91cf106e1f971168dee2d5c33a Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Fri, 7 Oct 2016 16:20:04 +0200 Subject: [PATCH 1/7] server: containers restore Signed-off-by: Antonio Murdaca --- server/container.go | 17 +++++++-- server/sandbox.go | 5 +++ server/server.go | 92 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 99 insertions(+), 15 deletions(-) diff --git a/server/container.go b/server/container.go index ba148218..d82cfeb7 100644 --- a/server/container.go +++ b/server/container.go @@ -1,6 +1,7 @@ package server import ( + "encoding/json" "errors" "fmt" "os" @@ -204,7 +205,6 @@ func (s *Server) createSandboxContainer(containerID string, containerName string specgen.AddAnnotation(k, v) } } - if containerConfig.GetPrivileged() { specgen.SetupPrivileged(true) } @@ -305,7 +305,18 @@ func (s *Server) createSandboxContainer(containerID string, containerName string } } - if err := specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil { + specgen.AddAnnotation("ocid/name", containerName) + specgen.AddAnnotation("ocid/sandbox_id", sb.id) + specgen.AddAnnotation("ocid/log_path", logPath) + specgen.AddAnnotation("ocid/tty", fmt.Sprintf("%v", containerConfig.GetTty())) + labelsJSON, err := json.Marshal(labels) + if err != nil { + return nil, err + } + + specgen.AddAnnotation("ocid/labels", string(labelsJSON)) + + if err = specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil { return nil, err } @@ -321,7 +332,7 @@ func (s *Server) createSandboxContainer(containerID string, containerName string // TODO: copy the rootfs into the bundle. // Currently, utils.CreateFakeRootfs is used to populate the rootfs. - if err := utils.CreateFakeRootfs(containerDir, image); err != nil { + if err = utils.CreateFakeRootfs(containerDir, image); err != nil { return nil, err } diff --git a/server/sandbox.go b/server/sandbox.go index c1a5a884..303dbbd9 100644 --- a/server/sandbox.go +++ b/server/sandbox.go @@ -173,6 +173,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest if err != nil { return nil, err } + g.SetProcessSelinuxLabel(processLabel) } containerID, containerName, err := s.generateContainerIDandName(name, "infra", 0) @@ -355,6 +356,10 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR s.removeContainer(c) } + if err := label.UnreserveLabel(sb.processLabel); err != nil { + return nil, err + } + // Remove the files related to the sandbox podSandboxDir := filepath.Join(s.sandboxDir, sb.id) if err := os.RemoveAll(podSandboxDir); err != nil { diff --git a/server/server.go b/server/server.go index 6cf9b6f6..692c6c67 100644 --- a/server/server.go +++ b/server/server.go @@ -38,6 +38,49 @@ type Server struct { ctrIDIndex *truncindex.TruncIndex } +func (s *Server) loadContainer(id string) error { + config, err := ioutil.ReadFile(filepath.Join(s.runtime.ContainerDir(), id, "config.json")) + if err != nil { + return err + } + var m rspec.Spec + if err = json.Unmarshal(config, &m); err != nil { + return err + } + labels := make(map[string]string) + if err = json.Unmarshal([]byte(m.Annotations["ocid/labels"]), &labels); err != nil { + return err + } + name := m.Annotations["ocid/name"] + name, err = s.reserveContainerName(id, name) + if err != nil { + return err + } + sb := s.getSandbox(m.Annotations["ocid/sandbox_id"]) + if sb == nil { + logrus.Warnf("could not get sandbox with id %s, skipping", m.Annotations["ocid/sandbox_id"]) + } + + var tty bool + if v := m.Annotations["ocid/tty"]; v == "true" { + tty = true + } + containerPath := filepath.Join(s.runtime.ContainerDir(), id) + + ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations["ocid/log_path"], labels, sb.id, tty) + if err != nil { + return err + } + s.addContainer(ctr) + if err = s.runtime.UpdateStatus(ctr); err != nil { + logrus.Warnf("error updating status for container %s: %v", ctr.ID(), err) + } + if err = s.ctrIDIndex.Add(id); err != nil { + return err + } + return nil +} + func (s *Server) loadSandbox(id string) error { config, err := ioutil.ReadFile(filepath.Join(s.sandboxDir, id, "config.json")) if err != nil { @@ -72,13 +115,24 @@ func (s *Server) loadSandbox(id string) error { }) sandboxPath := filepath.Join(s.sandboxDir, id) - scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], m.Annotations["ocid/container_name"], sandboxPath, sandboxPath, labels, id, false) + if err := label.ReserveLabel(processLabel); err != nil { + return err + } + + cname, err := s.reserveContainerName(m.Annotations["ocid/container_id"], m.Annotations["ocid/container_name"]) + if err != nil { + return err + } + scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], cname, sandboxPath, sandboxPath, labels, id, false) if err != nil { return err } s.addContainer(scontainer) if err = s.runtime.UpdateStatus(scontainer); err != nil { - logrus.Warnf("error updating status for container %s: %v", scontainer, err) + logrus.Warnf("error updating status for container %s: %v", scontainer.ID(), err) + } + if err = s.ctrIDIndex.Add(scontainer.ID()); err != nil { + return err } if err = s.podIDIndex.Add(id); err != nil { return err @@ -86,17 +140,32 @@ func (s *Server) loadSandbox(id string) error { return nil } -func (s *Server) restore() error { - dir, err := ioutil.ReadDir(s.sandboxDir) +func (s *Server) restore() { + sandboxDir, err := ioutil.ReadDir(s.sandboxDir) if err != nil { - return err + logrus.Warnf("could not read sandbox directory %s: %v", sandboxDir, err) } - for _, v := range dir { - if err := s.loadSandbox(v.Name()); err != nil { - return err + for _, v := range sandboxDir { + if !v.IsDir() { + continue + } + if err = s.loadSandbox(v.Name()); err != nil { + logrus.Warnf("could not restore sandbox %s: %v", v.Name(), err) + } + } + containerDir, err := ioutil.ReadDir(s.runtime.ContainerDir()) + if err != nil { + logrus.Warnf("could not read container directory %s: %v", s.runtime.ContainerDir(), err) + } + for _, v := range containerDir { + if !v.IsDir() { + continue + } + if err := s.loadContainer(v.Name()); err != nil { + logrus.Warnf("could not restore container %s: %v", v.Name(), err) + } } - return nil } func (s *Server) reservePodName(id, name string) (string, error) { @@ -182,9 +251,8 @@ func New(runtimePath, root, sandboxDir, containerDir, conmonPath, pausePath stri s.ctrIDIndex = truncindex.NewTruncIndex([]string{}) s.ctrNameIndex = registrar.NewRegistrar() - if err := s.restore(); err != nil { - logrus.Warnf("couldn't restore: %v", err) - } + s.restore() + logrus.Debugf("sandboxes: %v", s.state.sandboxes) logrus.Debugf("containers: %v", s.state.containers) return s, nil From 30757221b433f1c13cd79e7a7242f3dff4fd02f4 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:07:12 +0200 Subject: [PATCH 2/7] cmd/client/sandbox: add --quiet to pod list Signed-off-by: Antonio Murdaca --- cmd/client/sandbox.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/client/sandbox.go b/cmd/client/sandbox.go index ba31c32b..2b5dcd97 100644 --- a/cmd/client/sandbox.go +++ b/cmd/client/sandbox.go @@ -137,6 +137,12 @@ var podSandboxStatusCommand = cli.Command{ var listPodSandboxCommand = cli.Command{ Name: "list", Usage: "list pod sandboxes", + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "quiet", + Usage: "list only pod IDs", + }, + }, Action: func(context *cli.Context) error { // Set up a connection to the server. conn, err := getClientConnection(context) @@ -146,7 +152,7 @@ var listPodSandboxCommand = cli.Command{ defer conn.Close() client := pb.NewRuntimeServiceClient(conn) - err = ListPodSandboxes(client) + err = ListPodSandboxes(client, context.Bool("quiet")) if err != nil { return fmt.Errorf("listing pod sandboxes failed: %v", err) } @@ -258,12 +264,16 @@ func PodSandboxStatus(client pb.RuntimeServiceClient, ID string) error { // ListPodSandboxes sends a ListPodSandboxRequest to the server, and parses // the returned ListPodSandboxResponse. -func ListPodSandboxes(client pb.RuntimeServiceClient) error { +func ListPodSandboxes(client pb.RuntimeServiceClient, quiet bool) error { r, err := client.ListPodSandbox(context.Background(), &pb.ListPodSandboxRequest{}) if err != nil { return err } for _, pod := range r.Items { + if quiet { + fmt.Println(*pod.Id) + continue + } fmt.Printf("ID: %s\n", *pod.Id) if pod.Metadata != nil { if pod.Metadata.Name != nil { From e0364ec6330a926455b41b216b9859908357c4a2 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:24:16 +0200 Subject: [PATCH 3/7] add containers restore test Signed-off-by: Antonio Murdaca --- test/ctr.bats | 4 ++-- test/helpers.bash | 17 +++++++++-------- test/pod.bats | 4 ++-- test/restore.bats | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 test/restore.bats diff --git a/test/ctr.bats b/test/ctr.bats index 0ede579c..c39285ef 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -33,8 +33,8 @@ function teardown() { run ocic pod remove --id "$pod_id" echo "$output" [ "$status" -eq 0 ] - stop_ocid cleanup_pods + stop_ocid } @test "ctr lifecycle" { @@ -103,6 +103,6 @@ function teardown() { run ocic ctr list echo "$output" [ "$status" -eq 0 ] - stop_ocid cleanup_pods + stop_ocid } diff --git a/test/helpers.bash b/test/helpers.bash index ddcc81f5..13bced98 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -77,21 +77,22 @@ function start_ocid() { } function cleanup_pods() { - run ocic pod list + run ocic pod list --quiet if [ "$status" -eq 0 ]; then - printf '%s\n' "$output" | while IFS= read -r line - do - pod=$(echo "$line" | sed -e 's/ID: //g') - ocic pod stop --id "$pod" - ocic pod remove --id "$pod" - done + if [ "$output" != "" ]; then + printf '%s\n' "$output" | while IFS= read -r line + do + ocic pod stop --id "$line" + ocic pod remove --id "$line" + done + fi fi } # Stop ocid. function stop_ocid() { if [ "$OCID_PID" != "" ]; then - kill "$OCID_PID" >/dev/null 2>&1 + kill -9 "$OCID_PID" >/dev/null 2>&1 fi } diff --git a/test/pod.bats b/test/pod.bats index 9b8f918a..25f14b7a 100644 --- a/test/pod.bats +++ b/test/pod.bats @@ -35,8 +35,8 @@ function teardown() { run ocic pod remove --id "$id" echo "$output" [ "$status" -eq 0 ] - stop_ocid cleanup_pods + stop_ocid } @test "pod remove" { @@ -60,6 +60,6 @@ function teardown() { run ocic pod remove --id "$pod_id" echo "$output" [ "$status" -eq 0 ] - stop_ocid cleanup_pods + stop_ocid } diff --git a/test/restore.bats b/test/restore.bats new file mode 100644 index 00000000..88a6a19e --- /dev/null +++ b/test/restore.bats @@ -0,0 +1,41 @@ +#!/usr/bin/env bats + +load helpers + +function teardown() { + cleanup_test +} + +@test "ocid restore" { + # this test requires docker, thus it can't yet be run in a container + if [ "$TRAVIS" = "true" ]; then # instead of $TRAVIS, add a function is_containerized to skip here + skip "cannot yet run this test in a container, use sudo make localintegration" + fi + + start_ocid + run ocic pod create --config "$TESTDATA"/sandbox_config.json + echo "$output" + [ "$status" -eq 0 ] + pod_id="$output" + + run ocic ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + echo "$output" + [ "$status" -eq 0 ] + ctr_id="$output" + + stop_ocid + + start_ocid + run ocic pod list + echo "$output" + [ "$status" -eq 0 ] + #[[ "${output}" == *'${pod_id}'* ]] + + run ocic ctr list + echo "$output" + [ "$status" -eq 0 ] + #[[ "${output}" == *'${pod_id}'* ]] + + cleanup_pods + stop_ocid +} From a2fe83fe567ee283205b6e0da61af24a5b67d10f Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:30:29 +0200 Subject: [PATCH 4/7] cmd/client/container: add --quiet to ctr list Signed-off-by: Antonio Murdaca --- cmd/client/container.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/client/container.go b/cmd/client/container.go index 39590f81..9b728459 100644 --- a/cmd/client/container.go +++ b/cmd/client/container.go @@ -173,6 +173,12 @@ var containerStatusCommand = cli.Command{ var listContainersCommand = cli.Command{ Name: "list", Usage: "list containers", + Flags: []cli.Flag{ + cli.BoolFlag{ + Name: "quiet", + Usage: "list only container IDs", + }, + }, Action: func(context *cli.Context) error { // Set up a connection to the server. conn, err := getClientConnection(context) @@ -182,7 +188,7 @@ var listContainersCommand = cli.Command{ defer conn.Close() client := pb.NewRuntimeServiceClient(conn) - err = ListContainers(client) + err = ListContainers(client, context.Bool("quiet")) if err != nil { return fmt.Errorf("listing containers failed: %v", err) } @@ -298,12 +304,16 @@ func ContainerStatus(client pb.RuntimeServiceClient, ID string) error { // ListContainers sends a ListContainerRequest to the server, and parses // the returned ListContainerResponse. -func ListContainers(client pb.RuntimeServiceClient) error { +func ListContainers(client pb.RuntimeServiceClient, quiet bool) error { r, err := client.ListContainers(context.Background(), &pb.ListContainersRequest{}) if err != nil { return err } for _, c := range r.GetContainers() { + if quiet { + fmt.Println(*c.Id) + continue + } fmt.Printf("ID: %s\n", *c.Id) fmt.Printf("Pod: %s\n", *c.PodSandboxId) if c.State != nil { From 217d27862360ed590c8af22b092273466e5a3fb7 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:36:14 +0200 Subject: [PATCH 5/7] server/server: check pods/ctrs directories before restore Signed-off-by: Antonio Murdaca --- server/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server.go b/server/server.go index 692c6c67..19af7b4c 100644 --- a/server/server.go +++ b/server/server.go @@ -142,7 +142,7 @@ func (s *Server) loadSandbox(id string) error { func (s *Server) restore() { sandboxDir, err := ioutil.ReadDir(s.sandboxDir) - if err != nil { + if err != nil && !os.IsNotExist(err) { logrus.Warnf("could not read sandbox directory %s: %v", sandboxDir, err) } for _, v := range sandboxDir { @@ -154,7 +154,7 @@ func (s *Server) restore() { } } containerDir, err := ioutil.ReadDir(s.runtime.ContainerDir()) - if err != nil { + if err != nil && !os.IsNotExist(err) { logrus.Warnf("could not read container directory %s: %v", s.runtime.ContainerDir(), err) } for _, v := range containerDir { From cfa4a341a6950a4bace64aa0d3577c540375b696 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:55:25 +0200 Subject: [PATCH 6/7] server/container: fix bug when listing container IDs Signed-off-by: Antonio Murdaca --- server/container.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/container.go b/server/container.go index d82cfeb7..8adc46fa 100644 --- a/server/container.go +++ b/server/container.go @@ -422,9 +422,10 @@ func (s *Server) ListContainers(ctx context.Context, req *pb.ListContainersReque cState := s.runtime.ContainerStatus(ctr) created := cState.Created.Unix() rState := pb.ContainerState_UNKNOWN + cID := ctr.ID() c := &pb.Container{ - Id: &cState.ID, + Id: &cID, PodSandboxId: &podSandboxID, CreatedAt: int64Ptr(created), } From 9b72f29b72b723b1e1be27a4cffb208760667669 Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Sat, 8 Oct 2016 14:57:45 +0200 Subject: [PATCH 7/7] fixups for tests Signed-off-by: Antonio Murdaca --- test/ctr.bats | 2 ++ test/helpers.bash | 15 ++++++++++++++- test/pod.bats | 2 ++ test/restore.bats | 7 +++++-- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/test/ctr.bats b/test/ctr.bats index c39285ef..2244eda5 100644 --- a/test/ctr.bats +++ b/test/ctr.bats @@ -33,6 +33,7 @@ function teardown() { run ocic pod remove --id "$pod_id" echo "$output" [ "$status" -eq 0 ] + cleanup_ctrs cleanup_pods stop_ocid } @@ -103,6 +104,7 @@ function teardown() { run ocic ctr list echo "$output" [ "$status" -eq 0 ] + cleanup_ctrs cleanup_pods stop_ocid } diff --git a/test/helpers.bash b/test/helpers.bash index 13bced98..17bbe3af 100644 --- a/test/helpers.bash +++ b/test/helpers.bash @@ -76,6 +76,19 @@ function start_ocid() { wait_until_reachable } +function cleanup_ctrs() { + run ocic ctr list --quiet + if [ "$status" -eq 0 ]; then + if [ "$output" != "" ]; then + printf '%s\n' "$output" | while IFS= read -r line + do + ocic ctr stop --id "$line" + ocic ctr remove --id "$line" + done + fi + fi +} + function cleanup_pods() { run ocic pod list --quiet if [ "$status" -eq 0 ]; then @@ -92,7 +105,7 @@ function cleanup_pods() { # Stop ocid. function stop_ocid() { if [ "$OCID_PID" != "" ]; then - kill -9 "$OCID_PID" >/dev/null 2>&1 + kill "$OCID_PID" >/dev/null 2>&1 fi } diff --git a/test/pod.bats b/test/pod.bats index 25f14b7a..c6b719d4 100644 --- a/test/pod.bats +++ b/test/pod.bats @@ -35,6 +35,7 @@ function teardown() { run ocic pod remove --id "$id" echo "$output" [ "$status" -eq 0 ] + cleanup_ctrs cleanup_pods stop_ocid } @@ -60,6 +61,7 @@ function teardown() { run ocic pod remove --id "$pod_id" echo "$output" [ "$status" -eq 0 ] + cleanup_ctrs cleanup_pods stop_ocid } diff --git a/test/restore.bats b/test/restore.bats index 88a6a19e..b3b206a9 100644 --- a/test/restore.bats +++ b/test/restore.bats @@ -29,13 +29,16 @@ function teardown() { run ocic pod list echo "$output" [ "$status" -eq 0 ] - #[[ "${output}" == *'${pod_id}'* ]] + [[ "${output}" != "" ]] + [[ "${output}" =~ "${pod_id}" ]] run ocic ctr list echo "$output" [ "$status" -eq 0 ] - #[[ "${output}" == *'${pod_id}'* ]] + [[ "${output}" != "" ]] + [[ "${output}" =~ "${pod_id}" ]] + cleanup_ctrs cleanup_pods stop_ocid }