Esempio n. 1
0
// assignPod assigns the given pod to the given machine.
func (r *Registry) assignPod(ctx api.Context, podID string, machine string) error {
	finalPod, err := r.setPodHostTo(ctx, podID, "", machine)
	if err != nil {
		return err
	}
	boundPod, err := r.boundPodFactory.MakeBoundPod(machine, finalPod)
	if err != nil {
		return err
	}
	// Doing the constraint check this way provides atomicity guarantees.
	contKey := makeBoundPodsKey(machine)
	err = r.AtomicUpdate(contKey, &api.BoundPods{}, func(in runtime.Object) (runtime.Object, error) {
		boundPodList := in.(*api.BoundPods)
		boundPodList.Items = append(boundPodList.Items, *boundPod)
		if !constraint.Allowed(boundPodList.Items) {
			return nil, fmt.Errorf("the assignment would cause a constraint violation")
		}
		return boundPodList, nil
	})
	if err != nil {
		// Put the pod's host back the way it was. This is a terrible hack, but
		// can't really be helped, since there's not really a way to do atomic
		// multi-object changes in etcd.
		if _, err2 := r.setPodHostTo(ctx, podID, machine, ""); err2 != nil {
			glog.Errorf("Stranding pod %v; couldn't clear host after previous error: %v", podID, err2)
		}
	}
	return err
}
Esempio n. 2
0
// assignPod assigns the given pod to the given machine.
func (r *Registry) assignPod(podID string, machine string) error {
	finalPod, err := r.setPodHostTo(podID, "", machine)
	if err != nil {
		return err
	}
	// TODO: move this to a watch/rectification loop.
	manifest, err := r.manifestFactory.MakeManifest(machine, *finalPod)
	if err != nil {
		return err
	}
	contKey := makeContainerKey(machine)
	err = r.AtomicUpdate(contKey, &api.ContainerManifestList{}, func(in interface{}) (interface{}, error) {
		manifests := *in.(*api.ContainerManifestList)
		manifests.Items = append(manifests.Items, manifest)
		if !constraint.Allowed(manifests.Items) {
			return nil, fmt.Errorf("The assignment would cause a constraint violation")
		}
		return manifests, nil
	})
	if err != nil {
		// Put the pod's host back the way it was. This is a terrible hack that
		// won't be needed if we convert this to a rectification loop.
		if _, err2 := r.setPodHostTo(podID, machine, ""); err2 != nil {
			glog.Errorf("Stranding pod %v; couldn't clear host after previous error: %v", podID, err2)
		}
	}
	return err
}
Esempio n. 3
0
// assignPod assigns the given pod to the given machine.
func (r *Registry) assignPod(ctx api.Context, binding *api.Binding) error {
	podID := binding.PodID
	//finalPod, err := r.setPodHostTo(ctx, podID, "", machine)
	oldBind := &api.Binding{
		PodID:   podID,
		Host:    "",
		Network: api.Network{},
		CpuSet:  "",
	}
	finalPod, err := r.setPodToHost(ctx, oldBind, binding)
	if err != nil {
		return err
	}
	boundPod, err := r.boundPodFactory.MakeBoundPod(binding.Host, finalPod)
	if err != nil {
		return err
	}
	boundPod.Res = api.BoundResource{Network: binding.Network, CpuSet: binding.CpuSet}

	// Doing the constraint check this way provides atomicity guarantees.
	contKey := makeBoundPodsKey(binding.Host)
	err = r.AtomicUpdate(contKey, &api.BoundPods{}, func(in runtime.Object) (runtime.Object, error) {
		boundPodList := in.(*api.BoundPods)
		boundPodList.Items = append(boundPodList.Items, *boundPod)
		if !constraint.Allowed(boundPodList.Items) {
			return nil, fmt.Errorf("the assignment would cause a constraint violation")
		}
		return boundPodList, nil
	})
	glog.V(3).Infof("End to bound pod %+v", binding)
	if err != nil {
		// Put the pod's host back the way it was. This is a terrible hack, but
		// can't really be helped, since there's not really a way to do atomic
		// multi-object changes in etcd.
		//if _, err2 := r.setPodHostTo(ctx, podID, machine, ""); err2 != nil {
		if _, err2 := r.setPodToHost(ctx, binding, oldBind); err2 != nil {
			glog.Errorf("Stranding pod %v; couldn't clear host after previous error: %v", podID, err2)
		}
	}
	return err
}