filter nodes and validate volume mounts

This commit is contained in:
iwilltry42 2019-11-06 19:34:20 +01:00
parent 62501af7e9
commit c92c9b8e2f
3 changed files with 42 additions and 78 deletions

View File

@ -130,11 +130,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
} }
volumeFilterMap := make(map[string]string, 1) volumeFilterMap := make(map[string]string, 1)
for _, volumeFlag := range volumeFlags { for _, volumeFlag := range volumeFlags {
v, f, err := cliutil.SplitFilterFromFlag(volumeFlag) volume, filter, err := cliutil.SplitFilterFromFlag(volumeFlag)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
volumeFilterMap[v] = f if err := cliutil.ValidateVolumeMount(volume); err != nil {
log.Fatalln(err)
}
volumeFilterMap[volume] = filter
} }
/* generate cluster */ /* generate cluster */
@ -178,11 +181,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
// append volumes // append volumes
// TODO: // TODO:
for v, f := range volumeFilterMap { for volume, filter := range volumeFilterMap {
nodes, err := cliutil.FilterNodes(f) nodes, err := cliutil.FilterNodes(&cluster.Nodes, filter)
if err != nil { if err != nil {
log.Fatalln(err) log.Fatalln(err)
} }
for _, node := range nodes {
node.Volumes = append(node.Volumes, volume)
}
} }
return runtime, cluster return runtime, cluster

View File

@ -75,7 +75,7 @@ func SplitFilterFromFlag(flag string) (string, string, error) {
} }
// FilterNodes takes a string filter to return a filtered list of nodes // FilterNodes takes a string filter to return a filtered list of nodes
func FilterNodes(filterString string, nodes []*k3d.Node) ([]*k3d.Node, error) { func FilterNodes(nodes *[]k3d.Node, filterString string) ([]*k3d.Node, error) {
// filterString is a semicolon-separated list of node filters // filterString is a semicolon-separated list of node filters
filters := strings.Split(filterString, ";") filters := strings.Split(filterString, ";")

View File

@ -25,43 +25,19 @@ import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
log "github.com/sirupsen/logrus"
) )
// ValidateVolumeFlag checks, if the source of volume mounts exists and if the destination is an absolute path // ValidateVolumeMount checks, if the source of volume mounts exists and if the destination is an absolute path
// a flag can look like this: --volume SRC:DST@NODES, where...
// - SRC: source directory/file -> tests: must exist // - SRC: source directory/file -> tests: must exist
// - DEST: source directory/file -> tests: must be absolute path // - DEST: source directory/file -> tests: must be absolute path
// - NODES: specifies a set of nodes -> tests: fit regex // TODO: func ValidateVolumeMount(volumeMount string) error {
func ValidateVolumeFlag(volumeFlags []string) (string, string, error) {
for _, volume := range volumeFlags {
src := "" src := ""
dest := "" dest := ""
nodes := ""
split := strings.Split(volume, "@")
// max number of pieces after split = 2 (only one @ allowed in flag)
if len(split) > 2 {
return rolesToVolumesMap, fmt.Errorf("Invalid volume flag '%s': only one '@' allowed", volume)
}
// min number of pieces after split = 1 (catch empty flags)
if len(split) > 1 {
nodes = split[1]
}
// catch all other unlikely cases
if len(split) == 0 || split[0] == "" {
return rolesToVolumesMap, fmt.Errorf("Invalid volume flag '%s'", volume)
}
// validate 'SRC[:DEST]' substring // validate 'SRC[:DEST]' substring
split = strings.Split(split[0], ":") split := strings.Split(volumeMount, ":")
if len(split) < 1 || len(split) > 2 { if len(split) < 1 || len(split) > 2 {
return rolesToVolumesMap, fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volume) return fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volumeMount)
} }
// we only have SRC specified -> DEST = SRC // we only have SRC specified -> DEST = SRC
@ -76,32 +52,14 @@ func ValidateVolumeFlag(volumeFlags []string) (string, string, error) {
// verify that the source exists // verify that the source exists
if src != "" { if src != "" {
if _, err := os.Stat(src); err != nil { if _, err := os.Stat(src); err != nil {
return rolesToVolumesMap, fmt.Errorf("Failed to stat file/dir that you're trying to mount: '%s' in '%s'", src, volume) return fmt.Errorf("Failed to stat file/dir that you're trying to mount: '%s' in '%s'", src, volumeMount)
} }
} }
// verify that the destination is an absolute path // verify that the destination is an absolute path
if !strings.HasPrefix(dest, "/") { if !strings.HasPrefix(dest, "/") {
return rolesToVolumesMap, fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volume) return fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volumeMount)
} }
// put into struct return nil
volumeSpec.Source = src
volumeSpec.Destination = dest
// if no nodes are specified with an @nodeset, attach volume to all nodes and go to next value
if nodes == "" {
rolesToVolumesMap.AllRoles = append(rolesToVolumesMap.AllRoles, volumeSpec)
continue
}
specifiedNodes, err := parseNodeSpecifier(nodes, masterCount, workerCount)
if err != nil {
log.Errorf("Failed to parse node specifier on '--volume %s'", volume)
return rolesToVolumesMap, err
}
log.Debugf("Specified nodes: %+v", specifiedNodes)
}
return rolesToVolumesMap, nil
} }