// processUnits takes a set of Units and applies them to the given root using
// the given UnitManager. This can involve things like writing unit files to
// disk, masking/unmasking units, or invoking systemd
// commands against units. It returns any error encountered.
func processUnits(units []system.Unit, root string, um system.UnitManager) error {
	commands := make(map[string]string, 0)
	reload := false
	for _, unit := range units {
		dst := unit.Destination(root)
		if unit.Content != "" {
			log.Printf("Writing unit %s to filesystem at path %s", unit.Name, dst)
			if err := um.PlaceUnit(&unit, dst); err != nil {
				return err
			}
			log.Printf("Placed unit %s at %s", unit.Name, dst)
			reload = true
		}

		if unit.Mask {
			log.Printf("Masking unit file %s", unit.Name)
			if err := um.MaskUnit(&unit); err != nil {
				return err
			}
		} else if unit.Runtime {
			log.Printf("Ensuring runtime unit file %s is unmasked", unit.Name)
			if err := um.UnmaskUnit(&unit); err != nil {
				return err
			}
		}

		if unit.Enable {
			if unit.Group() != "network" {
				log.Printf("Enabling unit file %s", unit.Name)
				if err := um.EnableUnitFile(unit.Name, unit.Runtime); err != nil {
					return err
				}
				log.Printf("Enabled unit %s", unit.Name)
			} else {
				log.Printf("Skipping enable for network-like unit %s", unit.Name)
			}
		}

		if unit.Group() == "network" {
			commands["systemd-networkd.service"] = "restart"
		} else if unit.Command != "" {
			commands[unit.Name] = unit.Command
		}
	}

	if reload {
		if err := um.DaemonReload(); err != nil {
			return errors.New(fmt.Sprintf("failed systemd daemon-reload: %v", err))
		}
	}

	for unit, command := range commands {
		log.Printf("Calling unit command '%s %s'", command, unit)
		res, err := um.RunUnitCommand(command, unit)
		if err != nil {
			return err
		}
		log.Printf("Result of '%s %s': %s", command, unit, res)
	}

	return nil
}
Example #2
0
File: config.go Project: pirater/os
// processUnits takes a set of Units and applies them to the given root using
// the given UnitManager. This can involve things like writing unit files to
// disk, masking/unmasking units, or invoking systemd
// commands against units. It returns any error encountered.
func processUnits(units []system.Unit, root string, um system.UnitManager) error {
	type action struct {
		unit    system.Unit
		command string
	}
	actions := make([]action, 0, len(units))
	reload := false
	restartNetworkd := false
	for _, unit := range units {
		if unit.Name == "" {
			log.Printf("Skipping unit without name")
			continue
		}

		if unit.Content != "" {
			log.Printf("Writing unit %q to filesystem", unit.Name)
			if err := um.PlaceUnit(unit); err != nil {
				return err
			}
			log.Printf("Wrote unit %q", unit.Name)
			reload = true
		}

		for _, dropin := range unit.DropIns {
			if dropin.Name != "" && dropin.Content != "" {
				log.Printf("Writing drop-in unit %q to filesystem", dropin.Name)
				if err := um.PlaceUnitDropIn(unit, dropin); err != nil {
					return err
				}
				log.Printf("Wrote drop-in unit %q", dropin.Name)
				reload = true
			}
		}

		if unit.Mask {
			log.Printf("Masking unit file %q", unit.Name)
			if err := um.MaskUnit(unit); err != nil {
				return err
			}
		} else if unit.Runtime {
			log.Printf("Ensuring runtime unit file %q is unmasked", unit.Name)
			if err := um.UnmaskUnit(unit); err != nil {
				return err
			}
		}

		if unit.Enable {
			if unit.Group() != "network" {
				log.Printf("Enabling unit file %q", unit.Name)
				if err := um.EnableUnitFile(unit); err != nil {
					return err
				}
				log.Printf("Enabled unit %q", unit.Name)
			} else {
				log.Printf("Skipping enable for network-like unit %q", unit.Name)
			}
		}

		if unit.Group() == "network" {
			restartNetworkd = true
		} else if unit.Command != "" {
			actions = append(actions, action{unit, unit.Command})
		}
	}

	if reload {
		if err := um.DaemonReload(); err != nil {
			return errors.New(fmt.Sprintf("failed systemd daemon-reload: %s", err))
		}
	}

	if restartNetworkd {
		log.Printf("Restarting systemd-networkd")
		networkd := system.Unit{Unit: config.Unit{Name: "systemd-networkd.service"}}
		res, err := um.RunUnitCommand(networkd, "restart")
		if err != nil {
			return err
		}
		log.Printf("Restarted systemd-networkd (%s)", res)
	}

	for _, action := range actions {
		log.Printf("Calling unit command %q on %q'", action.command, action.unit.Name)
		res, err := um.RunUnitCommand(action.unit, action.command)
		if err != nil {
			return err
		}
		log.Printf("Result of %q on %q: %s", action.command, action.unit.Name, res)
	}

	return nil
}