package budget import ( "fmt" "io" "strings" ) type application struct { config config paths paths ctl unitCtl run func(...string) error out io.Writer } func (a application) apply() error { files, err := a.config.render() if err != nil { return err } if err := writeFiles(a.paths, files); err != nil { return err } if err := a.run("daemon-reload"); err != nil { return err } units, err := a.ctl.Units() if err != nil { return err } for _, unit := range units { name := a.config.unitProfile(unit.Name) if name == "" || unit.Active != "active" { continue } values, err := a.config.properties(name) if err != nil { return err } if err := a.ctl.Set(unit.Name, values); err != nil { return err } } if err := a.run("enable", "budget.service"); err != nil { return err } if err := a.run("restart", "budget.service"); err != nil { return err } _, err = fmt.Fprintf(a.out, "Applied %d resource configuration files\n", len(files)) return err } func selectUnits(c config, units []unit, target string) []string { selected := map[string]bool{} if strings.HasSuffix(target, ".slice") || strings.HasSuffix(target, ".scope") || strings.HasSuffix(target, ".service") { selected[target] = true } else { for _, unit := range units { if unit.Active == "active" && appMatches(target, unit.Name) { selected[unit.Name] = true } } if _, shared := c.Shared[target]; shared { selected[c.sharedSlice()] = true } } return keys(selected) } func (a application) override(name, target string) error { values, err := a.config.properties(name) if err != nil { return err } units, err := a.ctl.Units() if err != nil { return err } selected := selectUnits(a.config, units, target) if len(selected) == 0 { return fmt.Errorf("no running unit matches %s", target) } all := map[string]bool{} for _, name := range selected { all[name] = true } for _, unit := range selected { if !strings.HasSuffix(unit, ".slice") { continue } group, err := a.ctl.Group(unit) if err != nil { return err } for _, child := range units { if child.Active != "active" || all[child.Name] || (!strings.HasSuffix(child.Name, ".scope") && !strings.HasSuffix(child.Name, ".service")) { continue } childGroup, err := a.ctl.Group(child.Name) if err != nil { return err } if strings.HasPrefix(childGroup, group+"/") { all[child.Name] = true } } } for _, unit := range keys(all) { if err := a.ctl.Set(unit, values); err != nil { return err } if _, err := fmt.Fprintf(a.out, "%s: %s\n", unit, name); err != nil { return err } } return nil }