Beispiel #1
0
// VolumeCreate : docker personality implementation for VIC
func (v *Volume) VolumeCreate(name, driverName string, volumeData, labels map[string]string) (*types.Volume, error) {
	defer trace.End(trace.Begin("Volume.VolumeCreate"))

	result, err := v.volumeCreate(name, driverName, volumeData, labels)
	if err != nil {
		switch err := err.(type) {
		case *storage.CreateVolumeConflict:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("A volume named %s already exists. Choose a different volume name.", name), http.StatusInternalServerError)

		case *storage.CreateVolumeNotFound:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("No volume store named (%s) exists", volumeStore(volumeData)), http.StatusInternalServerError)

		case *storage.CreateVolumeInternalServerError:
			// FIXME: right now this does not return an error model...
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err.Error()), http.StatusInternalServerError)

		case *storage.CreateVolumeDefault:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err.Payload.Message), http.StatusInternalServerError)

		default:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err), http.StatusInternalServerError)
		}
	}

	return result, nil
}
Beispiel #2
0
// Use the Portlayer's support for docker ps to get the container count
//   return order: running, paused, stopped counts
func (s *SystemProxy) ContainerCount() (int, int, int, error) {
	defer trace.End(trace.Begin("ContainerCount"))

	var running, paused, stopped int

	plClient := PortLayerClient()
	if plClient == nil {
		return 0, 0, 0, derr.NewErrorWithStatusCode(fmt.Errorf("ContainerCount failed to create a portlayer client"),
			http.StatusInternalServerError)
	}

	all := true
	containList, err := plClient.Containers.GetContainerList(containers.NewGetContainerListParamsWithContext(ctx).WithAll(&all))
	if err != nil {
		return 0, 0, 0, derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get container list: %s", err), http.StatusInternalServerError)
	}

	for _, t := range containList.Payload {
		if *t.ContainerConfig.State == "Running" {
			running++
		} else if *t.ContainerConfig.State == "Stopped" || *t.ContainerConfig.State == "Created" {
			stopped++
		}
	}

	return running, paused, stopped, nil
}
Beispiel #3
0
// VolumeRm : docker personality for VIC
func (v *Volume) VolumeRm(name string) error {
	defer trace.End(trace.Begin("Volume.VolumeRm"))

	client := PortLayerClient()
	if client == nil {
		return derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get a portlayer client"), http.StatusInternalServerError)
	}

	// FIXME: check whether this is a name or a UUID. UUID expected for now.
	_, err := client.Storage.RemoveVolume(storage.NewRemoveVolumeParamsWithContext(ctx).WithName(name))
	if err != nil {

		switch err := err.(type) {
		case *storage.RemoveVolumeNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf("Get %s: no such volume", name))

		case *storage.RemoveVolumeConflict:
			return derr.NewRequestConflictError(fmt.Errorf(err.Payload.Message))

		case *storage.RemoveVolumeInternalServerError:
			return derr.NewErrorWithStatusCode(fmt.Errorf("Server error from portlayer: %s", err.Payload.Message), http.StatusInternalServerError)
		default:
			return derr.NewErrorWithStatusCode(fmt.Errorf("Server error from portlayer: %s", err), http.StatusInternalServerError)
		}
	}
	return nil
}
Beispiel #4
0
// Volumes docker personality implementation for VIC
func (v *Volume) Volumes(filter string) ([]*types.Volume, []string, error) {
	defer trace.End(trace.Begin("Volume.Volumes"))
	var volumes []*types.Volume

	client := PortLayerClient()
	if client == nil {
		return nil, nil, derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get a portlayer client"), http.StatusInternalServerError)
	}

	res, err := client.Storage.ListVolumes(storage.NewListVolumesParamsWithContext(ctx).WithFilterString(&filter))
	if err != nil {
		switch err := err.(type) {
		case *storage.ListVolumesInternalServerError:
			return nil, nil, derr.NewErrorWithStatusCode(fmt.Errorf("error from portlayer server: %s", err.Payload.Message), http.StatusInternalServerError)
		case *storage.ListVolumesDefault:
			return nil, nil, derr.NewErrorWithStatusCode(fmt.Errorf("error from portlayer server: %s", err.Payload.Message), http.StatusInternalServerError)
		default:
			return nil, nil, derr.NewErrorWithStatusCode(fmt.Errorf("error from portlayer server: %s", err.Error()), http.StatusInternalServerError)
		}
	}

	volumeResponses := res.Payload

	log.Infoln("volumes found: ")
	for _, vol := range volumeResponses {
		log.Infof("%s", vol.Name)
		volumeMetadata, err := extractDockerMetadata(vol.Metadata)
		if err != nil {
			return nil, nil, fmt.Errorf("error unmarshalling docker metadata: %s", err)
		}
		volume := NewVolumeModel(vol, volumeMetadata.Labels)
		volumes = append(volumes, volume)
	}
	return volumes, nil, nil
}
Beispiel #5
0
// VolumeInspect : docker personality implementation for VIC
func (v *Volume) VolumeInspect(name string) (*types.Volume, error) {
	defer trace.End(trace.Begin(name))

	client := PortLayerClient()
	if client == nil {
		return nil, fmt.Errorf("failed to get a portlayer client")
	}

	if name == "" {
		return nil, nil
	}

	param := storage.NewGetVolumeParamsWithContext(ctx).WithName(name)
	res, err := client.Storage.GetVolume(param)
	if err != nil {
		switch err := err.(type) {
		case *storage.GetVolumeNotFound:
			return nil, VolumeNotFoundError(name)
		default:
			return nil, derr.NewErrorWithStatusCode(fmt.Errorf("error from portlayer server: %s", err.Error()), http.StatusInternalServerError)
		}
	}

	volumeMetadata, err := extractDockerMetadata(res.Payload.Metadata)
	if err != nil {
		return nil, derr.NewErrorWithStatusCode(fmt.Errorf("error unmarshalling docker metadata: %s", err), http.StatusInternalServerError)
	}
	volume := NewVolumeModel(res.Payload, volumeMetadata.Labels)

	return volume, nil
}
Beispiel #6
0
// ContainerRunning returns true if the given container is running
func (c *ContainerProxy) ContainerRunning(vc *viccontainer.VicContainer) (bool, error) {
	defer trace.End(trace.Begin(""))

	if c.client == nil {
		return false, derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.CommitContainerHandle failed to create a portlayer client"),
			http.StatusInternalServerError)
	}

	results, err := c.client.Containers.GetContainerInfo(containers.NewGetContainerInfoParamsWithContext(ctx).WithID(vc.ContainerID))
	if err != nil {
		switch err := err.(type) {
		case *containers.GetContainerInfoNotFound:
			return false, derr.NewRequestNotFoundError(fmt.Errorf("No such container: %s", vc.ContainerID))
		case *containers.GetContainerInfoInternalServerError:
			return false, derr.NewErrorWithStatusCode(fmt.Errorf("Error from portlayer: %#v", err.Payload), http.StatusInternalServerError)
		default:
			return false, derr.NewErrorWithStatusCode(fmt.Errorf("Unknown error from the container portlayer"), http.StatusInternalServerError)
		}
	}

	inspectJSON, err := ContainerInfoToDockerContainerInspect(vc, results.Payload, c.portlayerName)
	if err != nil {
		log.Errorf("containerInfoToDockerContainerInspect failed with %s", err)
		return false, err
	}

	return inspectJSON.State.Running, nil
}
Beispiel #7
0
//VolumeCreate : docker personality implementation for VIC
func (v *Volume) VolumeCreate(name, driverName string, opts, labels map[string]string) (*types.Volume, error) {
	defer trace.End(trace.Begin("Volume.VolumeCreate"))
	result := &types.Volume{}

	//TODO: design a way to have better error returns.

	client := PortLayerClient()
	if client == nil {
		return nil, derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get a portlayer client"), http.StatusInternalServerError)
	}

	//TODO: support having another driver besides vsphere.
	//assign the values of the model to be passed to the portlayer handler
	model, varErr := translateInputsToPortlayerRequestModel(name, driverName, opts, labels)
	if varErr != nil {
		return result, derr.NewErrorWithStatusCode(fmt.Errorf("Bad Driver Arg: %s", varErr), http.StatusBadRequest)
	}

	//TODO: setup name randomization if name == nil

	res, err := client.Storage.CreateVolume(storage.NewCreateVolumeParams().WithVolumeRequest(&model))
	if err != nil {
		return result, derr.NewErrorWithStatusCode(fmt.Errorf("Server error from Portlayer: %s", err), http.StatusInternalServerError)
	}

	result = fillDockerVolumeModel(res.Payload, labels)
	return result, nil
}
Beispiel #8
0
func MockAddToScopeData() []AddToScopeMockData {
	addToScopeNotFound := plscopes.AddContainerNotFound{
		Payload: &plmodels.Error{
			Message: "Scope not found",
		},
	}

	addToScopeNotFoundErr := fmt.Errorf("ContainerProxy.AddContainerToScope: Scopes error: %s", addToScopeNotFound.Error())

	addToScopeTimeout := plscopes.AddContainerInternalServerError{
		Payload: &plmodels.Error{
			Message: "context deadline exceeded",
		},
	}

	addToScopeTimeoutErr := fmt.Errorf("ContainerProxy.AddContainerToScope: Scopes error: %s", addToScopeTimeout.Error())

	mockAddToScopeData := []AddToScopeMockData{
		{"busybox", "handle", nil, ""},
		{"busybox", "handle", derr.NewErrorWithStatusCode(fmt.Errorf("container.ContainerCreate failed to create a portlayer client"), http.StatusInternalServerError), "failed to create a portlayer"},
		{"busybox", "handle", derr.NewErrorWithStatusCode(addToScopeNotFoundErr, http.StatusInternalServerError), "Scope not found"},
		{"busybox", "handle", derr.NewErrorWithStatusCode(addToScopeTimeoutErr, http.StatusInternalServerError), "context deadline exceeded"},
	}

	return mockAddToScopeData
}
Beispiel #9
0
func (n *Network) CreateNetwork(name, driver string, ipam apinet.IPAM, options map[string]string, labels map[string]string, internal bool, enableIPv6 bool) (libnetwork.Network, error) {
	if len(ipam.Config) > 1 {
		return nil, fmt.Errorf("at most one ipam config supported")
	}

	var gateway, subnet *string
	var pools []string
	if len(ipam.Config) > 0 {
		if ipam.Config[0].Gateway != "" {
			gateway = new(string)
			*gateway = ipam.Config[0].Gateway
		}

		if ipam.Config[0].Subnet != "" {
			subnet = new(string)
			*subnet = ipam.Config[0].Subnet
		}

		if ipam.Config[0].IPRange != "" {
			pools = append(pools, ipam.Config[0].IPRange)
		}
	}

	if driver == "" {
		driver = "bridge"
	}

	cfg := &models.ScopeConfig{
		Gateway:   gateway,
		Name:      name,
		ScopeType: driver,
		Subnet:    subnet,
		IPAM:      pools,
	}

	created, err := PortLayerClient().Scopes.CreateScope(scopes.NewCreateScopeParamsWithContext(ctx).WithConfig(cfg))
	if err != nil {
		switch err := err.(type) {
		case *scopes.CreateScopeConflict:
			return nil, derr.NewErrorWithStatusCode(fmt.Errorf("network %s already exists", name), http.StatusConflict)

		case *scopes.CreateScopeDefault:
			return nil, derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return nil, derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	return &network{cfg: created.Payload}, nil
}
Beispiel #10
0
func (n *Network) GetNetworkByName(idName string) (libnetwork.Network, error) {
	ok, err := PortLayerClient().Scopes.List(scopes.NewListParamsWithContext(ctx).WithIDName(idName))
	if err != nil {
		switch err := err.(type) {
		case *scopes.ListNotFound:
			return nil, nil

		case *scopes.ListDefault:
			return nil, derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return nil, derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	return &network{cfg: ok.Payload[0]}, nil
}
Beispiel #11
0
// ContainerStart starts a container.
func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig) error {
	container, err := daemon.GetContainer(name)
	if err != nil {
		return err
	}

	if container.IsPaused() {
		return fmt.Errorf("Cannot start a paused container, try unpause instead.")
	}

	if container.IsRunning() {
		err := fmt.Errorf("Container already started")
		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
	}

	// Windows does not have the backwards compatibility issue here.
	if runtime.GOOS != "windows" {
		// This is kept for backward compatibility - hostconfig should be passed when
		// creating a container, not during start.
		if hostConfig != nil {
			logrus.Warn("DEPRECATED: Setting host configuration options when the container starts is deprecated and will be removed in Docker 1.12")
			oldNetworkMode := container.HostConfig.NetworkMode
			if err := daemon.setSecurityOptions(container, hostConfig); err != nil {
				return err
			}
			if err := daemon.setHostConfig(container, hostConfig); err != nil {
				return err
			}
			newNetworkMode := container.HostConfig.NetworkMode
			if string(oldNetworkMode) != string(newNetworkMode) {
				// if user has change the network mode on starting, clean up the
				// old networks. It is a deprecated feature and will be removed in Docker 1.12
				container.NetworkSettings.Networks = nil
				if err := container.ToDisk(); err != nil {
					return err
				}
			}
			container.InitDNSHostConfig()
		}
	} else {
		if hostConfig != nil {
			return fmt.Errorf("Supplying a hostconfig on start is not supported. It should be supplied on create")
		}
	}

	// check if hostConfig is in line with the current system settings.
	// It may happen cgroups are umounted or the like.
	if _, err = daemon.verifyContainerSettings(container.HostConfig, nil, false); err != nil {
		return err
	}
	// Adapt for old containers in case we have updates in this function and
	// old containers never have chance to call the new function in create stage.
	if err := daemon.adaptContainerSettings(container.HostConfig, false); err != nil {
		return err
	}

	return daemon.containerStart(container)
}
Beispiel #12
0
func (n *Network) DeleteNetwork(name string) error {
	client := PortLayerClient()

	if _, err := client.Scopes.DeleteScope(scopes.NewDeleteScopeParamsWithContext(ctx).WithIDName(name)); err != nil {
		switch err := err.(type) {
		case *scopes.DeleteScopeNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf("network %s not found", name))

		case *scopes.DeleteScopeInternalServerError:
			return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	return nil
}
Beispiel #13
0
func (s *SystemProxy) VCHInfo() (*models.VCHInfo, error) {
	defer trace.End(trace.Begin("VCHInfo"))

	plClient := PortLayerClient()
	if plClient == nil {
		return nil, derr.NewErrorWithStatusCode(fmt.Errorf("VCHInfo failed to create a portlayer client"),
			http.StatusInternalServerError)
	}

	params := misc.NewGetVCHInfoParamsWithContext(ctx)
	resp, err := plClient.Misc.GetVCHInfo(params)
	if err != nil {
		//There are no custom error for this operation.  If we get back an error, it's
		//unknown.
		return nil, derr.NewErrorWithStatusCode(fmt.Errorf("Unknown error from port layer: %s", err),
			http.StatusInternalServerError)
	}

	return resp.Payload, nil
}
Beispiel #14
0
func MockCommitData() []CommitHandleMockData {
	noSuchImageErr := fmt.Errorf("No such image: busybox")

	mockCommitData := []CommitHandleMockData{
		{"buxybox", "", nil},
		{"busybox", "failed to create a portlayer", derr.NewErrorWithStatusCode(fmt.Errorf("container.ContainerCreate failed to create a portlayer client"), http.StatusInternalServerError)},
		{"busybox", "No such image", derr.NewRequestNotFoundError(noSuchImageErr)},
	}

	return mockCommitData
}
Beispiel #15
0
func MockCreateHandleData() []CreateHandleMockData {
	createHandleTimeoutErr := client.NewAPIError("unknown error", "context deadline exceeded", http.StatusServiceUnavailable)

	mockCreateHandleData := []CreateHandleMockData{
		{"busybox", "321cba", "handle", nil, ""},
		{"busybox", "", "", derr.NewRequestNotFoundError(fmt.Errorf("No such image: abc123")), "No such image"},
		{"busybox", "", "", derr.NewErrorWithStatusCode(createHandleTimeoutErr, http.StatusInternalServerError), "context deadline exceeded"},
	}

	return mockCreateHandleData
}
Beispiel #16
0
// CreateContainerHandle creates a new VIC container by calling the portlayer
//
// returns:
// 	(containerID, containerHandle, error)
func (c *ContainerProxy) CreateContainerHandle(imageID string, config types.ContainerCreateConfig) (string, string, error) {
	defer trace.End(trace.Begin(imageID))

	if c.client == nil {
		return "", "",
			derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.CreateContainerHandle failed to create a portlayer client"),
				http.StatusInternalServerError)
	}

	if imageID == "" {
		return "", "",
			derr.NewRequestNotFoundError(fmt.Errorf("No image specified"))
	}

	// Call the Exec port layer to create the container
	host, err := sys.UUID()
	if err != nil {
		return "", "",
			derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.CreateContainerHandle got unexpected error getting VCH UUID"),
				http.StatusInternalServerError)
	}

	plCreateParams := dockerContainerCreateParamsToPortlayer(config, imageID, host)
	createResults, err := c.client.Containers.Create(plCreateParams)
	if err != nil {
		if _, ok := err.(*containers.CreateNotFound); ok {
			cerr := fmt.Errorf("No such image: %s", imageID)
			log.Errorf("%s (%s)", cerr, err)
			return "", "", derr.NewRequestNotFoundError(cerr)
		}

		// If we get here, most likely something went wrong with the port layer API server
		return "", "",
			derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
	}

	id := createResults.Payload.ID
	h := createResults.Payload.Handle

	return id, h, nil
}
Beispiel #17
0
//VolumeRm : docker personality for VIC
func (v *Volume) VolumeRm(name string) error {
	defer trace.End(trace.Begin("Volume.VolumeRm"))

	client := PortLayerClient()
	if client == nil {
		return derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get a portlayer client"), http.StatusInternalServerError)
	}

	//FIXME: check whether this is a name or a UUID. UUID expected for now.
	_, err := client.Storage.RemoveVolume(storage.NewRemoveVolumeParams().WithName(name))
	if err != nil {
		if _, ok := err.(*storage.RemoveVolumeNotFound); ok {
			return derr.NewRequestNotFoundError(fmt.Errorf("Get %s: no such volume", name))
		}
		if _, ok := err.(*storage.RemoveVolumeConflict); ok {
			return derr.NewRequestConflictError(fmt.Errorf("Volume is in use"))
		}
		return derr.NewErrorWithStatusCode(fmt.Errorf("Server error from portlayer: %s", err), http.StatusInternalServerError)
	}
	return nil
}
Beispiel #18
0
// AddContainerToScope adds a container, referenced by handle, to a scope.
// If an error is return, the returned handle should not be used.
//
// returns:
//	modified handle
func (c *ContainerProxy) AddContainerToScope(handle string, config types.ContainerCreateConfig) (string, error) {
	defer trace.End(trace.Begin(handle))

	if c.client == nil {
		return "",
			derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.AddContainerToScope failed to create a portlayer client"),
				http.StatusInternalServerError)
	}

	log.Debugf("Network Configuration Section - Container Create")
	// configure networking
	netConf := toModelsNetworkConfig(config)
	if netConf != nil {
		addContRes, err := c.client.Scopes.AddContainer(scopes.NewAddContainerParamsWithContext(ctx).
			WithScope(netConf.NetworkName).
			WithConfig(&models.ScopesAddContainerConfig{
				Handle:        handle,
				NetworkConfig: netConf,
			}))

		if err != nil {
			log.Errorf("ContainerProxy.AddContainerToScope: Scopes error: %s", err.Error())
			return handle, derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}

		defer func() {
			if err == nil {
				return
			}
			// roll back the AddContainer call
			if _, err2 := c.client.Scopes.RemoveContainer(scopes.NewRemoveContainerParamsWithContext(ctx).WithHandle(handle).WithScope(netConf.NetworkName)); err2 != nil {
				log.Warnf("could not roll back container add: %s", err2)
			}
		}()

		handle = addContRes.Payload
	}

	return handle, nil
}
Beispiel #19
0
// CreateNetwork creates a network with the given name, driver and other optional parameters
func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) {
	if runconfig.IsPreDefinedNetwork(create.Name) {
		err := fmt.Errorf("%s is a pre-defined network and cannot be created", create.Name)
		return nil, errors.NewErrorWithStatusCode(err, http.StatusForbidden)
	}

	var warning string
	nw, err := daemon.GetNetworkByName(create.Name)
	if err != nil {
		if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
			return nil, err
		}
	}
	if nw != nil {
		if create.CheckDuplicate {
			return nil, libnetwork.NetworkNameError(create.Name)
		}
		warning = fmt.Sprintf("Network with name %s (id : %s) already exists", nw.Name(), nw.ID())
	}

	c := daemon.netController
	driver := create.Driver
	if driver == "" {
		driver = c.Config().Daemon.DefaultDriver
	}

	ipam := create.IPAM
	v4Conf, v6Conf, err := getIpamConfig(ipam.Config)
	if err != nil {
		return nil, err
	}

	nwOptions := []libnetwork.NetworkOption{
		libnetwork.NetworkOptionIpam(ipam.Driver, "", v4Conf, v6Conf, ipam.Options),
		libnetwork.NetworkOptionEnableIPv6(create.EnableIPv6),
		libnetwork.NetworkOptionDriverOpts(create.Options),
		libnetwork.NetworkOptionLabels(create.Labels),
	}
	if create.Internal {
		nwOptions = append(nwOptions, libnetwork.NetworkOptionInternalNetwork())
	}
	n, err := c.NewNetwork(driver, create.Name, nwOptions...)
	if err != nil {
		return nil, err
	}

	daemon.LogNetworkEvent(n, "create")
	return &types.NetworkCreateResponse{
		ID:      n.ID(),
		Warning: warning,
	}, nil
}
Beispiel #20
0
// VolumeCreate : docker personality implementation for VIC
func (v *Volume) VolumeCreate(name, driverName string, opts, labels map[string]string) (*types.Volume, error) {
	defer trace.End(trace.Begin("Volume.VolumeCreate"))
	result := &types.Volume{}

	client := PortLayerClient()
	if client == nil {
		return nil, derr.NewErrorWithStatusCode(fmt.Errorf("Failed to get a portlayer client"), http.StatusInternalServerError)
	}

	// TODO: support having another driver besides vsphere.
	// assign the values of the model to be passed to the portlayer handler
	model, varErr := translateInputsToPortlayerRequestModel(name, driverName, opts, labels)
	if varErr != nil {
		return result, derr.NewErrorWithStatusCode(fmt.Errorf("Bad Driver Arg: %s", varErr), http.StatusBadRequest)
	}

	if model.Name == "" {
		model.Name = uuid.New().String()
	}

	res, err := client.Storage.CreateVolume(storage.NewCreateVolumeParamsWithContext(ctx).WithVolumeRequest(model))
	if err != nil {
		switch err := err.(type) {

		case *storage.CreateVolumeInternalServerError:
			// FIXME: right now this does not return an error model...
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err.Error()), http.StatusInternalServerError)

		case *storage.CreateVolumeDefault:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err.Payload.Message), http.StatusInternalServerError)

		default:
			return result, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err), http.StatusInternalServerError)
		}
	}

	result = NewVolumeModel(res.Payload, labels)
	return result, nil
}
Beispiel #21
0
// ContainerStop looks for the given container and terminates it,
// waiting the given number of seconds before forcefully killing the
// container. If a negative number of seconds is given, ContainerStop
// will wait for a graceful termination. An error is returned if the
// container is not found, is already stopped, or if there is a
// problem stopping the container.
func (daemon *Daemon) ContainerStop(name string, seconds int) error {
	container, err := daemon.GetContainer(name)
	if err != nil {
		return err
	}
	if !container.IsRunning() {
		err := fmt.Errorf("Container %s is already stopped", name)
		return errors.NewErrorWithStatusCode(err, http.StatusNotModified)
	}
	if err := daemon.containerStop(container, seconds); err != nil {
		return fmt.Errorf("Cannot stop container %s: %v", name, err)
	}
	return nil
}
Beispiel #22
0
// StreamContainerLogs reads the log stream from the portlayer rest server and writes
// it directly to the io.Writer that is passed in.
func (c *ContainerProxy) StreamContainerLogs(name string, out io.Writer, started chan struct{}, showTimestamps bool, followLogs bool, since int64, tailLines int64) error {
	defer trace.End(trace.Begin(""))

	plClient, transport := c.createNewAttachClientWithTimeouts(attachConnectTimeout, 0, attachAttemptTimeout)
	defer transport.Close()
	close(started)

	params := containers.NewGetContainerLogsParamsWithContext(ctx).
		WithID(name).
		WithFollow(&followLogs).
		WithTimestamp(&showTimestamps).
		WithSince(&since).
		WithTaillines(&tailLines)
	_, err := plClient.Containers.GetContainerLogs(params, out)
	if err != nil {
		switch err := err.(type) {
		case *containers.GetContainerLogsNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf("No such container: %s", name))

		case *containers.GetContainerLogsInternalServerError:
			return derr.NewErrorWithStatusCode(fmt.Errorf("Server error from the interaction port layer"),
				http.StatusInternalServerError)

		default:
			//Check for EOF.  Since the connection, transport, and data handling are
			//encapsulated inisde of Swagger, we can only detect EOF by checking the
			//error string
			if strings.Contains(err.Error(), swaggerSubstringEOF) {
				return nil
			}
			unknownErrMsg := fmt.Errorf("Unknown error from the interaction port layer: %s", err)
			return derr.NewErrorWithStatusCode(unknownErrMsg, http.StatusInternalServerError)
		}
	}

	return nil
}
Beispiel #23
0
// Update runs only once at startup to hydrate the image cache
func (ic *ICache) Update(client *client.PortLayer) error {
	log.Debugf("Updating image cache...")

	host, err := sys.UUID()
	if host == "" {
		host, err = os.Hostname()
	}
	if err != nil {
		return fmt.Errorf("Unexpected error getting hostname: %s", err)
	}

	// attempt to create the image store if it doesn't exist
	store := &models.ImageStore{Name: host}
	_, err = client.Storage.CreateImageStore(
		storage.NewCreateImageStoreParamsWithContext(ctx).WithBody(store),
	)

	if err != nil {
		if _, ok := err.(*storage.CreateImageStoreConflict); ok {
			log.Debugf("Store already exists")
		} else {
			log.Debugf("Creating a store failed: %#v", err)
			return err
		}
	}

	params := storage.NewListImagesParamsWithContext(ctx).WithStoreName(host)

	layers, err := client.Storage.ListImages(params)
	if err != nil {
		return fmt.Errorf("Failed to retrieve image list from portlayer: %s", err)
	}

	for _, layer := range layers.Payload {
		imageConfig := &metadata.ImageConfig{}
		if err := json.Unmarshal([]byte(layer.Metadata["metaData"]), imageConfig); err != nil {
			derr.NewErrorWithStatusCode(fmt.Errorf("Failed to unmarshal image config: %s", err),
				http.StatusInternalServerError)
		}

		if imageConfig.ImageID != "" {
			ic.AddImage(imageConfig)
		}
	}

	return nil
}
Beispiel #24
0
// DeleteNetwork destroys a network unless it's one of docker's predefined networks.
func (daemon *Daemon) DeleteNetwork(networkID string) error {
	nw, err := daemon.FindNetwork(networkID)
	if err != nil {
		return err
	}

	if runconfig.IsPreDefinedNetwork(nw.Name()) {
		err := fmt.Errorf("%s is a pre-defined network and cannot be removed", nw.Name())
		return errors.NewErrorWithStatusCode(err, http.StatusForbidden)
	}

	if err := nw.Delete(); err != nil {
		return err
	}
	daemon.LogNetworkEvent(nw, "destroy")
	return nil
}
Beispiel #25
0
// AddVolumesToContainer adds volumes to a container, referenced by handle.
// If an error is return, the returned handle should not be used.
//
// returns:
//	modified handle
func (c *ContainerProxy) AddVolumesToContainer(handle string, config types.ContainerCreateConfig) (string, error) {
	defer trace.End(trace.Begin(handle))

	if c.client == nil {
		return "",
			derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.AddVolumesToContainer failed to create a portlayer client"),
				http.StatusInternalServerError)
	}

	//Volume Attachment Section
	log.Debugf("ContainerProxy.AddVolumesToContainer - VolumeSection")
	log.Debugf("Raw Volume arguments : binds:  %#v : volumes : %#v", config.HostConfig.Binds, config.Config.Volumes)
	var joinList []volumeFields
	var err error

	joinList, err = processAnonymousVolumes(&handle, config.Config.Volumes, c.client)
	if err != nil {
		return handle, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err), http.StatusBadRequest)
	}

	volumeSubset, err := processSpecifiedVolumes(config.HostConfig.Binds)
	if err != nil {
		return handle, derr.NewErrorWithStatusCode(fmt.Errorf("%s", err), http.StatusBadRequest)
	}
	joinList = append(joinList, volumeSubset...)

	for _, fields := range joinList {
		flags := make(map[string]string)
		//NOTE: for now we are passing the flags directly through. This is NOT SAFE and only a stop gap.
		flags["Mode"] = fields.Flags
		joinParams := storage.NewVolumeJoinParamsWithContext(ctx).WithJoinArgs(&models.VolumeJoinConfig{
			Flags:     flags,
			Handle:    handle,
			MountPath: fields.Dest,
		}).WithName(fields.ID)

		res, err := c.client.Storage.VolumeJoin(joinParams)
		if err != nil {
			switch err := err.(type) {
			case *storage.VolumeJoinInternalServerError:
				return handle, derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)
			case *storage.VolumeJoinDefault:
				return handle, derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)
			default:
				return handle, derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
			}
		}

		handle = res.Payload
	}

	return handle, nil
}
Beispiel #26
0
// CommitContainerHandle() commits any changes to container handle.
//
func (c *ContainerProxy) CommitContainerHandle(handle, imageID string) error {
	defer trace.End(trace.Begin(handle))

	if c.client == nil {
		return derr.NewErrorWithStatusCode(fmt.Errorf("ContainerProxy.CommitContainerHandle failed to create a portlayer client"),
			http.StatusInternalServerError)
	}

	_, err := c.client.Containers.Commit(containers.NewCommitParamsWithContext(ctx).WithHandle(handle))
	if err != nil {
		cerr := fmt.Errorf("No such image: %s", imageID)
		log.Errorf("%s (%s)", cerr, err)
		// FIXME: Containers.Commit returns more errors than it's swagger spec says.
		// When no image exist, it also sends back non swagger errors.  We should fix
		// this once Commit returns correct error codes.
		return derr.NewRequestNotFoundError(cerr)
	}

	return nil
}
Beispiel #27
0
// BadRequestError returns a 400 docker error on a bad request.
func BadRequestError(msg string) error {
	return derr.NewErrorWithStatusCode(fmt.Errorf("Bad request error from portlayer: %s", msg), http.StatusBadRequest)
}
Beispiel #28
0
// Update adds new images to the cache
func (c *ImageCache) Update(client *client.PortLayer) error {
	c.m.Lock()
	defer c.m.Unlock()

	CacheNotUpdated = true

	log.Debugf("Updating image cache...")

	host, err := guest.UUID()
	if host == "" {
		host, err = os.Hostname()
	}
	if err != nil {
		return fmt.Errorf("Unexpected error getting hostname: %s", err)
	}

	// attempt to create the image store if it doesn't exist
	store := &models.ImageStore{Name: host}
	_, err = client.Storage.CreateImageStore(
		storage.NewCreateImageStoreParams().WithBody(store),
	)

	if err != nil {
		if _, ok := err.(*storage.CreateImageStoreConflict); ok {
			log.Debugf("Store already exists")
		} else {
			log.Debugf("Creating a store failed: %#v", err)
			return err
		}
	}

	params := storage.NewListImagesParams().WithStoreName(host)

	layers, err := client.Storage.ListImages(params)
	if err != nil {
		return fmt.Errorf("Failed to retrieve image list from portlayer: %s", err)
	}

	for _, layer := range layers.Payload {
		imageConfig := &metadata.ImageConfig{}
		if err := json.Unmarshal([]byte(layer.Metadata["metaData"]), imageConfig); err != nil {
			derr.NewErrorWithStatusCode(fmt.Errorf("Failed to unmarshal image config: %s", err),
				http.StatusInternalServerError)
		}

		if imageConfig.ImageID != "" {
			var imageID string

			// Don't assume the image id in image has "sha256:<id> as format.  We store it in
			// this fomat to make it easier to lookup by digest
			if strings.HasPrefix(imageConfig.ImageID, "sha") {
				imageID = imageConfig.ImageID
			} else {
				imageID = "sha256:" + imageConfig.ImageID
			}

			c.cacheByID[imageID] = imageConfig

			// Normalize the name stored in imageConfig using Docker's reference code
			ref, err := reference.WithName(imageConfig.Name)
			if err != nil {
				log.Errorf("Tried to create reference from %s: %s", imageConfig.Name, err.Error())
				continue
			}

			for id := range imageConfig.Tags {
				tag := imageConfig.Tags[id]
				ref, err = reference.WithTag(ref, tag)
				if err != nil {
					log.Errorf("Tried to create tagged reference from %s and tag %s: %s", imageConfig.Name, tag, err.Error())
					continue
				}

				if tagged, ok := ref.(reference.NamedTagged); ok {
					taggedName := fmt.Sprintf("%s:%s", tagged.Name(), tagged.Tag())
					c.cacheByName[taggedName] = imageConfig
				} else {
					c.cacheByName[ref.Name()] = imageConfig
				}
			}
		}
	}

	CacheNotUpdated = false
	return nil
}
Beispiel #29
0
package backends

