introduce node roles

pull/227/head
iwilltry42 5 years ago
parent cc682427b8
commit 84cdfac7cb
  1. 18
      cmd/create/createCluster.go
  2. 9
      cmd/create/createNode.go
  3. 13
      pkg/cluster/cluster.go
  4. 11
      pkg/cluster/node.go
  5. 15
      pkg/runtimes/docker/container.go
  6. 2
      pkg/runtimes/docker/node.go
  7. 6
      pkg/runtimes/docker/translate_test.go
  8. 16
      pkg/types/types.go

@ -54,6 +54,7 @@ func NewCmdCreateCluster() *cobra.Command {
cmd.Flags().IntP("workers", "w", 0, "Specify how many workers you want to create")
cmd.Flags().String("config", "", "Specify a cluster configuration file") // TODO: to implement
cmd.Flags().String("image", k3d.DefaultK3sImageRepo, "Specify k3s image that you want to use for the nodes") // TODO: get image version
cmd.Flags().String("network", "", "Join an existing network")
// add subcommands
@ -92,14 +93,23 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
log.Fatalln(err)
}
// generate cluster
cluster := &k3d.Cluster{Name: args[0]} // TODO: validate name
// --network
network, err := cmd.Flags().GetString("network")
if err != nil {
log.Fatalln(err)
}
/* generate cluster */
cluster := &k3d.Cluster{
Name: args[0], // TODO: validate name
Network: network,
}
// generate list of nodes
cluster.Nodes = []k3d.Node{}
for i := 0; i < masterCount; i++ {
node := k3d.Node{
Role: "master",
Role: k3d.MasterRole,
Image: image,
}
cluster.Nodes = append(cluster.Nodes, node)
@ -107,7 +117,7 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
for i := 0; i < workerCount; i++ {
node := k3d.Node{
Role: "worker",
Role: k3d.WorkerRole,
Image: image,
}
cluster.Nodes = append(cluster.Nodes, node)

@ -48,7 +48,7 @@ func NewCmdCreateNode() *cobra.Command {
// add flags
cmd.Flags().Int("replicas", 1, "Number of replicas of this node specification.")
cmd.Flags().String("role", "worker", "Specify node role [master, worker]")
cmd.Flags().String("role", string(k3d.WorkerRole), "Specify node role [master, worker]")
cmd.Flags().StringP("cluster", "c", "", "Select the cluster that the node shall connect to.")
cmd.Flags().String("image", k3d.DefaultK3sImageRepo, "Specify k3s image used for the node(s)") // TODO: get image version tag
@ -77,14 +77,15 @@ func parseCreateNodeCmd(cmd *cobra.Command, args []string) ([]*k3d.Node, runtime
}
// --role
role, err := cmd.Flags().GetString("role")
roleStr, err := cmd.Flags().GetString("role")
if err != nil {
log.Errorln("No node role specified")
log.Fatalln(err)
}
if _, ok := k3d.DefaultK3dRoles[role]; !ok {
log.Fatalf("Unknown node role '%s'\n", role)
if _, ok := k3d.DefaultK3dRoles[roleStr]; !ok {
log.Fatalf("Unknown node role '%s'\n", roleStr)
}
role := k3d.DefaultK3dRoles[roleStr]
// --image
image, err := cmd.Flags().GetString("image")

@ -46,11 +46,11 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
// node role specific settings
suffix := 0
if node.Role == "master" {
if node.Role == k3d.MasterRole {
// name suffix
suffix = masterCount
masterCount++
} else if node.Role == "worker" {
} else if node.Role == k3d.WorkerRole {
// name suffix
suffix = workerCount
workerCount++
@ -59,13 +59,14 @@ func CreateCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
node.Name = fmt.Sprintf("%s-%s-%s-%d", k3d.DefaultObjectNamePrefix, cluster.Name, node.Role, suffix)
// create node
log.Infoln("Creating node", node.Name)
log.Infof("Creating node '%s'", node.Name)
if err := CreateNode(&node, runtime); err != nil {
log.Errorln("...failed")
log.Errorln("Failed to create node")
return err
}
log.Debugf("Created node '%s'", node.Name)
}
log.Debugln("...success")
return nil
}
@ -76,7 +77,7 @@ func DeleteCluster(cluster *k3d.Cluster, runtime k3drt.Runtime) error {
// GetClusters returns a list of all existing clusters
func GetClusters(runtime k3drt.Runtime) ([]*k3d.Cluster, error) {
runtime.GetNodesByLabel(map[string]string{"role": "master"})
runtime.GetNodesByLabel(map[string]string{"role": string(k3d.MasterRole)})
return []*k3d.Cluster{}, nil
}

@ -60,11 +60,11 @@ func CreateNode(node *k3d.Node, runtime k3drt.Runtime) error {
node.Labels = labels
// specify options depending on node role
if node.Role == "worker" { // TODO: check here AND in CLI or only here?
if node.Role == k3d.WorkerRole { // TODO: check here AND in CLI or only here?
if err := patchWorkerSpec(node); err != nil {
return err
}
} else if node.Role == "master" {
} else if node.Role == k3d.MasterRole {
if err := patchMasterSpec(node); err != nil {
return err
}
@ -80,7 +80,6 @@ func CreateNode(node *k3d.Node, runtime k3drt.Runtime) error {
return err
}
log.Debugln("...success")
return nil
}
@ -96,21 +95,19 @@ func DeleteNode(node *k3d.Node, runtimeChoice string) error {
if err := runtime.DeleteNode(node); err != nil {
log.Error(err)
}
log.Infoln("Deleted", node.Name)
log.Debugln("...success")
return nil
}
// patchWorkerSpec adds worker node specific settings to a node
func patchWorkerSpec(node *k3d.Node) error {
node.Args = append([]string{"agent"}, node.Args...)
node.Labels["role"] = "worker" // TODO: maybe put those in a global var DefaultWorkerNodeSpec?
node.Labels["role"] = string(k3d.MasterRole) // TODO: maybe put those in a global var DefaultWorkerNodeSpec?
return nil
}
// patchMasterSpec adds worker node specific settings to a node
func patchMasterSpec(node *k3d.Node) error {
node.Args = append([]string{"server"}, node.Args...)
node.Labels["role"] = "master" // TODO: maybe put those in a global var DefaultMasterNodeSpec?
node.Labels["role"] = string(k3d.MasterRole) // TODO: maybe put those in a global var DefaultMasterNodeSpec?
return nil
}

@ -46,10 +46,8 @@ func createContainer(dockerNode *NodeInDocker, name string) error {
return err
}
// check that we have the image locally
// start container
create: // label used to restart process, if we're only missing the image
// create container
create: // label used to restart creation process, if we're only missing the image
resp, err := docker.ContainerCreate(ctx, &dockerNode.ContainerConfig, &dockerNode.HostConfig, &dockerNode.NetworkingConfig, name)
if err != nil {
if client.IsErrNotFound(err) {
@ -62,7 +60,13 @@ create: // label used to restart process, if we're only missing the image
log.Errorln("Failed to create container")
return err
}
log.Infoln("Created container", resp.ID)
log.Debugln("Created container", resp.ID)
// start container
if err := docker.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {
log.Errorln("Failed to start container")
return err
}
return nil
}
@ -95,6 +99,7 @@ func removeContainer(ID string) error {
return nil
}
// pullImage pulls a container image and outputs progress if --verbose flag is set
func pullImage(ctx *context.Context, docker *client.Client, image string) error {
resp, err := docker.ImagePull(*ctx, image, types.ImagePullOptions{})

@ -93,7 +93,7 @@ func (d Docker) GetNodesByLabel(labels map[string]string) ([]*k3d.Node, error) {
for _, container := range containers {
node := &k3d.Node{
Name: container.Names[0],
Role: container.Labels["role"], // TODO: catch keyerror
Role: k3d.DefaultK3dRoles[container.Labels["role"]], // TODO: catch keyerror
Labels: container.Labels,
}
nodes = append(nodes, node)

@ -37,7 +37,7 @@ func TestTranslateNodeToContainer(t *testing.T) {
inputNode := &k3d.Node{
Name: "test",
Role: "master",
Role: k3d.MasterRole,
Image: "rancher/k3s:v0.9.0",
Volumes: []string{"/test:/tmp/test"},
Env: []string{"TEST_KEY_1=TEST_VAL_1"},
@ -45,7 +45,7 @@ func TestTranslateNodeToContainer(t *testing.T) {
Args: []string{"--some-boolflag"},
Ports: []string{"0.0.0.0:6443:6443/tcp"},
Restart: true,
Labels: map[string]string{"k3d.role": "master", "test_key_1": "test_val_1"},
Labels: map[string]string{"k3d.role": string(k3d.MasterRole), "test_key_1": "test_val_1"},
}
expectedRepresentation := &NodeInDocker{
@ -54,7 +54,7 @@ func TestTranslateNodeToContainer(t *testing.T) {
Image: "rancher/k3s:v0.9.0",
Env: []string{"TEST_KEY_1=TEST_VAL_1"},
Cmd: []string{"server", "--https-listen-port=6443", "--some-boolflag"},
Labels: map[string]string{"k3d.role": "master", "test_key_1": "test_val_1"},
Labels: map[string]string{"k3d.role": string(k3d.MasterRole), "test_key_1": "test_val_1"},
ExposedPorts: nat.PortSet{},
},
HostConfig: container.HostConfig{

@ -38,8 +38,20 @@ const DefaultK3sImageRepo = "docker.io/rancher/k3s"
// DefaultObjectNamePrefix defines the name prefix for every object created by k3d
const DefaultObjectNamePrefix = "k3d"
// Role defines a k3d node role
type Role string
// existing k3d node roles
const (
MasterRole Role = "master"
WorkerRole Role = "worker"
)
// DefaultK3dRoles defines the roles available for nodes
var DefaultK3dRoles = map[string]bool{"master": true, "worker": true}
var DefaultK3dRoles = map[string]Role{
string(MasterRole): MasterRole,
string(WorkerRole): WorkerRole,
}
// DefaultObjectLabels specifies a set of labels that will be attached to k3d objects by default
var DefaultObjectLabels = map[string]string{
@ -63,7 +75,7 @@ type Cluster struct {
// Node describes a k3d node
type Node struct {
Name string `yaml:"name" json:"name,omitempty"`
Role string `yaml:"role" json:"role,omitempty"`
Role Role `yaml:"role" json:"role,omitempty"`
Image string `yaml:"image" json:"image,omitempty"`
Volumes []string `yaml:"volumes" json:"volumes,omitempty"`
Env []string `yaml:"env" json:"env,omitempty"`

Loading…
Cancel
Save