filter nodes and validate volume mounts
This commit is contained in:
parent
62501af7e9
commit
c92c9b8e2f
@ -130,11 +130,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
|
||||
}
|
||||
volumeFilterMap := make(map[string]string, 1)
|
||||
for _, volumeFlag := range volumeFlags {
|
||||
v, f, err := cliutil.SplitFilterFromFlag(volumeFlag)
|
||||
volume, filter, err := cliutil.SplitFilterFromFlag(volumeFlag)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
volumeFilterMap[v] = f
|
||||
if err := cliutil.ValidateVolumeMount(volume); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
volumeFilterMap[volume] = filter
|
||||
}
|
||||
|
||||
/* generate cluster */
|
||||
@ -178,11 +181,14 @@ func parseCreateClusterCmd(cmd *cobra.Command, args []string) (runtimes.Runtime,
|
||||
|
||||
// append volumes
|
||||
// TODO:
|
||||
for v, f := range volumeFilterMap {
|
||||
nodes, err := cliutil.FilterNodes(f)
|
||||
for volume, filter := range volumeFilterMap {
|
||||
nodes, err := cliutil.FilterNodes(&cluster.Nodes, filter)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
for _, node := range nodes {
|
||||
node.Volumes = append(node.Volumes, volume)
|
||||
}
|
||||
}
|
||||
|
||||
return runtime, cluster
|
||||
|
||||
@ -75,7 +75,7 @@ func SplitFilterFromFlag(flag string) (string, string, error) {
|
||||
}
|
||||
|
||||
// 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
|
||||
filters := strings.Split(filterString, ";")
|
||||
|
||||
@ -25,83 +25,41 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// ValidateVolumeFlag 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...
|
||||
// ValidateVolumeMount checks, if the source of volume mounts exists and if the destination is an absolute path
|
||||
// - SRC: source directory/file -> tests: must exist
|
||||
// - DEST: source directory/file -> tests: must be absolute path
|
||||
// - NODES: specifies a set of nodes -> tests: fit regex // TODO:
|
||||
func ValidateVolumeFlag(volumeFlags []string) (string, string, error) {
|
||||
|
||||
for _, volume := range volumeFlags {
|
||||
src := ""
|
||||
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
|
||||
split = strings.Split(split[0], ":")
|
||||
if len(split) < 1 || len(split) > 2 {
|
||||
return rolesToVolumesMap, fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volume)
|
||||
}
|
||||
|
||||
// we only have SRC specified -> DEST = SRC
|
||||
if len(split) == 1 {
|
||||
src = split[0]
|
||||
dest = src
|
||||
} else {
|
||||
src = split[0]
|
||||
dest = split[1]
|
||||
}
|
||||
|
||||
// verify that the source exists
|
||||
if src != "" {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// verify that the destination is an absolute path
|
||||
if !strings.HasPrefix(dest, "/") {
|
||||
return rolesToVolumesMap, fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volume)
|
||||
}
|
||||
|
||||
// put into struct
|
||||
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)
|
||||
func ValidateVolumeMount(volumeMount string) error {
|
||||
src := ""
|
||||
dest := ""
|
||||
|
||||
// validate 'SRC[:DEST]' substring
|
||||
split := strings.Split(volumeMount, ":")
|
||||
if len(split) < 1 || len(split) > 2 {
|
||||
return fmt.Errorf("Invalid volume mount '%s': only one ':' allowed", volumeMount)
|
||||
}
|
||||
return rolesToVolumesMap, nil
|
||||
|
||||
// we only have SRC specified -> DEST = SRC
|
||||
if len(split) == 1 {
|
||||
src = split[0]
|
||||
dest = src
|
||||
} else {
|
||||
src = split[0]
|
||||
dest = split[1]
|
||||
}
|
||||
|
||||
// verify that the source exists
|
||||
if src != "" {
|
||||
if _, err := os.Stat(src); err != nil {
|
||||
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
|
||||
if !strings.HasPrefix(dest, "/") {
|
||||
return fmt.Errorf("Volume mount destination doesn't appear to be an absolute path: '%s' in '%s'", dest, volumeMount)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user