Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release/1.5] Setup pod network after creating the sandbox container #7464

Merged
merged 3 commits into from Nov 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
103 changes: 99 additions & 4 deletions integration/main_test.go
Expand Up @@ -20,18 +20,23 @@
package integration

import (
"bytes"
"context"
"encoding/json"
"flag"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"syscall"
"testing"
"time"

"github.com/containerd/containerd"
"github.com/containerd/containerd/containers"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -164,6 +169,15 @@ func WithPodHostname(hostname string) PodSandboxOpts {
}
}

// Add pod labels.
func WithPodLabels(kvs map[string]string) PodSandboxOpts {
return func(p *runtime.PodSandboxConfig) {
for k, v := range kvs {
p.Labels[k] = v
}
}
}

// PodSandboxConfig generates a pod sandbox config for test.
func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandboxConfig {
config := &runtime.PodSandboxConfig{
Expand All @@ -176,6 +190,7 @@ func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandb
},
Linux: &runtime.LinuxPodSandboxConfig{},
Annotations: make(map[string]string),
Labels: make(map[string]string),
}
for _, opt := range opts {
opt(config)
Expand Down Expand Up @@ -318,8 +333,10 @@ func Randomize(str string) string {
}

// KillProcess kills the process by name. pkill is used.
func KillProcess(name string) error {
output, err := exec.Command("pkill", "-x", fmt.Sprintf("^%s$", name)).CombinedOutput()
func KillProcess(name string, signal syscall.Signal) error {
command := []string{"pkill", "-" + strconv.Itoa(int(signal)), "-x", fmt.Sprintf("^%s$", name)}

output, err := exec.Command(command[0], command[1:]...).CombinedOutput()
if err != nil {
return errors.Errorf("failed to kill %q - error: %v, output: %q", name, err, output)
}
Expand Down Expand Up @@ -348,6 +365,80 @@ func PidOf(name string) (int, error) {
return strconv.Atoi(output)
}

// PidsOf returns pid(s) of a process by name
func PidsOf(name string) ([]int, error) {
if len(name) == 0 {
return []int{}, fmt.Errorf("name is required")
}

procDirFD, err := os.Open("/proc")
if err != nil {
return nil, fmt.Errorf("failed to open /proc: %w", err)
}
defer procDirFD.Close()

res := []int{}
for {
fileInfos, err := procDirFD.Readdir(100)
if err != nil {
if err == io.EOF {
break
}
return nil, fmt.Errorf("failed to readdir: %w", err)
}

for _, fileInfo := range fileInfos {
if !fileInfo.IsDir() {
continue
}

pid, err := strconv.Atoi(fileInfo.Name())
if err != nil {
continue
}

exePath, err := os.Readlink(filepath.Join("/proc", fileInfo.Name(), "exe"))
if err != nil {
continue
}

if strings.HasSuffix(exePath, name) {
res = append(res, pid)
}
}
}
return res, nil
}

// PidEnvs returns the environ of pid in key-value pairs.
func PidEnvs(pid int) (map[string]string, error) {
envPath := filepath.Join("/proc", strconv.Itoa(pid), "environ")

b, err := os.ReadFile(envPath)
if err != nil {
return nil, fmt.Errorf("failed to read %s: %w", envPath, err)
}

values := bytes.Split(b, []byte{0})
if len(values) == 0 {
return nil, nil
}

res := make(map[string]string)
for _, value := range values {
value := strings.TrimSpace(string(value))
if len(value) == 0 {
continue
}

parts := strings.SplitN(value, "=", 2)
if len(parts) == 2 {
res[parts[0]] = parts[1]
}
}
return res, nil
}

// RawRuntimeClient returns a raw grpc runtime service client.
func RawRuntimeClient() (runtime.RuntimeServiceClient, error) {
addr, dialer, err := dialer.GetAddressAndDialer(*criEndpoint)
Expand Down Expand Up @@ -401,8 +492,8 @@ func SandboxInfo(id string) (*runtime.PodSandboxStatus, *server.SandboxInfo, err
return status, &info, nil
}

func RestartContainerd(t *testing.T) {
require.NoError(t, KillProcess(*containerdBin))
func RestartContainerd(t *testing.T, signal syscall.Signal) {
require.NoError(t, KillProcess(*containerdBin, signal))

// Use assert so that the 3rd wait always runs, this makes sure
// containerd is running before this function returns.
Expand All @@ -418,3 +509,7 @@ func RestartContainerd(t *testing.T) {
return ConnectDaemons() == nil, nil
}, time.Second, 30*time.Second), "wait for containerd to be restarted")
}

func GetContainer(id string) (containers.Container, error) {
return containerdClient.ContainerService().Get(context.Background(), id)
}
3 changes: 2 additions & 1 deletion integration/restart_test.go
Expand Up @@ -21,6 +21,7 @@ package integration

import (
"sort"
"syscall"
"testing"

"github.com/containerd/containerd"
Expand Down Expand Up @@ -146,7 +147,7 @@ func TestContainerdRestart(t *testing.T) {
assert.NoError(t, err)

t.Logf("Restart containerd")
RestartContainerd(t)
RestartContainerd(t, syscall.SIGTERM)

t.Logf("Check sandbox and container state after restart")
loadedSandboxes, err := runtimeService.ListPodSandbox(&runtime.PodSandboxFilter{})
Expand Down