Merge pull request #179 from Crazykev/add-metadata

Return pod metadata in container list and status APIs
This commit is contained in:
Mrunal Patel 2016-11-04 10:00:58 -06:00 committed by GitHub
commit 5d62a9fbb9
11 changed files with 201 additions and 23 deletions

View file

@ -364,6 +364,14 @@ func ContainerStatus(client pb.RuntimeServiceClient, ID string) error {
return err return err
} }
fmt.Printf("ID: %s\n", *r.Status.Id) fmt.Printf("ID: %s\n", *r.Status.Id)
if r.Status.Metadata != nil {
if r.Status.Metadata.Name != nil {
fmt.Printf("Name: %s\n", *r.Status.Metadata.Name)
}
if r.Status.Metadata.Attempt != nil {
fmt.Printf("Attempt: %v\n", *r.Status.Metadata.Attempt)
}
}
if r.Status.State != nil { if r.Status.State != nil {
fmt.Printf("Status: %s\n", r.Status.State) fmt.Printf("Status: %s\n", r.Status.State)
} }
@ -428,6 +436,14 @@ func ListContainers(client pb.RuntimeServiceClient, opts listOptions) error {
} }
fmt.Printf("ID: %s\n", *c.Id) fmt.Printf("ID: %s\n", *c.Id)
fmt.Printf("Pod: %s\n", *c.PodSandboxId) fmt.Printf("Pod: %s\n", *c.PodSandboxId)
if c.Metadata != nil {
if c.Metadata.Name != nil {
fmt.Printf("Name: %s\n", *c.Metadata.Name)
}
if c.Metadata.Attempt != nil {
fmt.Printf("Attempt: %v\n", *c.Metadata.Attempt)
}
}
if c.State != nil { if c.State != nil {
fmt.Printf("Status: %s\n", *c.State) fmt.Printf("Status: %s\n", *c.State)
} }
@ -437,16 +453,17 @@ func ListContainers(client pb.RuntimeServiceClient, opts listOptions) error {
} }
if c.Labels != nil { if c.Labels != nil {
fmt.Println("Labels:") fmt.Println("Labels:")
for k, v := range c.Labels { for _, k := range getSortedKeys(c.Labels) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, c.Labels[k])
} }
} }
if c.Annotations != nil { if c.Annotations != nil {
fmt.Println("Annotations:") fmt.Println("Annotations:")
for k, v := range c.Annotations { for _, k := range getSortedKeys(c.Annotations) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, c.Annotations[k])
} }
} }
fmt.Println()
} }
return nil return nil
} }

View file

@ -3,6 +3,7 @@ package main
import ( import (
"fmt" "fmt"
"log" "log"
"sort"
"strings" "strings"
"time" "time"
@ -302,14 +303,14 @@ func PodSandboxStatus(client pb.RuntimeServiceClient, ID string) error {
} }
if r.Status.Labels != nil { if r.Status.Labels != nil {
fmt.Println("Labels:") fmt.Println("Labels:")
for k, v := range r.Status.Labels { for _, k := range getSortedKeys(r.Status.Labels) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, r.Status.Labels[k])
} }
} }
if r.Status.Annotations != nil { if r.Status.Annotations != nil {
fmt.Println("Annotations:") fmt.Println("Annotations:")
for k, v := range r.Status.Annotations { for _, k := range getSortedKeys(r.Status.Annotations) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, r.Status.Annotations[k])
} }
} }
return nil return nil
@ -369,16 +370,27 @@ func ListPodSandboxes(client pb.RuntimeServiceClient, opts listOptions) error {
fmt.Printf("Created: %v\n", ctm) fmt.Printf("Created: %v\n", ctm)
if pod.Labels != nil { if pod.Labels != nil {
fmt.Println("Labels:") fmt.Println("Labels:")
for k, v := range pod.Labels { for _, k := range getSortedKeys(pod.Labels) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, pod.Labels[k])
} }
} }
if pod.Annotations != nil { if pod.Annotations != nil {
fmt.Println("Annotations:") fmt.Println("Annotations:")
for k, v := range pod.Annotations { for _, k := range getSortedKeys(pod.Annotations) {
fmt.Printf("\t%s -> %s\n", k, v) fmt.Printf("\t%s -> %s\n", k, pod.Annotations[k])
} }
} }
fmt.Println()
} }
return nil return nil
} }
func getSortedKeys(m map[string]string) []string {
var keys []string
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}

