// ValidateOptions ensures that a set of UnitOptions is valid; if not, an error // is returned detailing the issue encountered. If there are several problems // with a set of options, only the first is returned. func ValidateOptions(opts []*schema.UnitOption) error { uf := schema.MapSchemaUnitOptionsToUnitFile(opts) // Sanity check using go-systemd's deserializer, which will do things // like check for excessive line lengths _, err := gsunit.Deserialize(gsunit.Serialize(uf.Options)) if err != nil { return err } j := &job.Job{ Unit: *uf, } conflicts := pkg.NewUnsafeSet(j.Conflicts()...) peers := pkg.NewUnsafeSet(j.Peers()...) for _, peer := range peers.Values() { for _, conflict := range conflicts.Values() { matched, _ := path.Match(conflict, peer) if matched { return fmt.Errorf("unresolvable requirements: peer %q matches conflict %q", peer, conflict) } } } hasPeers := peers.Length() != 0 hasConflicts := conflicts.Length() != 0 _, hasReqTarget := j.RequiredTarget() u := &job.Unit{ Unit: *uf, } isGlobal := u.IsGlobal() switch { case hasReqTarget && hasPeers: return errors.New("MachineID cannot be used with Peers") case hasReqTarget && hasConflicts: return errors.New("MachineID cannot be used with Conflicts") case hasReqTarget && isGlobal: return errors.New("MachineID cannot be used with Global") case isGlobal && hasPeers: return errors.New("Global cannot be used with Peers") case isGlobal && hasConflicts: return errors.New("Global cannot be used with Conflicts") } return nil }
func (u *UnitFile) Bytes() []byte { b, _ := ioutil.ReadAll(unit.Serialize(u.Options)) return b }