func (c *LinuxContainer) Restore(snapshot linux_backend.LinuxContainerSpec) error {
	cLog := c.logger.Session("restore")

	cLog.Debug("restoring")

	c.setState(linux_backend.State(snapshot.State))

	c.Env = snapshot.Env

	for _, ev := range snapshot.Events {
		c.registerEvent(ev)
	}

	if snapshot.Limits.Memory != nil {
		err := c.LimitMemory(*snapshot.Limits.Memory)
		if err != nil {
			cLog.Error("failed-to-limit-memory", err)
			return err
		}
	}

	signaller := c.processSignaller()

	for _, process := range snapshot.Processes {
		cLog.Info("restoring-process", lager.Data{
			"process": process,
		})

		c.processIDPool.Restore(process.ID)
		c.processTracker.Restore(fmt.Sprintf("%d", process.ID), signaller)
	}

	if err := c.ipTablesManager.ContainerSetup(snapshot.ID, snapshot.Resources.Bridge, snapshot.Resources.Network.IP, snapshot.Resources.Network.Subnet); err != nil {
		cLog.Error("failed-to-reenforce-network-rules", err)
		return err
	}

	for _, in := range snapshot.NetIns {
		if _, _, err := c.NetIn(in.HostPort, in.ContainerPort); err != nil {
			cLog.Error("failed-to-reenforce-port-mapping", err)
			return err
		}
	}

	for _, out := range snapshot.NetOuts {
		if err := c.NetOut(out); err != nil {
			cLog.Error("failed-to-reenforce-net-out", err)
			return err
		}
	}

	cLog.Info("restored")

	return nil
}
func (c *LinuxContainer) Restore(snapshot linux_backend.LinuxContainerSpec) error {
	cLog := c.logger.Session("restore")

	cLog.Debug("restoring")

	cRunner := logging.Runner{
		CommandRunner: c.runner,
		Logger:        cLog,
	}

	c.setState(linux_backend.State(snapshot.State))

	c.Env = snapshot.Env

	for _, ev := range snapshot.Events {
		c.registerEvent(ev)
	}

	if snapshot.Limits.Memory != nil {
		err := c.LimitMemory(*snapshot.Limits.Memory)
		if err != nil {
			cLog.Error("failed-to-limit-memory", err)
			return err
		}
	}

	signaller := c.processSignaller()

	for _, process := range snapshot.Processes {
		cLog.Info("restoring-process", lager.Data{
			"process": process,
		})

		c.processIDPool.Restore(process.ID)
		c.processTracker.Restore(process.ID, signaller)
	}

	net := exec.Command(path.Join(c.ContainerPath, "net.sh"), "setup")

	if err := cRunner.Run(net); err != nil {
		cLog.Error("failed-to-reenforce-network-rules", err)
		return err
	}

	for _, in := range snapshot.NetIns {
		if _, _, err := c.NetIn(in.HostPort, in.ContainerPort); err != nil {
			cLog.Error("failed-to-reenforce-port-mapping", err)
			return err
		}
	}

	for _, out := range snapshot.NetOuts {
		if err := c.NetOut(out); err != nil {
			cLog.Error("failed-to-reenforce-net-out", err)
			return err
		}
	}

	cLog.Info("restored")

	return nil
}
Example #3
0
func (p *LinuxResourcePool) Restore(snapshot io.Reader) (linux_backend.LinuxContainerSpec, error) {
	var containerSnapshot linux_container.ContainerSnapshot

	err := json.NewDecoder(snapshot).Decode(&containerSnapshot)
	if err != nil {
		return linux_backend.LinuxContainerSpec{}, err
	}

	id := containerSnapshot.ID
	rLog := p.logger.Session("restore", lager.Data{
		"id": id,
	})

	rLog.Debug("restoring")

	resources := containerSnapshot.Resources
	subnetLogger := rLog.Session("subnet-pool")

	if err = p.subnetPool.Remove(resources.Network, subnetLogger); err != nil {
		return linux_backend.LinuxContainerSpec{}, err
	}

	if err = p.bridges.Rereserve(resources.Bridge, resources.Network.Subnet, id); err != nil {
		p.subnetPool.Release(resources.Network, subnetLogger)
		return linux_backend.LinuxContainerSpec{}, err
	}

	for _, port := range resources.Ports {
		err = p.portPool.Remove(port)
		if err != nil {
			p.subnetPool.Release(resources.Network, subnetLogger)

			for _, port := range resources.Ports {
				p.portPool.Release(port)
			}

			return linux_backend.LinuxContainerSpec{}, err
		}
	}

	version, err := p.restoreContainerVersion(id)
	if err != nil {
		return linux_backend.LinuxContainerSpec{}, err
	}

	spec := linux_backend.LinuxContainerSpec{
		ID:                  id,
		ContainerPath:       path.Join(p.depotPath, id),
		ContainerRootFSPath: containerSnapshot.RootFSPath,

		State:  linux_backend.State(containerSnapshot.State),
		Events: containerSnapshot.Events,
		ContainerSpec: garden.ContainerSpec{
			Handle:     containerSnapshot.Handle,
			GraceTime:  containerSnapshot.GraceTime,
			Properties: containerSnapshot.Properties,
		},

		Resources: linux_backend.NewResources(
			resources.RootUID,
			resources.Network,
			resources.Bridge,
			resources.Ports,
			p.externalIP,
		),

		Limits:    containerSnapshot.Limits,
		NetIns:    containerSnapshot.NetIns,
		NetOuts:   containerSnapshot.NetOuts,
		Processes: containerSnapshot.Processes,
		Version:   version,
	}

	return spec, nil
}
				))

			})
		})
	})

	Describe("Restoring", func() {
		It("sets the container's state and events", func() {
			err := container.Restore(linux_backend.LinuxContainerSpec{
				State:     "active",
				Events:    []string{"out of memory", "foo"},
				Resources: containerResources,
			})
			Expect(err).ToNot(HaveOccurred())

			Expect(container.State()).To(Equal(linux_backend.State("active")))
			Expect(container.Events()).To(Equal([]string{
				"out of memory",
				"foo",
			}))

		})

		It("restores process state", func() {
			err := container.Restore(linux_backend.LinuxContainerSpec{
				State:     "active",
				Events:    []string{},
				Resources: containerResources,

				Processes: []linux_backend.ActiveProcess{
					{