View file

@ -19,6 +19,7 @@ import (
"github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-spec/specs-go"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
) )
const ( const (
@ -228,6 +229,7 @@ type Container struct {
sandbox string sandbox string
terminal bool terminal bool
state *ContainerState state *ContainerState
metadata *pb.ContainerMetadata
stateLock sync.Mutex stateLock sync.Mutex
} }
@ -241,7 +243,7 @@ type ContainerState struct {
} }
// NewContainer creates a container object. // NewContainer creates a container object.
func NewContainer(id string, name string, bundlePath string, logPath string, labels map[string]string, sandbox string, terminal bool) (*Container, error) { func NewContainer(id string, name string, bundlePath string, logPath string, labels map[string]string, metadata *pb.ContainerMetadata, sandbox string, terminal bool) (*Container, error) {
c := &Container{ c := &Container{
id: id, id: id,
name: name, name: name,
@ -250,6 +252,7 @@ func NewContainer(id string, name string, bundlePath string, logPath string, lab
labels: labels, labels: labels,
sandbox: sandbox, sandbox: sandbox,
terminal: terminal, terminal: terminal,
metadata: metadata,
} }
return c, nil return c, nil
} }
@ -292,6 +295,11 @@ func (c *Container) NetNsPath() (string, error) {
return fmt.Sprintf("/proc/%d/ns/net", c.state.Pid), nil return fmt.Sprintf("/proc/%d/ns/net", c.state.Pid), nil
} }
// Metadata returns the metadata of the container.
func (c *Container) Metadata() *pb.ContainerMetadata {
return c.metadata
}
// newPipe creates a unix socket pair for communication // newPipe creates a unix socket pair for communication
func newPipe() (parent *os.File, child *os.File, err error) { func newPipe() (parent *os.File, child *os.File, err error) {
fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0) fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)

View file

