// 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 }
// 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 }
// 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 }