Beispiel #1
0
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)
}
Beispiel #2
0
// 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)
}
Beispiel #3
0
// 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)
}
Beispiel #4
0
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
}
Beispiel #5
0
// 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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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
}
Beispiel #8
0
// 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

}
Beispiel #10
0
// 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
}
Beispiel #11
0
// 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)
}
Beispiel #12
0
// 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
}