func (s *initSystemSuite) checkCreateFileCall(c *gc.C, index int, filename, content string, perm os.FileMode) { if content == "" { name := filename filename = fmt.Sprintf("%s/init/%s/%s.service", s.dataDir, name, name) content = s.newConfStr(name) } call := s.stub.Calls()[index] if !c.Check(call.FuncName, gc.Equals, "CreateFile") { return } if !c.Check(call.Args, gc.HasLen, 3) { return } callFilename, callData, callPerm := call.Args[0], call.Args[1], call.Args[2] c.Check(callFilename, gc.Equals, filename) // Some tests don't generate valid ini files, instead including placeholder // strings (e.g. "a\nb\nc\n"). To avoid parsing errors, we only try and // parse actual and expected file content if they don't exactly match. if content != string(callData.([]byte)) { // Parse the ini configurations and compare those. expected, err := unit.Deserialize(bytes.NewReader(callData.([]byte))) c.Assert(err, jc.ErrorIsNil) cfg, err := unit.Deserialize(strings.NewReader(content)) c.Assert(err, jc.ErrorIsNil) c.Check(cfg, jc.SameContents, expected) } c.Check(callPerm, gc.Equals, perm) }
// findRktID returns the rkt uuid for the pod. // TODO(yifan): This is unefficient which require us to list // all the unit files. func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) { units, err := r.systemd.ListUnits() if err != nil { return "", err } unitName := makePodServiceFileName(pod.ID) for _, u := range units { // u.Name contains file name ext such as .service, .socket, etc. if u.Name != unitName { continue } f, err := os.Open(path.Join(systemdServiceDir, u.Name)) if err != nil { return "", err } defer f.Close() opts, err := unit.Deserialize(f) if err != nil { return "", err } for _, opt := range opts { if opt.Section == unitKubernetesSection && opt.Name == unitRktID { return opt.Value, nil } } } return "", fmt.Errorf("rkt uuid not found for pod %v", pod) }
// deserialize parses the provided data (in the systemd unit file // format) and populates a new Conf with the result. func deserialize(data []byte, renderer shell.Renderer) (common.Conf, error) { opts, err := unit.Deserialize(bytes.NewBuffer(data)) if err != nil { return common.Conf{}, errors.Trace(err) } return deserializeOptions(opts, renderer) }
func NewUnitFile(raw string) (*UnitFile, error) { reader := strings.NewReader(raw) opts, err := unit.Deserialize(reader) if err != nil { return nil, err } return NewUnitFromOptions(opts), nil }
// 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()...) replaces := pkg.NewUnsafeSet(j.Replaces()...) 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) } } for _, replace := range replaces.Values() { matched, _ := path.Match(replace, peer) if matched { return fmt.Errorf("unresolvable requirements: peer %q matches replace %q", peer, replace) } } } hasPeers := peers.Length() != 0 hasConflicts := conflicts.Length() != 0 hasReplaces := replaces.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 hasReqTarget && hasReplaces: return errors.New("MachineID cannot be used with Replaces") case isGlobal && hasPeers: return errors.New("Global cannot be used with Peers") case isGlobal && hasReplaces: return errors.New("Global cannot be used with Replaces") case hasConflicts && hasReplaces: return errors.New("Conflicts cannot be used with Replaces") } return nil }
// take a unit file as string and convert it to a unit object. func Load(name string, unitAsFile io.Reader) (u *Unit) { opts, err := unit.Deserialize(unitAsFile) if err != nil { panic(err) } u = &Unit{} u.Options = opts u.Name = name + ".service" return }
func validateUnitContent(content string) error { c := bytes.NewBufferString(content) unit, err := unit.Deserialize(c) if err != nil { return fmt.Errorf("invalid unit content: %s", err) } if len(unit) == 0 { return errEmptyUnit } return nil }
// readServiceFile reads the service file and constructs the runtime pod and the rkt info. func (r *runtime) readServiceFile(serviceName string) (*kubecontainer.Pod, *rktInfo, error) { f, err := os.Open(serviceFilePath(serviceName)) if err != nil { return nil, nil, err } defer f.Close() var pod kubecontainer.Pod opts, err := unit.Deserialize(f) if err != nil { return nil, nil, err } info := emptyRktInfo() for _, opt := range opts { if opt.Section != unitKubernetesSection { continue } switch opt.Name { case unitPodName: err = json.Unmarshal([]byte(opt.Value), &pod) if err != nil { return nil, nil, err } case unitRktID: info.uuid = opt.Value case unitRestartCount: cnt, err := strconv.Atoi(opt.Value) if err != nil { return nil, nil, err } info.restartCount = cnt default: return nil, nil, fmt.Errorf("rkt: unexpected key: %q", opt.Name) } } if info.isEmpty() { return nil, nil, fmt.Errorf("rkt: cannot find rkt info of pod %v, unit file is broken", pod) } return &pod, info, nil }
func unitFileToJson(unitFileContent string) ([]byte, error) { // deserialize to units opts, err := unit.Deserialize(strings.NewReader(unitFileContent)) if err != nil { return nil, err } fleetUnit := struct { Options []*unit.UnitOption `json:"options"` DesiredState string `json:"desiredState"` }{ Options: opts, DesiredState: "launched", } bytes, err := json.Marshal(fleetUnit) return bytes, err }
// makeRuntimePod constructs the container runtime pod. It will: // 1, Construct the pod by the information stored in the unit file. // 2, Construct the pod status from pod info. func (r *runtime) makeRuntimePod(unitName string, podInfos map[string]*podInfo) (*kubecontainer.Pod, error) { f, err := os.Open(path.Join(systemdServiceDir, unitName)) if err != nil { return nil, err } defer f.Close() var pod kubecontainer.Pod opts, err := unit.Deserialize(f) if err != nil { return nil, err } var rktID string for _, opt := range opts { if opt.Section != unitKubernetesSection { continue } switch opt.Name { case unitPodName: err = json.Unmarshal([]byte(opt.Value), &pod) if err != nil { return nil, err } case unitRktID: rktID = opt.Value default: return nil, fmt.Errorf("rkt: Unexpected key: %q", opt.Name) } } if len(rktID) == 0 { return nil, fmt.Errorf("rkt: cannot find rkt ID of pod %v, unit file is broken", pod) } info, found := podInfos[rktID] if !found { return nil, fmt.Errorf("rkt: cannot find info for pod %q, rkt uuid: %q", pod.Name, rktID) } pod.Status = info.toPodStatus(&pod) return &pod, nil }
// findRktID returns the rkt uuid for the pod. func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) { serviceName := makePodServiceFileName(pod.ID) f, err := os.Open(serviceFilePath(serviceName)) if err != nil { if os.IsNotExist(err) { return "", fmt.Errorf("no service file %v for runtime pod %q, ID %q", serviceName, pod.Name, pod.ID) } return "", err } defer f.Close() opts, err := unit.Deserialize(f) if err != nil { return "", err } for _, opt := range opts { if opt.Section == unitKubernetesSection && opt.Name == unitRktID { return opt.Value, nil } } return "", fmt.Errorf("rkt uuid not found for pod %v", pod) }
// makeRuntimePod constructs the container runtime pod. It will: // 1, Construct the pod by the information stored in the unit file. // 2, Return the rkt uuid. func (r *runtime) makeRuntimePod(unitName string) (*kubecontainer.Pod, string, error) { f, err := os.Open(path.Join(systemdServiceDir, unitName)) if err != nil { return nil, "", err } defer f.Close() var pod kubecontainer.Pod opts, err := unit.Deserialize(f) if err != nil { return nil, "", err } var rktID string for _, opt := range opts { if opt.Section != unitKubernetesSection { continue } switch opt.Name { case unitPodName: err = json.Unmarshal([]byte(opt.Value), &pod) if err != nil { return nil, "", err } case unitRktID: rktID = opt.Value default: return nil, "", fmt.Errorf("rkt: Unexpected key: %q", opt.Name) } } if len(rktID) == 0 { return nil, "", fmt.Errorf("rkt: cannot find rkt ID of pod %v, unit file is broken", pod) } return &pod, "", nil }