@ -205,6 +205,8 @@ func (s *Server) createSandboxContainer(containerID string, containerName string
labels := containerConfig.GetLabels() labels := containerConfig.GetLabels()
metadata := containerConfig.GetMetadata()
annotations := containerConfig.GetAnnotations() annotations := containerConfig.GetAnnotations()
if annotations != nil { if annotations != nil {
for k, v := range annotations { for k, v := range annotations {
@ -312,11 +314,17 @@ func (s *Server) createSandboxContainer(containerID string, containerName string
specgen.AddAnnotation("ocid/sandbox_id", sb.id) specgen.AddAnnotation("ocid/sandbox_id", sb.id)
specgen.AddAnnotation("ocid/log_path", logPath) specgen.AddAnnotation("ocid/log_path", logPath)
specgen.AddAnnotation("ocid/tty", fmt.Sprintf("%v", containerConfig.GetTty())) specgen.AddAnnotation("ocid/tty", fmt.Sprintf("%v", containerConfig.GetTty()))
metadataJSON, err := json.Marshal(metadata)
if err != nil {
return nil, err
}
specgen.AddAnnotation("ocid/metadata", string(metadataJSON))
labelsJSON, err := json.Marshal(labels) labelsJSON, err := json.Marshal(labels)
if err != nil { if err != nil {
return nil, err return nil, err
} }
specgen.AddAnnotation("ocid/labels", string(labelsJSON)) specgen.AddAnnotation("ocid/labels", string(labelsJSON))
if err = specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil { if err = specgen.SaveToFile(filepath.Join(containerDir, "config.json")); err != nil {
@ -339,7 +347,7 @@ func (s *Server) createSandboxContainer(containerID string, containerName string
return nil, err return nil, err
} }
container, err := oci.NewContainer(containerID, containerName, containerDir, logPath, labels, sb.id, containerConfig.GetTty()) container, err := oci.NewContainer(containerID, containerName, containerDir, logPath, labels, metadata, sb.id, containerConfig.GetTty())
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -491,6 +499,7 @@ func (s *Server) ListContainers(ctx context.Context, req *pb.ListContainersReque
PodSandboxId: &podSandboxID, PodSandboxId: &podSandboxID,
CreatedAt: int64Ptr(created), CreatedAt: int64Ptr(created),
Labels: ctr.Labels(), Labels: ctr.Labels(),
Metadata: ctr.Metadata(),
} }
switch cState.Status { switch cState.Status {
@ -531,7 +540,8 @@ func (s *Server) ContainerStatus(ctx context.Context, req *pb.ContainerStatusReq
containerID := c.ID() containerID := c.ID()
resp := &pb.ContainerStatusResponse{ resp := &pb.ContainerStatusResponse{
Status: &pb.ContainerStatus{ Status: &pb.ContainerStatus{
Id: &containerID, Id: &containerID,
Metadata: c.Metadata(),
}, },
} }

View file

@ -176,6 +176,13 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
g.AddBindMount(resolvPath, "/etc/resolv.conf", "ro") g.AddBindMount(resolvPath, "/etc/resolv.conf", "ro")
// add metadata
metadata := req.GetConfig().GetMetadata()
metadataJSON, err := json.Marshal(metadata)
if err != nil {
return nil, err
}
// add labels // add labels
labels := req.GetConfig().GetLabels() labels := req.GetConfig().GetLabels()
labelsJSON, err := json.Marshal(labels) labelsJSON, err := json.Marshal(labels)
@ -222,6 +229,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
} }
}() }()
g.AddAnnotation("ocid/metadata", string(metadataJSON))
g.AddAnnotation("ocid/labels", string(labelsJSON)) g.AddAnnotation("ocid/labels", string(labelsJSON))
g.AddAnnotation("ocid/annotations", string(annotationsJSON)) g.AddAnnotation("ocid/annotations", string(annotationsJSON))
g.AddAnnotation("ocid/log_path", logDir) g.AddAnnotation("ocid/log_path", logDir)
@ -238,7 +246,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
containers: oci.NewMemoryStore(), containers: oci.NewMemoryStore(),
processLabel: processLabel, processLabel: processLabel,
mountLabel: mountLabel, mountLabel: mountLabel,
metadata: req.GetConfig().GetMetadata(), metadata: metadata,
} }
s.addSandbox(sb) s.addSandbox(sb)
@ -291,7 +299,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
} }
} }
container, err := oci.NewContainer(containerID, containerName, podSandboxDir, podSandboxDir, labels, id, false) container, err := oci.NewContainer(containerID, containerName, podSandboxDir, podSandboxDir, labels, nil, id, false)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -16,6 +16,7 @@ import (
"github.com/opencontainers/runc/libcontainer/label" "github.com/opencontainers/runc/libcontainer/label"
rspec "github.com/opencontainers/runtime-spec/specs-go" rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/rajatchopra/ocicni" "github.com/rajatchopra/ocicni"
pb "k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
) )
const ( const (
@ -53,6 +54,10 @@ func (s *Server) loadContainer(id string) error {
if err != nil { if err != nil {
return err return err
} }
var metadata pb.ContainerMetadata
if err = json.Unmarshal([]byte(m.Annotations["ocid/metadata"]), &metadata); err != nil {
return err
}
sb := s.getSandbox(m.Annotations["ocid/sandbox_id"]) sb := s.getSandbox(m.Annotations["ocid/sandbox_id"])
if sb == nil { if sb == nil {
logrus.Warnf("could not get sandbox with id %s, skipping", m.Annotations["ocid/sandbox_id"]) logrus.Warnf("could not get sandbox with id %s, skipping", m.Annotations["ocid/sandbox_id"])
@ -65,7 +70,7 @@ func (s *Server) loadContainer(id string) error {
} }
containerPath := filepath.Join(s.runtime.ContainerDir(), id) containerPath := filepath.Join(s.runtime.ContainerDir(), id)
ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations["ocid/log_path"], labels, sb.id, tty) ctr, err := oci.NewContainer(id, name, containerPath, m.Annotations["ocid/log_path"], labels, &metadata, sb.id, tty)
if err != nil { if err != nil {
return err return err
} }
@ -97,6 +102,10 @@ func (s *Server) loadSandbox(id string) error {
if err != nil { if err != nil {
return err return err
} }
var metadata pb.PodSandboxMetadata
if err = json.Unmarshal([]byte(m.Annotations["ocid/metadata"]), &metadata); err != nil {
return err
}
processLabel, mountLabel, err := label.InitLabels(label.DupSecOpt(m.Process.SelinuxLabel)) processLabel, mountLabel, err := label.InitLabels(label.DupSecOpt(m.Process.SelinuxLabel))
if err != nil { if err != nil {
@ -117,6 +126,7 @@ func (s *Server) loadSandbox(id string) error {
processLabel: processLabel, processLabel: processLabel,
mountLabel: mountLabel, mountLabel: mountLabel,
annotations: annotations, annotations: annotations,
metadata: &metadata,
} }
s.addSandbox(sb) s.addSandbox(sb)
@ -130,7 +140,7 @@ func (s *Server) loadSandbox(id string) error {
if err != nil { if err != nil {
return err return err
} }
scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], cname, sandboxPath, sandboxPath, labels, id, false) scontainer, err := oci.NewContainer(m.Annotations["ocid/container_id"], cname, sandboxPath, sandboxPath, labels, nil, id, false)
if err != nil { if err != nil {
return err return err
} }

View file

@ -292,3 +292,38 @@ function teardown() {
cleanup_pods cleanup_pods
stop_ocid stop_ocid
} }
@test "ctr metadata in list & status" {
# 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"
run ocic ctr list --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
# TODO: expected value should not hard coded here
[[ "$output" =~ "Name: container1" ]]
[[ "$output" =~ "Attempt: 1" ]]
run ocic ctr status --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
# TODO: expected value should not hard coded here
[[ "$output" =~ "Name: container1" ]]
[[ "$output" =~ "Attempt: 1" ]]
cleanup_ctrs
cleanup_pods
stop_ocid
}

View file

@ -152,4 +152,38 @@ function teardown() {
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
cleanup_pods cleanup_pods
stop_ocid stop_ocid
} }
@test "pod metadata in list & status" {
# 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 pod list --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
# TODO: expected value should not hard coded here
[[ "$output" =~ "Name: podsandbox1" ]]
[[ "$output" =~ "UID: redhat-test-ocid" ]]
[[ "$output" =~ "Namespace: redhat.test.ocid" ]]
[[ "$output" =~ "Attempt: 1" ]]
run ocic pod status --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
# TODO: expected value should not hard coded here
[[ "$output" =~ "Name: podsandbox1" ]]
[[ "$output" =~ "UID: redhat-test-ocid" ]]
[[ "$output" =~ "Namespace: redhat.test.ocid" ]]
[[ "$output" =~ "Attempt: 1" ]]
cleanup_pods
stop_ocid
}

View file

@ -18,11 +18,31 @@ function teardown() {
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
pod_id="$output" pod_id="$output"
run ocic pod list --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
pod_list_info="$output"
run ocic pod status --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
pod_status_info="$output"
run ocic ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" run ocic ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id"
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
ctr_id="$output" ctr_id="$output"
run ocic ctr list --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
ctr_list_info="$output"
run ocic ctr status --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
ctr_status_info="$output"
stop_ocid stop_ocid
start_ocid start_ocid
@ -32,12 +52,32 @@ function teardown() {
[[ "${output}" != "" ]] [[ "${output}" != "" ]]
[[ "${output}" =~ "${pod_id}" ]] [[ "${output}" =~ "${pod_id}" ]]
run ocic pod list --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
[[ "${output}" == "${pod_list_info}" ]]
run ocic pod status --id "$pod_id"
echo "$output"
[ "$status" -eq 0 ]
[[ "${output}" == "${pod_status_info}" ]]
run ocic ctr list run ocic ctr list
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
[[ "${output}" != "" ]] [[ "${output}" != "" ]]
[[ "${output}" =~ "${pod_id}" ]] [[ "${output}" =~ "${pod_id}" ]]
run ocic ctr list --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
[[ "${output}" == "${ctr_list_info}" ]]
run ocic ctr status --id "$ctr_id"
echo "$output"
[ "$status" -eq 0 ]
[[ "${output}" == "${ctr_status_info}" ]]
cleanup_ctrs cleanup_ctrs
cleanup_pods cleanup_pods
stop_ocid stop_ocid

View file

@ -1,6 +1,7 @@
{ {
"metadata": { "metadata": {
"name": "container1" "name": "container1",
"attempt": 1
}, },
"image": { "image": {
"image": "docker://redis:latest" "image": "docker://redis:latest"

View file

@ -1,6 +1,9 @@
{ {
"metadata": { "metadata": {
"name": "podsandbox1" "name": "podsandbox1",
"uid": "redhat-test-ocid",
"namespace": "redhat.test.ocid",
"attempt": 1
}, },
"hostname": "ocic_host", "hostname": "ocic_host",
"log_directory": ".", "log_directory": ".",