Skip to content

Commit

Permalink
add join cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
ryota-sakamoto committed Jun 16, 2024
1 parent 89e8631 commit b199f50
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 63 deletions.
16 changes: 10 additions & 6 deletions pkg/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ var createWorkerCmd = &cobra.Command{
}

func getProvisionerConfig(cmd *cobra.Command) provisioner.Config {
join, _ := cmd.Flags().GetBool("join")

return provisioner.Config{
Name: cmd.Flag("name").Value.String(),
CPUs: cmd.Flag("cpus").Value.String(),
Memory: cmd.Flag("memory").Value.String(),
Disk: cmd.Flag("disk").Value.String(),
K8sVersion: cmd.Flag("k8s-version").Value.String(),
Image: cmd.Flag("image").Value.String(),
Name: cmd.Flag("name").Value.String(),
CPUs: cmd.Flag("cpus").Value.String(),
Memory: cmd.Flag("memory").Value.String(),
Disk: cmd.Flag("disk").Value.String(),
K8sVersion: cmd.Flag("k8s-version").Value.String(),
Image: cmd.Flag("image").Value.String(),
IsJoinCluster: join,
}
}

Expand All @@ -42,6 +45,7 @@ func defineCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringP("disk", "d", "10G", "Amount of disk space")
cmd.Flags().StringP("k8s-version", "k", "v1.30.0", "Kubernetes version")
cmd.Flags().StringP("image", "i", "22.04", "Image to use for the VM")
cmd.Flags().BoolP("join", "j", true, "Join the cluster")
}

func init() {
Expand Down
10 changes: 7 additions & 3 deletions pkg/multipass/multipass.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,17 @@ func LaunchInstance(config InstanceConfig, cloudinit string) error {
return err
}

func Exec(name string, command string) error {
func Exec(name string, command string) (string, error) {
args := []string{"exec", name, "--"}
args = append(args, strings.Fields(command)...)

cmd := exec.Command("multipass", args...)
_, err := cmd.Output()
return err
output, err := cmd.Output()
if err != nil {
return "", err
}

return string(output), nil
}

func Transfer(name string, from string, to string) error {
Expand Down
84 changes: 30 additions & 54 deletions pkg/provisioner/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,86 +9,62 @@ import (
"k8s.io/apimachinery/pkg/runtime"
clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"

"github.com/ryota-sakamoto/kubernetes-on-multipass/pkg/cloudinit"
"github.com/ryota-sakamoto/kubernetes-on-multipass/pkg/kubernetes"
"github.com/ryota-sakamoto/kubernetes-on-multipass/pkg/multipass"
)

type Config struct {
Name string
CPUs string
Memory string
Disk string
K8sVersion string
Image string
Name string
CPUs string
Memory string
Disk string
K8sVersion string
Image string
IsJoinCluster bool
}

func CreateMaster(clusterName string, config Config) error {
slog.Debug("create master", slog.String("clusterName", clusterName), slog.Any("config", config))

instanceName := fmt.Sprintf("%s-%s", clusterName, "master")
instance, err := multipass.GetInstance(instanceName)
config.Name = "master"
_, err := LaunchInstance(clusterName, config, GetMasterTemplate())
if err != nil {
return fmt.Errorf("failed to get instance: %w", err)
}

slog.Debug("get instance", slog.String("instanceName", instanceName), slog.Any("instance", instance))
if instance != nil {
return nil
return fmt.Errorf("failed to launch instance: %w", err)
}

template, err := cloudinit.Generate(GetMasterTemplate(), map[string]string{
"KubernetesVersion": config.K8sVersion,
"Arch": "amd64",
})
if err != nil {
return fmt.Errorf("failed to generate cloud-init template: %w", err)
}

return multipass.LaunchInstance(multipass.InstanceConfig{
Name: instanceName,
CPUs: config.CPUs,
Memory: config.Memory,
Disk: config.Disk,
Image: config.Image,
}, template)
return nil
}

func CreateWorker(clusterName string, config Config) error {
slog.Debug("create worker", slog.String("clusterName", clusterName), slog.Any("config", config))

name := config.Name
if name == "" {
name = GetRandomName()
instanceName, err := LaunchInstance(clusterName, config, GetWorkerTemplate())
if err != nil {
return fmt.Errorf("failed to launch instance: %w", err)
}

instanceName := fmt.Sprintf("%s-%s", clusterName, name)

instance, err := multipass.GetInstance(instanceName)
if err != nil {
return fmt.Errorf("failed to get instance: %w", err)
if config.IsJoinCluster {
return JoinCluster(clusterName, instanceName)
}

slog.Debug("get instance", slog.String("instanceName", instanceName), slog.Any("instance", instance))
if instance != nil {
return nil
return nil
}

func JoinCluster(clusterName, name string) error {
slog.Debug("join cluster", slog.String("clusterName", clusterName), slog.String("name", name))

masterName := clusterName + "-master"
joinCommand, err := multipass.Exec(masterName, "sudo kubeadm token create --print-join-command")
if err != nil {
return fmt.Errorf("failed to get join command: %w", err)
}

template, err := cloudinit.Generate(GetWorkerTemplate(), map[string]string{
"KubernetesVersion": config.K8sVersion,
"Arch": "amd64",
})
_, err = multipass.Exec(name, fmt.Sprintf("sudo %s", joinCommand))
if err != nil {
return fmt.Errorf("failed to generate cloud-init template: %w", err)
return fmt.Errorf("failed to join cluster: %w", err)
}

return multipass.LaunchInstance(multipass.InstanceConfig{
Name: instanceName,
CPUs: config.CPUs,
Memory: config.Memory,
Disk: config.Disk,
Image: config.Image,
}, template)
return nil
}

func GenerateKubeconfig(name string) error {
Expand All @@ -104,7 +80,7 @@ func GenerateKubeconfig(name string) error {
return fmt.Errorf("instance not found: %s", name)
}

err = multipass.Exec(name, "/opt/csr.sh")
_, err = multipass.Exec(name, "/opt/csr.sh")
if err != nil {
return fmt.Errorf("failed to execute csr.sh: %w", err)
}
Expand Down
44 changes: 44 additions & 0 deletions pkg/provisioner/instance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package provisioner

import (
"fmt"
"log/slog"

"github.com/ryota-sakamoto/kubernetes-on-multipass/pkg/cloudinit"
"github.com/ryota-sakamoto/kubernetes-on-multipass/pkg/multipass"
)

func LaunchInstance(clusterName string, config Config, cloudinitConfig cloudinit.Config) (string, error) {
name := config.Name
if name == "" {
name = GetRandomName()
}

instanceName := fmt.Sprintf("%s-%s", clusterName, name)

instance, err := multipass.GetInstance(instanceName)
if err != nil {
return "", fmt.Errorf("failed to get instance: %w", err)
}

slog.Debug("get instance", slog.String("instanceName", instanceName), slog.Any("instance", instance))
if instance != nil {
return "", fmt.Errorf("instance already exists: %s", instanceName)
}

template, err := cloudinit.Generate(GetWorkerTemplate(), map[string]string{
"KubernetesVersion": config.K8sVersion,
"Arch": "amd64",
})
if err != nil {
return "", fmt.Errorf("failed to generate cloud-init template: %w", err)
}

return instanceName, multipass.LaunchInstance(multipass.InstanceConfig{
Name: instanceName,
CPUs: config.CPUs,
Memory: config.Memory,
Disk: config.Disk,
Image: config.Image,
}, template)
}

0 comments on commit b199f50

Please sign in to comment.