Beispiel #1
0
func (s *WardenServer) streamProcessToConnection(processID uint32, stream <-chan warden.ProcessStream, conn net.Conn) proto.Message {
	for payload := range stream {
		if payload.ExitStatus != nil {
			return &protocol.ProcessPayload{
				ProcessId:  proto.Uint32(processID),
				ExitStatus: proto.Uint32(*payload.ExitStatus),
			}
		}

		var payloadSource protocol.ProcessPayload_Source

		switch payload.Source {
		case warden.ProcessStreamSourceStdout:
			payloadSource = protocol.ProcessPayload_stdout
		case warden.ProcessStreamSourceStderr:
			payloadSource = protocol.ProcessPayload_stderr
		case warden.ProcessStreamSourceStdin:
			payloadSource = protocol.ProcessPayload_stdin
		}

		protocol.Messages(&protocol.ProcessPayload{
			ProcessId: proto.Uint32(processID),
			Source:    &payloadSource,
			Data:      proto.String(string(payload.Data)),
		}).WriteTo(conn)
	}

	return nil
}
Beispiel #2
0
func (s *WardenServer) handleRun(conn net.Conn, request *protocol.RunRequest) (proto.Message, error) {
	handle := request.GetHandle()
	script := request.GetScript()
	privileged := request.GetPrivileged()
	env := request.GetEnv()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	ProcessSpec := warden.ProcessSpec{
		Script:               script,
		Privileged:           privileged,
		EnvironmentVariables: convertEnvironmentVariables(env),
	}

	if request.Rlimits != nil {
		ProcessSpec.Limits = resourceLimits(request.Rlimits)
	}

	processID, stream, err := container.Run(ProcessSpec)
	if err != nil {
		return nil, err
	}

	protocol.Messages(&protocol.ProcessPayload{
		ProcessId: proto.Uint32(processID),
	}).WriteTo(conn)

	return s.streamProcessToConnection(processID, stream, conn), nil
}
func (s *WardenServer) handleSpawn(request *protocol.SpawnRequest) (proto.Message, error) {
	handle := request.GetHandle()
	script := request.GetScript()
	privileged := request.GetPrivileged()
	discardOutput := request.GetDiscardOutput()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	jobSpec := backend.JobSpec{
		Script:        script,
		Privileged:    privileged,
		DiscardOutput: discardOutput,
		AutoLink:      true,
	}

	if request.Rlimits != nil {
		jobSpec.Limits = resourceLimits(request.Rlimits)
	}

	jobID, err := container.Spawn(jobSpec)
	if err != nil {
		return nil, err
	}

	return &protocol.SpawnResponse{JobId: proto.Uint32(jobID)}, nil
}
Beispiel #4
0
func (s *WardenServer) handleNetIn(request *protocol.NetInRequest) (proto.Message, error) {
	handle := request.GetHandle()
	hostPort := request.GetHostPort()
	containerPort := request.GetContainerPort()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	hostPort, containerPort, err = container.NetIn(hostPort, containerPort)
	if err != nil {
		return nil, err
	}

	return &protocol.NetInResponse{
		HostPort:      proto.Uint32(hostPort),
		ContainerPort: proto.Uint32(containerPort),
	}, nil
}
Beispiel #5
0
func (c *Connection) Link(handle string, jobID uint32) (*warden.LinkResponse, error) {
	res, err := c.RoundTrip(
		&warden.LinkRequest{
			Handle: proto.String(handle),
			JobId:  proto.Uint32(jobID),
		},
		&warden.LinkResponse{},
	)

	if err != nil {
		return nil, err
	}

	return res.(*warden.LinkResponse), nil
}
func (f *FakeGordon) Run(handle string, script string) (*warden.RunResponse, error) {
	f.lock.Lock()
	defer f.lock.Unlock()

	f.scriptsThatRan = append(f.scriptsThatRan, &RunningScript{
		Handle: handle,
		Script: script,
	})

	for ro, cb := range f.runCallbacks {
		if ro.Handle == handle && ro.Script == script {
			return cb()
		}
	}

	return &warden.RunResponse{ExitStatus: proto.Uint32(f.runReturnStatusCode)}, f.runReturnError
}
func (s *WardenServer) handleRun(request *protocol.RunRequest) (proto.Message, error) {
	handle := request.GetHandle()
	script := request.GetScript()
	privileged := request.GetPrivileged()
	discardOutput := request.GetDiscardOutput()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	jobSpec := backend.JobSpec{
		Script:        script,
		Privileged:    privileged,
		DiscardOutput: discardOutput,
		AutoLink:      false,
	}

	if request.Rlimits != nil {
		jobSpec.Limits = resourceLimits(request.Rlimits)
	}

	jobID, err := container.Spawn(jobSpec)
	if err != nil {
		return nil, err
	}

	jobResult, err := container.Link(jobID)
	if err != nil {
		return nil, err
	}

	return &protocol.RunResponse{
		ExitStatus: proto.Uint32(jobResult.ExitStatus),
		Stdout:     proto.String(string(jobResult.Stdout)),
		Stderr:     proto.String(string(jobResult.Stderr)),
	}, nil
}
Beispiel #8
0
func (c *Connection) Stream(handle string, jobId uint32) (chan *warden.StreamResponse, chan bool, error) {
	err := c.sendMessage(
		&warden.StreamRequest{
			Handle: proto.String(handle),
			JobId:  proto.Uint32(jobId),
		},
	)

	if err != nil {
		return nil, nil, err
	}

	responses := make(chan *warden.StreamResponse)

	streamDone := make(chan bool)

	go func() {
		for {
			resMsg, err := c.readResponse(&warden.StreamResponse{})
			if err != nil {
				close(responses)
				close(streamDone)
				break
			}

			response := resMsg.(*warden.StreamResponse)

			responses <- response

			if response.ExitStatus != nil {
				close(responses)
				close(streamDone)
				break
			}
		}
	}()

	return responses, streamDone, nil
}
func (s *WardenServer) handleLink(link *protocol.LinkRequest) (proto.Message, error) {
	handle := link.GetHandle()
	jobID := link.GetJobId()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	jobResult, err := container.Link(jobID)
	if err != nil {
		return nil, err
	}

	return &protocol.LinkResponse{
		ExitStatus: proto.Uint32(jobResult.ExitStatus),
		Stdout:     proto.String(string(jobResult.Stdout)),
		Stderr:     proto.String(string(jobResult.Stderr)),
	}, nil
}
func (s *WardenServer) handleStream(conn net.Conn, request *protocol.StreamRequest) (proto.Message, error) {
	handle := request.GetHandle()
	jobID := request.GetJobId()

	container, err := s.backend.Lookup(handle)
	if err != nil {
		return nil, err
	}

	s.bomberman.Pause(container.Handle())
	defer s.bomberman.Unpause(container.Handle())

	stream, err := container.Stream(jobID)
	if err != nil {
		return nil, err
	}

	var response proto.Message

	for chunk := range stream {
		if chunk.ExitStatus != nil {
			response = &protocol.StreamResponse{
				ExitStatus: proto.Uint32(*chunk.ExitStatus),
			}

			break
		}

		protocol.Messages(&protocol.StreamResponse{
			Name: proto.String(chunk.Name),
			Data: proto.String(string(chunk.Data)),
		}).WriteTo(conn)
	}

	return response, nil
}
Beispiel #11
0
				Properties: map[string]string{
					"foo": "bar",
				},
			})
			Ω(err).ShouldNot(HaveOccurred())
			Ω(handle).Should(Equal("foohandle"))

			ro := protocol.CreateRequest_BindMount_RO
			rw := protocol.CreateRequest_BindMount_RW

			hostOrigin := protocol.CreateRequest_BindMount_Host
			containerOrigin := protocol.CreateRequest_BindMount_Container

			assertWriteBufferContains(&protocol.CreateRequest{
				Handle:    proto.String("some-handle"),
				GraceTime: proto.Uint32(10),
				Rootfs:    proto.String("some-rootfs-path"),
				Network:   proto.String("some-network"),
				BindMounts: []*protocol.CreateRequest_BindMount{
					{
						SrcPath: proto.String("/src-a"),
						DstPath: proto.String("/dst-a"),
						Mode:    &ro,
						Origin:  &hostOrigin,
					},
					{
						SrcPath: proto.String("/src-b"),
						DstPath: proto.String("/dst-b"),
						Mode:    &rw,
						Origin:  &containerOrigin,
					},
Beispiel #12
0
// InitChecksum initializes a checksum based on the provided key and
// the contents of the value. If the value contains a byte slice, the
// checksum includes it directly; if the value contains an integer,
// the checksum includes the integer as 8 bytes in big-endian order.
func (v *Value) InitChecksum(key []byte) {
	if v.Checksum == nil {
		v.Checksum = gogoproto.Uint32(v.computeChecksum(key))
	}
}
				wardenServer.Stop()

				Expect(time.Since(before)).To(BeNumerically(">", 50*time.Millisecond))

				readResponse(&protocol.CreateResponse{})

				_, err := protocol.Messages(&protocol.PingRequest{}).WriteTo(serverConnection)
				Expect(err).To(HaveOccurred())
			})
		})

		dontWaitRequests := []proto.Message{
			&protocol.LinkRequest{
				Handle: proto.String("some-handle"),
				JobId:  proto.Uint32(1),
			},
			&protocol.StreamRequest{
				Handle: proto.String("some-handle"),
				JobId:  proto.Uint32(1),
			},
			&protocol.RunRequest{
				Handle: proto.String("some-handle"),
				Script: proto.String("some-script"),
			},
		}

		for _, req := range dontWaitRequests {
			request := req

			Context(fmt.Sprintf("when a %T request is in-flight", request), func() {
Beispiel #14
0
				readResponse(&protocol.CreateResponse{})

				_, err := protocol.Messages(&protocol.PingRequest{}).WriteTo(serverConnection)
				Expect(err).To(HaveOccurred())
			})
		})

		dontWaitRequests := []proto.Message{
			&protocol.RunRequest{
				Handle: proto.String("some-handle"),
				Script: proto.String("some-script"),
			},
			&protocol.AttachRequest{
				Handle:    proto.String("some-handle"),
				ProcessId: proto.Uint32(1),
			},
		}

		for _, req := range dontWaitRequests {
			request := req

			Context(fmt.Sprintf("when a %T request is in-flight", request), func() {
				BeforeEach(func() {
					serverBackend = fake_backend.NewSlow(100 * time.Millisecond)

					container, err := serverBackend.Create(warden.ContainerSpec{Handle: "some-handle"})
					Expect(err).ToNot(HaveOccurred())

					exitStatus := uint32(42)
					Background: proto.Bool(true),
					Kill:       proto.Bool(true),
				},
				&warden.DestroyRequest{Handle: proto.String("foo")},
			).Bytes())

			Ω(string(writeBuffer.Bytes())).Should(Equal(expectedWriteBufferContents))
		})
	})

	Describe("Spawning and streaming", func() {
		BeforeEach(func() {
			provider = NewFakeConnectionProvider(
				warden.Messages(
					&warden.SpawnResponse{
						JobId: proto.Uint32(42),
					},
					&warden.StreamResponse{
						Name: proto.String("stdout"),
						Data: proto.String("some data for stdout"),
					},
				),
				writeBuffer,
			)

			client = NewClient(provider)
			err := client.Connect()
			Ω(err).ShouldNot(HaveOccurred())
		})

		It("should spawn and stream succesfully", func(done Done) {
			It("should return the correct memory format", func() {
				diskLimit, err := connection.GetDiskLimit("foo")
				Ω(err).ShouldNot(HaveOccurred())
				Ω(diskLimit).Should(BeNumerically("==", 40))

				assertWriteBufferContains(&warden.LimitDiskRequest{
					Handle: proto.String("foo"),
				})
			})
		})
	})

	Describe("Spawning", func() {
		BeforeEach(func() {
			wardenMessages = append(wardenMessages,
				&warden.SpawnResponse{JobId: proto.Uint32(42)},
				&warden.SpawnResponse{JobId: proto.Uint32(43)},
			)
		})

		It("should be able to spawn multiple jobs sequentially", func() {
			resp, err := connection.Spawn("foo-handle", "echo hi", true)
			Ω(err).ShouldNot(HaveOccurred())
			Ω(resp.GetJobId()).Should(BeNumerically("==", 42))

			assertWriteBufferContains(&warden.SpawnRequest{
				Handle:        proto.String("foo-handle"),
				Script:        proto.String("echo hi"),
				DiscardOutput: proto.Bool(true),
			})