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

Kind provider #1232

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions cluster-provision/gocli/cmd/rm_kind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package cmd

import (
"github.com/spf13/cobra"
kind "kubevirt.io/kubevirtci/cluster-provision/gocli/providers/kind/kindbase"
)

func NewRemoveKindCommand() *cobra.Command {
rm := &cobra.Command{
Use: "rm-kind",
Short: "rm deletes all traces of a kind cluster",
RunE: rmKind,
Args: cobra.ExactArgs(1),
}
return rm
}

func rmKind(cmd *cobra.Command, args []string) error {
prefix := args[0]

kindProvider, err := kind.NewKindBaseProvider(&kind.KindConfig{Version: prefix})
if err != nil {
return err
}
if err = kindProvider.Delete(); err != nil {
return err
}

return nil
}
2 changes: 2 additions & 0 deletions cluster-provision/gocli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ func NewRootCommand() *cobra.Command {
NewSSHCommand(),
NewSCPCommand(),
NewProvisionManagerCommand(),
NewRunKindCommand(),
NewRemoveKindCommand(),
)

return root
Expand Down
110 changes: 110 additions & 0 deletions cluster-provision/gocli/cmd/run_kind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cmd

import (
"context"
"fmt"

"github.com/spf13/cobra"
kind "kubevirt.io/kubevirtci/cluster-provision/gocli/providers/kind/kindbase"
"kubevirt.io/kubevirtci/cluster-provision/gocli/providers/kind/sriov"
"kubevirt.io/kubevirtci/cluster-provision/gocli/providers/kind/vgpu"
)

var kindProvider kind.KindProvider

func NewRunKindCommand() *cobra.Command {
rk := &cobra.Command{
Use: "run-kind",
Short: "runs a kind provider",
RunE: runKind,
Args: cobra.ExactArgs(1),
}
rk.Flags().UintP("nodes", "n", 1, "number of cluster nodes to start")
rk.Flags().String("registry-port", "5000", "forwarded host port for registry container")
rk.Flags().String("registry-proxy", "", "registry proxy to use")
rk.Flags().String("ip-family", "", "ip family")
rk.Flags().Bool("enable-cpu-manager", false, "enable cpu manager")
rk.Flags().Bool("with-extra-mounts", false, "add extra mounts")
rk.Flags().Bool("with-vfio", false, "use vfio")
rk.Flags().Uint("pf-count-per-node", 1, "count of physical functions to pass to sriov node")
rk.Flags().Uint("vf-count-per-node", 6, "count of virtual functions to create on sriov node")

return rk
}

func runKind(cmd *cobra.Command, args []string) error {
nodes, err := cmd.Flags().GetUint("nodes")
if err != nil {
return err
}
port, err := cmd.Flags().GetString("registry-port")
if err != nil {
return err
}
rp, err := cmd.Flags().GetString("registry-proxy")
if err != nil {
return err
}
ipf, err := cmd.Flags().GetString("ip-family")
if err != nil {
return err
}
cpum, err := cmd.Flags().GetBool("enable-cpu-manager")
if err != nil {
return err
}
mounts, err := cmd.Flags().GetBool("with-extra-mounts")
if err != nil {
return err
}
vfio, err := cmd.Flags().GetBool("with-vfio")
if err != nil {
return err
}
pfs, err := cmd.Flags().GetUint("pf-count-per-node")
if err != nil {
return err
}
vfs, err := cmd.Flags().GetUint("vf-count-per-node")
if err != nil {
return err
}

kindVersion := args[0]
conf := &kind.KindConfig{
Nodes: int(nodes),
Version: kindVersion,
RegistryPort: port,
RegistryProxy: rp,
WithCPUManager: cpum,
IpFamily: ipf,
WithExtraMounts: mounts,
WithVfio: vfio,
}

switch kindVersion {
case "k8s-1.28":
kindProvider, err = kind.NewKindBaseProvider(conf)
if err != nil {
return err
}
case "sriov":
kindProvider, err = sriov.NewKindSriovProvider(conf, int(pfs), int(vfs))
if err != nil {
return err
}
case "vgpu":
kindProvider, err = vgpu.NewKindVGPU(conf)
default:
return fmt.Errorf("Invalid k8s version passed, please use one of k8s-1.28, sriov or vgpu")
}

b := context.Background()
ctx, cancel := context.WithCancel(b)

err = kindProvider.Start(ctx, cancel)
if err != nil {
return err
}
return nil
}
100 changes: 100 additions & 0 deletions cluster-provision/gocli/cri/docker/docker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package docker

import (
"os/exec"
"strconv"
"strings"

"github.com/sirupsen/logrus"
"kubevirt.io/kubevirtci/cluster-provision/gocli/cri"
)

type DockerClient struct{}

func NewDockerClient() *DockerClient {
return &DockerClient{}
}

func IsAvailable() bool {
cmd := exec.Command("docker", "-v")
out, err := cmd.Output()
if err != nil {
return false
}
return strings.HasPrefix(string(out), "Docker version")
}

func (dc *DockerClient) ImagePull(image string) error {
cmd := exec.Command("docker", "pull", image)
if err := cmd.Run(); err != nil {
return err
}

return nil
}

func (dc *DockerClient) Inspect(containerID, format string) ([]byte, error) {
cmd := exec.Command("docker", "inspect", containerID, "--format", format)
out, err := cmd.Output()
if err != nil {
return nil, err
}
return out, nil
}

func (dc *DockerClient) Start(containerID string) error {
cmd := exec.Command("docker",
"start",
containerID)

if _, err := cmd.CombinedOutput(); err != nil {
return err
}
return nil
}

func (dc *DockerClient) Create(image string, createOpts *cri.CreateOpts) (string, error) {
ports := ""
for containerPort, hostPort := range createOpts.Ports {
ports += "-p " + containerPort + ":" + hostPort
}

args := []string{
"--name=" + createOpts.Name,
"--privileged=" + strconv.FormatBool(createOpts.Privileged),
"--rm=" + strconv.FormatBool(createOpts.Remove),
"--restart=" + createOpts.RestartPolicy,
"--network=" + createOpts.Network,
}

for containerPort, hostPort := range createOpts.Ports {
args = append(args, "-p", containerPort+":"+hostPort)
}

if len(createOpts.Capabilities) > 0 {
args = append(args, "--cap-add="+strings.Join(createOpts.Capabilities, ","))
}

fullArgs := append([]string{"create"}, args...)
fullArgs = append(fullArgs, image)
fullArgs = append(fullArgs, createOpts.Command...)

cmd := exec.Command("docker",
fullArgs...,
)

containerID, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
logrus.Info("created registry container with id: ", string(containerID))
return strings.TrimSuffix(string(containerID), "\n"), nil
}

func (dc *DockerClient) Remove(containerID string) error {
cmd := exec.Command("docker", "rm", "-f", containerID)
if err := cmd.Run(); err != nil {
return err
}
return nil
}
21 changes: 21 additions & 0 deletions cluster-provision/gocli/cri/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cri

// maybe just create wrappers around bash after all
type ContainerClient interface {
ImagePull(image string) error
Create(image string, co *CreateOpts) (string, error)
Start(containerID string) error
Remove(containerID string) error
Inspect(containerID, format string) ([]byte, error)
}

type CreateOpts struct {
Privileged bool
Name string
Ports map[string]string
RestartPolicy string
Network string
Command []string
Remove bool
Capabilities []string
}
Loading