import (
	"fmt"
	"net"
	"net/http"

	derr "github.com/docker/docker/errors"
	"github.com/docker/libnetwork"
	"github.com/docker/libnetwork/types"

	"github.com/vmware/vic/lib/apiservers/portlayer/models"
)

var notImplementedError = derr.NewErrorWithStatusCode(fmt.Errorf("not implemented"), http.StatusInternalServerError)

type endpoint struct {
	ep *models.EndpointConfig
	sc *models.ScopeConfig
}

// A system generated id for this endpoint.
func (e *endpoint) ID() string {
	return e.ep.ID
}

// Name returns the name of this endpoint.
func (e *endpoint) Name() string {
	return e.ep.Name
}
Beispiel #30
0
func (n *Network) ConnectContainerToNetwork(containerName, networkName string, endpointConfig *apinet.EndpointSettings) error {
	vc := cache.ContainerCache().GetContainer(containerName)
	if vc != nil {
		containerName = vc.ContainerID
	}

	client := PortLayerClient()
	getRes, err := client.Containers.Get(containers.NewGetParamsWithContext(ctx).WithID(containerName))
	if err != nil {
		switch err := err.(type) {
		case *containers.GetNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf(err.Payload.Message))

		case *containers.GetDefault:
			return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	h := getRes.Payload
	nc := &models.NetworkConfig{NetworkName: networkName}
	if endpointConfig != nil {
		if endpointConfig.IPAMConfig != nil && endpointConfig.IPAMConfig.IPv4Address != "" {
			nc.Address = &endpointConfig.IPAMConfig.IPv4Address

		}

		// Pass Links and Aliases to PL
		nc.Aliases = vicendpoint.Alias(endpointConfig)
	}

	addConRes, err := client.Scopes.AddContainer(scopes.NewAddContainerParamsWithContext(ctx).
		WithScope(nc.NetworkName).
		WithConfig(&models.ScopesAddContainerConfig{
			Handle:        h,
			NetworkConfig: nc,
		}))
	if err != nil {
		switch err := err.(type) {
		case *scopes.AddContainerNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf(err.Payload.Message))

		case *scopes.AddContainerInternalServerError:
			return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	h = addConRes.Payload

	// only bind if the container is running
	// get the state of the container
	getStateRes, err := client.Containers.GetState(containers.NewGetStateParamsWithContext(ctx).WithHandle(h))
	if err != nil {
		switch err := err.(type) {
		case *containers.GetStateNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf(err.Payload.Message))

		case *containers.GetStateDefault:
			return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	h = getStateRes.Payload.Handle
	if getStateRes.Payload.State == "RUNNING" {
		bindRes, err := client.Scopes.BindContainer(scopes.NewBindContainerParamsWithContext(ctx).WithHandle(h))
		if err != nil {
			switch err := err.(type) {
			case *scopes.BindContainerNotFound:
				return derr.NewRequestNotFoundError(fmt.Errorf(err.Payload.Message))

			case *scopes.BindContainerInternalServerError:
				return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

			default:
				return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
			}
		}

		defer func() {
			if err == nil {
				return
			}
			if _, err2 := client.Scopes.UnbindContainer(scopes.NewUnbindContainerParamsWithContext(ctx).WithHandle(h)); err2 != nil {
				log.Warnf("failed bind container rollback: %s", err2)
			}
		}()

		h = bindRes.Payload.Handle
	}

	// commit handle
	_, err = client.Containers.Commit(containers.NewCommitParamsWithContext(ctx).WithHandle(h))
	if err != nil {
		switch err := err.(type) {
		case *containers.CommitNotFound:
			return derr.NewRequestNotFoundError(fmt.Errorf(err.Payload.Message))

		case *containers.CommitDefault:
			return derr.NewErrorWithStatusCode(fmt.Errorf(err.Payload.Message), http.StatusInternalServerError)

		default:
			return derr.NewErrorWithStatusCode(err, http.StatusInternalServerError)
		}
	}

	return nil
}