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