Skip to content

Commit

Permalink
Merge pull request #116 from cedrickring/add-node-specifier
Browse files Browse the repository at this point in the history
Add node-specifier for volumes (thanks to @cedrickring )
  • Loading branch information
iwilltry42 authored Oct 10, 2019
2 parents 0d01441 + 33c3f7c commit b09a968
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 18 deletions.
10 changes: 8 additions & 2 deletions cli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,13 @@ func CreateCluster(c *cli.Context) error {
return err
}
volumes := c.StringSlice("volume")
volumes = append(volumes, fmt.Sprintf("%s:/images", imageVolume.Name))

volumesSpec, err := NewVolumes(volumes)
if err != nil {
return err
}

volumesSpec.DefaultVolumes = append(volumesSpec.DefaultVolumes, fmt.Sprintf("%s:/images", imageVolume.Name))

clusterSpec := &ClusterSpec{
AgentArgs: k3AgentArgs,
Expand All @@ -159,7 +165,7 @@ func CreateCluster(c *cli.Context) error {
NodeToPortSpecMap: portmap,
PortAutoOffset: c.Int("port-auto-offset"),
ServerArgs: k3sServerArgs,
Volumes: volumes,
Volumes: volumesSpec,
}

// create the server
Expand Down
10 changes: 3 additions & 7 deletions cli/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type ClusterSpec struct {
NodeToPortSpecMap map[string][]string
PortAutoOffset int
ServerArgs []string
Volumes []string
Volumes *Volumes
}

func startContainer(config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, containerName string) (string, error) {
Expand Down Expand Up @@ -118,9 +118,7 @@ func createServer(spec *ClusterSpec) (string, error) {
hostConfig.RestartPolicy.Name = "unless-stopped"
}

if len(spec.Volumes) > 0 && spec.Volumes[0] != "" {
hostConfig.Binds = spec.Volumes
}
spec.Volumes.addVolumesToHostConfig(containerName, "server", hostConfig)

networkingConfig := &network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
Expand Down Expand Up @@ -187,9 +185,7 @@ func createWorker(spec *ClusterSpec, postfix int) (string, error) {
hostConfig.RestartPolicy.Name = "unless-stopped"
}

if len(spec.Volumes) > 0 && spec.Volumes[0] != "" {
hostConfig.Binds = spec.Volumes
}
spec.Volumes.addVolumesToHostConfig(containerName, "worker", hostConfig)

networkingConfig := &network.NetworkingConfig{
EndpointsConfig: map[string]*network.EndpointSettings{
Expand Down
9 changes: 0 additions & 9 deletions cli/port.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,6 @@ type PublishedPorts struct {
PortBindings map[nat.Port][]nat.PortBinding
}

// defaultNodes describes the type of nodes on which a port should be exposed by default
const defaultNodes = "server"

// mapping a node role to groups that should be applied to it
var nodeRuleGroupsMap = map[string][]string{
"worker": {"all", "workers"},
"server": {"all", "server", "master"},
}

// mapNodesToPortSpecs maps nodes to portSpecs
func mapNodesToPortSpecs(specs []string, createdNodes []string) (map[string][]string, error) {

Expand Down
9 changes: 9 additions & 0 deletions cli/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ const (
letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits
)

// defaultNodes describes the default node group (master)
const defaultNodes = "server"

// mapping a node role to groups that should be applied to it
var nodeRuleGroupsMap = map[string][]string{
"worker": {"all", "workers"},
"server": {"all", "server", "master"},
}

var src = rand.NewSource(time.Now().UnixNano())

// GenerateRandomString thanks to https://stackoverflow.com/a/31832326/6450189
Expand Down
87 changes: 87 additions & 0 deletions cli/volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ package run
import (
"context"
"fmt"
"strings"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/volume"
"github.com/docker/docker/client"
)

type Volumes struct {
DefaultVolumes []string
NodeSpecificVolumes map[string][]string
GroupSpecificVolumes map[string][]string
}

// createImageVolume will create a new docker volume used for storing image tarballs that can be loaded into the clusters
func createImageVolume(clusterName string) (types.Volume, error) {

Expand Down Expand Up @@ -90,3 +98,82 @@ func getImageVolume(clusterName string) (types.Volume, error) {

return vol, nil
}

func NewVolumes(volumes []string) (*Volumes, error) {
volumesSpec := &Volumes{
DefaultVolumes: []string{},
NodeSpecificVolumes: make(map[string][]string),
GroupSpecificVolumes: make(map[string][]string),
}

volumes:
for _, volume := range volumes {
if strings.Contains(volume, "@") {
split := strings.Split(volume, "@")
if len(split) != 2 {
return nil, fmt.Errorf("invalid node volume spec: %s", volume)
}

nodeVolumes := split[0]
node := strings.ToLower(split[1])
if len(node) == 0 {
return nil, fmt.Errorf("invalid node volume spec: %s", volume)
}

// check if node selector is a node group
for group, names := range nodeRuleGroupsMap {
added := false

for _, name := range names {
if name == node {
volumesSpec.addGroupSpecificVolume(group, nodeVolumes)
added = true
break
}
}

if added {
continue volumes
}
}

// otherwise this is a volume for a specific node
volumesSpec.addNodeSpecificVolume(node, nodeVolumes)
} else {
volumesSpec.DefaultVolumes = append(volumesSpec.DefaultVolumes, volume)
}
}

return volumesSpec, nil
}

// addVolumesToHostConfig adds all default volumes and node / group specific volumes to a HostConfig
func (v Volumes) addVolumesToHostConfig(containerName string, groupName string, hostConfig *container.HostConfig) {
volumes := v.DefaultVolumes

if v, ok := v.NodeSpecificVolumes[containerName]; ok {
volumes = append(volumes, v...)
}

if v, ok := v.GroupSpecificVolumes[groupName]; ok {
volumes = append(volumes, v...)
}

if len(volumes) > 0 {
hostConfig.Binds = volumes
}
}

func (v *Volumes) addNodeSpecificVolume(node, volume string) {
if _, ok := v.NodeSpecificVolumes[node]; !ok {
v.NodeSpecificVolumes[node] = []string{}
}
v.NodeSpecificVolumes[node] = append(v.NodeSpecificVolumes[node], volume)
}

func (v *Volumes) addGroupSpecificVolume(group, volume string) {
if _, ok := v.GroupSpecificVolumes[group]; !ok {
v.GroupSpecificVolumes[group] = []string{}
}
v.GroupSpecificVolumes[group] = append(v.GroupSpecificVolumes[group], volume)
}

0 comments on commit b09a968

Please # to comment.