X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=cmd%2Fsafcm%2Fconfig%2Fgroups.go;h=466e493c401ea895062294304b0961c5f360ce2d;hb=77f373a4aa590711155e3af0b768997781f81559;hp=7f7cb3f635c346663808e69e990aac020040b345;hpb=f2f2bc47e8729548f3c10117f7f008b547c4afc5;p=safcm%2Fsafcm.git diff --git a/cmd/safcm/config/groups.go b/cmd/safcm/config/groups.go index 7f7cb3f..466e493 100644 --- a/cmd/safcm/config/groups.go +++ b/cmd/safcm/config/groups.go @@ -34,7 +34,7 @@ const ( GroupRemoveSuffix = GroupSpecialSeparator + "remove" ) -// Keep in sync with sync_info.go:infoGroupDetectedRegexp +// Keep in sync with cmd/safcm/sync_info.go:infoGroupDetectedRegexp var groupNameRegexp = regexp.MustCompile(`^[a-z0-9_-]+$`) func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) { @@ -60,7 +60,9 @@ func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) { "%s conflict with pre-defined group %q", errPrefix, name) } - if hosts.Map[name] != nil { + if hosts.Map[name] != nil || + hosts.Map[strings.TrimSuffix(name, + GroupRemoveSuffix)] != nil { return nil, fmt.Errorf( "%s conflict with existing host", errPrefix) @@ -84,6 +86,8 @@ func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) { if x == GroupAll { continue } + // Don't validate against groupNameRegexp because + // hosts have less strict restrictions. if strings.Contains(x, GroupSpecialSeparator) { return nil, fmt.Errorf( "%s member %q must not contain %q", @@ -95,14 +99,14 @@ func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) { if hosts.Map[x] != nil || groups[x] != nil { continue } - return nil, fmt.Errorf("%s group %q not found", + return nil, fmt.Errorf("%s member %q not found", errPrefix, x) } } // Sanity check for global configuration - for _, x := range cfg.GroupOrder { - const errPrefix = "config.yaml: group_order:" + for _, x := range cfg.GroupPriority { + const errPrefix = "config.yaml: group_priority:" if x == GroupAll { continue @@ -124,11 +128,10 @@ func LoadGroups(cfg *Config, hosts *Hosts) (map[string][]string, error) { return groups, nil } -func ResolveHostGroups(host string, - groups map[string][]string, +func ResolveHostGroups(host string, groups map[string][]string, detectedGroups []string) ([]string, error) { - const maxDepth = 100 + const maxRecursionDepth = 100 detectedGroupsMap := make(map[string]bool) for _, x := range detectedGroups { @@ -140,7 +143,7 @@ func ResolveHostGroups(host string, // groups). var lookup func(string, int) bool lookup = func(group string, depth int) bool { - if depth > maxDepth { + if depth > maxRecursionDepth { cycle = &group return false } @@ -186,3 +189,36 @@ func ResolveHostGroups(host string, sort.Strings(res) return res, nil } + +// TransitivelyDetectedGroups returns all groups which depend on "detected" +// groups, either directly or by depending on groups which transitively depend +// on "detected" groups. +func TransitivelyDetectedGroups(groups map[string][]string) map[string]bool { + work := make(map[string][]string) + for k, v := range groups { + work[k] = v + } + + // Mark all groups which contain "detected" groups as long as new + // (transitive) "detected" groups are found. + detected := make(map[string]bool) + for { + change := false + for group, members := range work { + for _, x := range members { + if !detected[x] && !strings.HasPrefix(x, + GroupDetectedPrefix) { + continue + } + detected[strings.TrimSuffix(group, + GroupRemoveSuffix)] = true + delete(work, group) + change = true + } + } + if !change { + break + } + } + return detected +}