gofmt GoDoc comments with go1.19
Older versions of Go don't format comments, so committing this as a separate commit, so that we can already make these changes before we upgrade to Go 1.19. Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commit52c1a2fae8
) Signed-off-by: Sebastiaan van Stijn <github@gone.nl> (cherry picked from commitcdbca4061b
) Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
parent
78d8e65d2a
commit
c8c40abbba
51 changed files with 389 additions and 353 deletions
|
@ -1,4 +1,5 @@
|
|||
/*Package filters provides tools for encoding a mapping of keys to a set of
|
||||
/*
|
||||
Package filters provides tools for encoding a mapping of keys to a set of
|
||||
multiple values.
|
||||
*/
|
||||
package filters // import "github.com/docker/docker/api/types/filters"
|
||||
|
|
|
@ -45,31 +45,32 @@ func (ipnet *NetIPNet) UnmarshalJSON(b []byte) (err error) {
|
|||
// IndexInfo contains information about a registry
|
||||
//
|
||||
// RepositoryInfo Examples:
|
||||
// {
|
||||
// "Index" : {
|
||||
// "Name" : "docker.io",
|
||||
// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"],
|
||||
// "Secure" : true,
|
||||
// "Official" : true,
|
||||
// },
|
||||
// "RemoteName" : "library/debian",
|
||||
// "LocalName" : "debian",
|
||||
// "CanonicalName" : "docker.io/debian"
|
||||
// "Official" : true,
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "Index" : {
|
||||
// "Name" : "127.0.0.1:5000",
|
||||
// "Mirrors" : [],
|
||||
// "Secure" : false,
|
||||
// "Official" : false,
|
||||
// },
|
||||
// "RemoteName" : "user/repo",
|
||||
// "LocalName" : "127.0.0.1:5000/user/repo",
|
||||
// "CanonicalName" : "127.0.0.1:5000/user/repo",
|
||||
// "Official" : false,
|
||||
// }
|
||||
// {
|
||||
// "Index" : {
|
||||
// "Name" : "docker.io",
|
||||
// "Mirrors" : ["https://registry-2.docker.io/v1/", "https://registry-3.docker.io/v1/"],
|
||||
// "Secure" : true,
|
||||
// "Official" : true,
|
||||
// },
|
||||
// "RemoteName" : "library/debian",
|
||||
// "LocalName" : "debian",
|
||||
// "CanonicalName" : "docker.io/debian"
|
||||
// "Official" : true,
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "Index" : {
|
||||
// "Name" : "127.0.0.1:5000",
|
||||
// "Mirrors" : [],
|
||||
// "Secure" : false,
|
||||
// "Official" : false,
|
||||
// },
|
||||
// "RemoteName" : "user/repo",
|
||||
// "LocalName" : "127.0.0.1:5000/user/repo",
|
||||
// "CanonicalName" : "127.0.0.1:5000/user/repo",
|
||||
// "Official" : false,
|
||||
// }
|
||||
type IndexInfo struct {
|
||||
// Name is the name of the registry, such as "docker.io"
|
||||
Name string
|
||||
|
|
|
@ -100,8 +100,10 @@ func GetTimestamp(value string, reference time.Time) (string, error) {
|
|||
// if the incoming nanosecond portion is longer or shorter than 9 digits it is
|
||||
// converted to nanoseconds. The expectation is that the seconds and
|
||||
// seconds will be used to create a time variable. For example:
|
||||
// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0)
|
||||
// if err == nil since := time.Unix(seconds, nanoseconds)
|
||||
//
|
||||
// seconds, nanoseconds, err := ParseTimestamp("1136073600.000000001",0)
|
||||
// if err == nil since := time.Unix(seconds, nanoseconds)
|
||||
//
|
||||
// returns seconds as def(aultSeconds) if value == ""
|
||||
func ParseTimestamps(value string, def int64) (int64, int64, error) {
|
||||
if value == "" {
|
||||
|
|
|
@ -35,7 +35,6 @@ import (
|
|||
//
|
||||
// Sets the environment variable foo to bar, also makes interpolation
|
||||
// in the dockerfile available from the next statement on via ${foo}.
|
||||
//
|
||||
func dispatchEnv(d dispatchRequest, c *instructions.EnvCommand) error {
|
||||
runConfig := d.state.runConfig
|
||||
commitMessage := bytes.NewBufferString("ENV")
|
||||
|
@ -73,7 +72,6 @@ func dispatchMaintainer(d dispatchRequest, c *instructions.MaintainerCommand) er
|
|||
// LABEL some json data describing the image
|
||||
//
|
||||
// Sets the Label variable foo to bar,
|
||||
//
|
||||
func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
|
||||
if d.state.runConfig.Labels == nil {
|
||||
d.state.runConfig.Labels = make(map[string]string)
|
||||
|
@ -90,7 +88,6 @@ func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
|
|||
//
|
||||
// Add the file 'foo' to '/path'. Tarball and Remote URL (http, https) handling
|
||||
// exist here. If you do not wish to have this automatic handling, use COPY.
|
||||
//
|
||||
func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
||||
if c.Chmod != "" {
|
||||
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||
|
@ -112,7 +109,6 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
|||
// COPY foo /path
|
||||
//
|
||||
// Same as 'ADD' but without the tar and remote url handling.
|
||||
//
|
||||
func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
|
||||
if c.Chmod != "" {
|
||||
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||
|
@ -157,7 +153,6 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error
|
|||
}
|
||||
|
||||
// FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name]
|
||||
//
|
||||
func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
|
||||
d.builder.imageProber.Reset()
|
||||
|
||||
|
@ -304,7 +299,6 @@ func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error {
|
|||
// WORKDIR /tmp
|
||||
//
|
||||
// Set the working directory for future RUN/CMD/etc statements.
|
||||
//
|
||||
func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
|
||||
runConfig := d.state.runConfig
|
||||
var err error
|
||||
|
@ -347,7 +341,6 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
|
|||
// RUN echo hi # sh -c echo hi (Linux and LCOW)
|
||||
// RUN echo hi # cmd /S /C echo hi (Windows)
|
||||
// RUN [ "echo", "hi" ] # echo hi
|
||||
//
|
||||
func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
|
||||
if !system.IsOSSupported(d.state.operatingSystem) {
|
||||
return system.ErrNotSupportedOperatingSystem
|
||||
|
@ -442,7 +435,6 @@ func prependEnvOnCmd(buildArgs *BuildArgs, buildArgVars []string, cmd strslice.S
|
|||
//
|
||||
// Set the default command to run in the container (which may be empty).
|
||||
// Argument handling is the same as RUN.
|
||||
//
|
||||
func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
|
||||
runConfig := d.state.runConfig
|
||||
cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String())
|
||||
|
@ -473,7 +465,6 @@ func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
|
|||
//
|
||||
// Set the default healthcheck command to run in the container (which may be empty).
|
||||
// Argument handling is the same as RUN.
|
||||
//
|
||||
func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) error {
|
||||
runConfig := d.state.runConfig
|
||||
if runConfig.Healthcheck != nil {
|
||||
|
@ -493,7 +484,6 @@ func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand)
|
|||
//
|
||||
// Handles command processing similar to CMD and RUN, only req.runConfig.Entrypoint
|
||||
// is initialized at newBuilder time instead of through argument parsing.
|
||||
//
|
||||
func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) error {
|
||||
runConfig := d.state.runConfig
|
||||
cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String())
|
||||
|
@ -523,7 +513,6 @@ func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) er
|
|||
//
|
||||
// Expose ports for links and port mappings. This all ends up in
|
||||
// req.runConfig.ExposedPorts for runconfig.
|
||||
//
|
||||
func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []string) error {
|
||||
// custom multi word expansion
|
||||
// expose $FOO with FOO="80 443" is expanded as EXPOSE [80,443]. This is the only command supporting word to words expansion
|
||||
|
@ -557,7 +546,6 @@ func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []str
|
|||
//
|
||||
// Set the user to 'foo' for future commands and when running the
|
||||
// ENTRYPOINT/CMD at container run time.
|
||||
//
|
||||
func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error {
|
||||
d.state.runConfig.User = c.User
|
||||
return d.builder.commit(d.state, fmt.Sprintf("USER %v", c.User))
|
||||
|
@ -566,7 +554,6 @@ func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error {
|
|||
// VOLUME /foo
|
||||
//
|
||||
// Expose the volume /foo for use. Will also accept the JSON array form.
|
||||
//
|
||||
func dispatchVolume(d dispatchRequest, c *instructions.VolumeCommand) error {
|
||||
if d.state.runConfig.Volumes == nil {
|
||||
d.state.runConfig.Volumes = map[string]struct{}{}
|
||||
|
|
|
@ -80,10 +80,10 @@ func GetWithStatusError(address string) (resp *http.Response, err error) {
|
|||
// inspectResponse looks into the http response data at r to determine whether its
|
||||
// content-type is on the list of acceptable content types for remote build contexts.
|
||||
// This function returns:
|
||||
// - a string representation of the detected content-type
|
||||
// - an io.Reader for the response body
|
||||
// - an error value which will be non-nil either when something goes wrong while
|
||||
// reading bytes from r or when the detected content-type is not acceptable.
|
||||
// - a string representation of the detected content-type
|
||||
// - an io.Reader for the response body
|
||||
// - an error value which will be non-nil either when something goes wrong while
|
||||
// reading bytes from r or when the detected content-type is not acceptable.
|
||||
func inspectResponse(ct string, r io.Reader, clen int64) (string, io.Reader, error) {
|
||||
plen := clen
|
||||
if plen <= 0 || plen > maxPreambleLength {
|
||||
|
|
|
@ -4,7 +4,7 @@ Package client is a Go client for the Docker Engine API.
|
|||
For more information about the Engine API, see the documentation:
|
||||
https://docs.docker.com/engine/api/
|
||||
|
||||
Usage
|
||||
# Usage
|
||||
|
||||
You use the library by creating a client object and calling methods on it. The
|
||||
client can be created either from environment variables with NewClientWithOpts(client.FromEnv),
|
||||
|
@ -37,7 +37,6 @@ For example, to list running containers (the equivalent of "docker ps"):
|
|||
fmt.Printf("%s %s\n", container.ID[:10], container.Image)
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
package client // import "github.com/docker/docker/client"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
// multiplexed.
|
||||
// The format of the multiplexed stream is as follows:
|
||||
//
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
//
|
||||
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||
//
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
// multiplexed.
|
||||
// The format of the multiplexed stream is as follows:
|
||||
//
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
// [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT}
|
||||
//
|
||||
// STREAM_TYPE can be 1 for stdout and 2 for stderr
|
||||
//
|
||||
|
|
|
@ -594,7 +594,7 @@ func newAPIServerConfig(cli *DaemonCli) (*apiserver.Config, error) {
|
|||
|
||||
// checkTLSAuthOK checks basically for an explicitly disabled TLS/TLSVerify
|
||||
// Going forward we do not want to support a scenario where dockerd listens
|
||||
// on TCP without either TLS client auth (or an explicit opt-in to disable it)
|
||||
// on TCP without either TLS client auth (or an explicit opt-in to disable it)
|
||||
func checkTLSAuthOK(c *config.Config) bool {
|
||||
if c.TLS == nil {
|
||||
// Either TLS is enabled by default, in which case TLS verification should be enabled by default, or explicitly disabled
|
||||
|
|
|
@ -300,10 +300,11 @@ func (container *Container) SetupWorkingDirectory(rootIdentity idtools.Identity)
|
|||
// particular path inside the container as though you were a process in that
|
||||
// container.
|
||||
//
|
||||
// NOTE: The returned path is *only* safely scoped inside the container's BaseFS
|
||||
// if no component of the returned path changes (such as a component
|
||||
// symlinking to a different path) between using this method and using the
|
||||
// path. See symlink.FollowSymlinkInScope for more details.
|
||||
// # NOTE
|
||||
// The returned path is *only* safely scoped inside the container's BaseFS
|
||||
// if no component of the returned path changes (such as a component
|
||||
// symlinking to a different path) between using this method and using the
|
||||
// path. See symlink.FollowSymlinkInScope for more details.
|
||||
func (container *Container) GetResourcePath(path string) (string, error) {
|
||||
if container.BaseFS == nil {
|
||||
return "", errors.New("GetResourcePath: BaseFS of container " + container.ID + " is unexpectedly nil")
|
||||
|
@ -329,10 +330,11 @@ func (container *Container) GetResourcePath(path string) (string, error) {
|
|||
// Only use this method to safely access the container's `container.json` or
|
||||
// other metadata files. If in doubt, use container.GetResourcePath.
|
||||
//
|
||||
// NOTE: The returned path is *only* safely scoped inside the container's root
|
||||
// if no component of the returned path changes (such as a component
|
||||
// symlinking to a different path) between using this method and using the
|
||||
// path. See symlink.FollowSymlinkInScope for more details.
|
||||
// # NOTE
|
||||
// The returned path is *only* safely scoped inside the container's root
|
||||
// if no component of the returned path changes (such as a component
|
||||
// symlinking to a different path) between using this method and using the
|
||||
// path. See symlink.FollowSymlinkInScope for more details.
|
||||
func (container *Container) GetRootResourcePath(path string) (string, error) {
|
||||
// IMPORTANT - These are paths on the OS where the daemon is running, hence
|
||||
// any filepath operations must be done in an OS agnostic way.
|
||||
|
|
|
@ -205,9 +205,9 @@ func resolveInterfaceAddr(specifiedInterface string) (net.IP, error) {
|
|||
}
|
||||
|
||||
// resolveInputIPAddr tries to resolve the IP address from the string passed as input
|
||||
// - tries to match the string as an interface name, if so returns the IP address associated with it
|
||||
// - on failure of previous step tries to parse the string as an IP address itself
|
||||
// if succeeds returns the IP address
|
||||
// - tries to match the string as an interface name, if so returns the IP address associated with it
|
||||
// - on failure of previous step tries to parse the string as an IP address itself
|
||||
// if succeeds returns the IP address
|
||||
func resolveInputIPAddr(input string, isUnspecifiedValid bool) (net.IP, error) {
|
||||
// Try to see if it is an interface name
|
||||
interfaceAddr, err := resolveInterfaceAddr(input)
|
||||
|
|
|
@ -30,11 +30,11 @@ import (
|
|||
|
||||
// GetContainer looks for a container using the provided information, which could be
|
||||
// one of the following inputs from the caller:
|
||||
// - A full container ID, which will exact match a container in daemon's list
|
||||
// - A container name, which will only exact match via the GetByName() function
|
||||
// - A partial container ID prefix (e.g. short ID) of any length that is
|
||||
// unique enough to only return a single container object
|
||||
// If none of these searches succeed, an error is returned
|
||||
// - A full container ID, which will exact match a container in daemon's list
|
||||
// - A container name, which will only exact match via the GetByName() function
|
||||
// - A partial container ID prefix (e.g. short ID) of any length that is
|
||||
// unique enough to only return a single container object
|
||||
// If none of these searches succeed, an error is returned
|
||||
func (daemon *Daemon) GetContainer(prefixOrName string) (*container.Container, error) {
|
||||
if len(prefixOrName) == 0 {
|
||||
return nil, errors.WithStack(invalidIdentifier(prefixOrName))
|
||||
|
|
|
@ -63,7 +63,8 @@ func (cp namespacedContent) Info(ctx context.Context, dgst digest.Digest) (conte
|
|||
// If one or more fieldpaths are provided, only those
|
||||
// fields will be updated.
|
||||
// Mutable fields:
|
||||
// labels.*
|
||||
//
|
||||
// labels.*
|
||||
func (cp namespacedContent) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
|
||||
return cp.provider.Update(withDefaultNamespace(ctx, cp.ns), info, fieldpaths...)
|
||||
}
|
||||
|
|
|
@ -1073,15 +1073,16 @@ func setupInitLayer(idMapping *idtools.IdentityMapping) func(containerfs.Contain
|
|||
}
|
||||
|
||||
// Parse the remapped root (user namespace) option, which can be one of:
|
||||
// username - valid username from /etc/passwd
|
||||
// username:groupname - valid username; valid groupname from /etc/group
|
||||
// uid - 32-bit unsigned int valid Linux UID value
|
||||
// uid:gid - uid value; 32-bit unsigned int Linux GID value
|
||||
//
|
||||
// If no groupname is specified, and a username is specified, an attempt
|
||||
// will be made to lookup a gid for that username as a groupname
|
||||
// - username - valid username from /etc/passwd
|
||||
// - username:groupname - valid username; valid groupname from /etc/group
|
||||
// - uid - 32-bit unsigned int valid Linux UID value
|
||||
// - uid:gid - uid value; 32-bit unsigned int Linux GID value
|
||||
//
|
||||
// If names are used, they are verified to exist in passwd/group
|
||||
// If no groupname is specified, and a username is specified, an attempt
|
||||
// will be made to lookup a gid for that username as a groupname
|
||||
//
|
||||
// If names are used, they are verified to exist in passwd/group
|
||||
func parseRemappedRoot(usergrp string) (string, string, error) {
|
||||
|
||||
var (
|
||||
|
|
|
@ -31,10 +31,11 @@ type NaiveDiffDriver struct {
|
|||
// NewNaiveDiffDriver returns a fully functional driver that wraps the
|
||||
// given ProtoDriver and adds the capability of the following methods which
|
||||
// it may or may not support on its own:
|
||||
// Diff(id, parent string) (archive.Archive, error)
|
||||
// Changes(id, parent string) ([]archive.Change, error)
|
||||
// ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
|
||||
// DiffSize(id, parent string) (size int64, err error)
|
||||
//
|
||||
// Diff(id, parent string) (archive.Archive, error)
|
||||
// Changes(id, parent string) ([]archive.Change, error)
|
||||
// ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error)
|
||||
// DiffSize(id, parent string) (size int64, err error)
|
||||
func NewNaiveDiffDriver(driver ProtoDriver, uidMaps, gidMaps []idtools.IDMap) Driver {
|
||||
return &NaiveDiffDriver{ProtoDriver: driver,
|
||||
uidMaps: uidMaps,
|
||||
|
|
|
@ -62,12 +62,12 @@ type serviceVM struct {
|
|||
}
|
||||
|
||||
// add will add an id to the service vm map. There are three cases:
|
||||
// - entry doesn't exist:
|
||||
// - add id to map and return a new vm that the caller can manually configure+start
|
||||
// - entry does exist
|
||||
// - return vm in map and increment ref count
|
||||
// - entry does exist but the ref count is 0
|
||||
// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
// - entry doesn't exist:
|
||||
// add id to map and return a new vm that the caller can manually configure+start
|
||||
// - entry does exist:
|
||||
// return vm in map and increment ref count
|
||||
// - entry does exist but the ref count is 0:
|
||||
// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
func (svmMap *serviceVMMap) add(id string) (svm *serviceVM, alreadyExists bool, err error) {
|
||||
svmMap.Lock()
|
||||
defer svmMap.Unlock()
|
||||
|
@ -95,12 +95,12 @@ func (svmMap *serviceVMMap) add(id string) (svm *serviceVM, alreadyExists bool,
|
|||
}
|
||||
|
||||
// get will get the service vm from the map. There are three cases:
|
||||
// - entry doesn't exist:
|
||||
// - return errVMUnknown
|
||||
// - entry does exist
|
||||
// - return vm with no error
|
||||
// - entry does exist but the ref count is 0
|
||||
// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
// - entry doesn't exist:
|
||||
// return errVMUnknown
|
||||
// - entry does exist:
|
||||
// return vm with no error
|
||||
// - entry does exist but the ref count is 0:
|
||||
// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
func (svmMap *serviceVMMap) get(id string) (*serviceVM, error) {
|
||||
svmMap.Lock()
|
||||
defer svmMap.Unlock()
|
||||
|
@ -115,15 +115,15 @@ func (svmMap *serviceVMMap) get(id string) (*serviceVM, error) {
|
|||
}
|
||||
|
||||
// decrementRefCount decrements the ref count of the given ID from the map. There are four cases:
|
||||
// - entry doesn't exist:
|
||||
// - return errVMUnknown
|
||||
// - entry does exist but the ref count is 0
|
||||
// - return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
// - entry does exist but ref count is 1
|
||||
// - return vm and set lastRef to true. The caller can then stop the vm, delete the id from this map
|
||||
// - and execute svm.signalStopFinished to signal the threads that the svm has been terminated.
|
||||
// - entry does exist and ref count > 1
|
||||
// - just reduce ref count and return svm
|
||||
// - entry doesn't exist:
|
||||
// return errVMUnknown
|
||||
// - entry does exist but the ref count is 0:
|
||||
// return the svm and errVMisTerminating. Caller can call svm.getStopError() to wait for stop
|
||||
// - entry does exist but ref count is 1:
|
||||
// return vm and set lastRef to true. The caller can then stop the vm, delete the id from this map
|
||||
// and execute svm.signalStopFinished to signal the threads that the svm has been terminated.
|
||||
// - entry does exist and ref count > 1:
|
||||
// just reduce ref count and return svm
|
||||
func (svmMap *serviceVMMap) decrementRefCount(id string) (_ *serviceVM, lastRef bool, _ error) {
|
||||
svmMap.Lock()
|
||||
defer svmMap.Unlock()
|
||||
|
|
|
@ -219,7 +219,7 @@ func (i *ImageService) GetImage(refOrID string, platform *specs.Platform) (retIm
|
|||
}
|
||||
|
||||
// OnlyPlatformWithFallback uses `platforms.Only` with a fallback to handle the case where the platform
|
||||
// being matched does not have a CPU variant.
|
||||
// being matched does not have a CPU variant.
|
||||
//
|
||||
// The reason for this is that CPU variant is not even if the official image config spec as of this writing.
|
||||
// See: https://github.com/opencontainers/image-spec/pull/809
|
||||
|
|
|
@ -109,9 +109,9 @@ func exportContainerRw(layerStore layer.Store, id, mountLabel string) (arch io.R
|
|||
// the build.
|
||||
//
|
||||
// This method is different from CreateImageFromContainer:
|
||||
// * it doesn't attempt to validate container state
|
||||
// * it doesn't send a commit action to metrics
|
||||
// * it doesn't log a container commit event
|
||||
// - it doesn't attempt to validate container state
|
||||
// - it doesn't send a commit action to metrics
|
||||
// - it doesn't log a container commit event
|
||||
//
|
||||
// This is a temporary shim. Should be removed when builder stops using commit.
|
||||
func (i *ImageService) CommitBuildStep(c backend.CommitConfig) (image.ID, error) {
|
||||
|
|
|
@ -45,13 +45,13 @@ const (
|
|||
// are divided into two categories grouped by their severity:
|
||||
//
|
||||
// Hard Conflict:
|
||||
// - a pull or build using the image.
|
||||
// - any descendant image.
|
||||
// - any running container using the image.
|
||||
// - a pull or build using the image.
|
||||
// - any descendant image.
|
||||
// - any running container using the image.
|
||||
//
|
||||
// Soft Conflict:
|
||||
// - any stopped container using the image.
|
||||
// - any repository tag or digest references to the image.
|
||||
// - any stopped container using the image.
|
||||
// - any repository tag or digest references to the image.
|
||||
//
|
||||
// The image cannot be removed if there are any hard conflicts and can be
|
||||
// removed if there are soft conflicts only if force is true.
|
||||
|
@ -59,7 +59,6 @@ const (
|
|||
// If prune is true, ancestor images will each attempt to be deleted quietly,
|
||||
// meaning any delete conflicts will cause the image to not be deleted and the
|
||||
// conflict will not be reported.
|
||||
//
|
||||
func (i *ImageService) ImageDelete(imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error) {
|
||||
start := time.Now()
|
||||
records := []types.ImageDeleteResponseItem{}
|
||||
|
|
|
@ -249,7 +249,7 @@ func getBackingFs(v *types.Info) string {
|
|||
//
|
||||
// Output example from `docker-init --version`:
|
||||
//
|
||||
// tini version 0.18.0 - git.fec3683
|
||||
// tini version 0.18.0 - git.fec3683
|
||||
func parseInitVersion(v string) (version string, commit string, err error) {
|
||||
parts := strings.Split(v, " - ")
|
||||
|
||||
|
@ -274,9 +274,9 @@ func parseInitVersion(v string) (version string, commit string, err error) {
|
|||
//
|
||||
// Output example from `runc --version`:
|
||||
//
|
||||
// runc version 1.0.0-rc5+dev
|
||||
// commit: 69663f0bd4b60df09991c08812a60108003fa340
|
||||
// spec: 1.0.0
|
||||
// runc version 1.0.0-rc5+dev
|
||||
// commit: 69663f0bd4b60df09991c08812a60108003fa340
|
||||
// spec: 1.0.0
|
||||
func parseRuntimeVersion(v string) (runtime string, version string, commit string, err error) {
|
||||
lines := strings.Split(strings.TrimSpace(v), "\n")
|
||||
for _, line := range lines {
|
||||
|
|
|
@ -11,19 +11,20 @@ import (
|
|||
)
|
||||
|
||||
// ContainerTop handles `docker top` client requests.
|
||||
//
|
||||
// Future considerations:
|
||||
// -- Windows users are far more familiar with CPU% total.
|
||||
// Further, users on Windows rarely see user/kernel CPU stats split.
|
||||
// The kernel returns everything in terms of 100ns. To obtain
|
||||
// CPU%, we could do something like docker stats does which takes two
|
||||
// samples, subtract the difference and do the maths. Unfortunately this
|
||||
// would slow the stat call down and require two kernel calls. So instead,
|
||||
// we do something similar to linux and display the CPU as combined HH:MM:SS.mmm.
|
||||
// -- Perhaps we could add an argument to display "raw" stats
|
||||
// -- "Memory" is an extremely overloaded term in Windows. Hence we do what
|
||||
// task manager does and use the private working set as the memory counter.
|
||||
// We could return more info for those who really understand how memory
|
||||
// management works in Windows if we introduced a "raw" stats (above).
|
||||
// - Windows users are far more familiar with CPU% total.
|
||||
// Further, users on Windows rarely see user/kernel CPU stats split.
|
||||
// The kernel returns everything in terms of 100ns. To obtain
|
||||
// CPU%, we could do something like docker stats does which takes two
|
||||
// samples, subtract the difference and do the maths. Unfortunately this
|
||||
// would slow the stat call down and require two kernel calls. So instead,
|
||||
// we do something similar to linux and display the CPU as combined HH:MM:SS.mmm.
|
||||
// - Perhaps we could add an argument to display "raw" stats
|
||||
// - "Memory" is an extremely overloaded term in Windows. Hence we do what
|
||||
// task manager does and use the private working set as the memory counter.
|
||||
// We could return more info for those who really understand how memory
|
||||
// management works in Windows if we introduced a "raw" stats (above).
|
||||
func (daemon *Daemon) ContainerTop(name string, psArgs string) (*containertypes.ContainerTopOKBody, error) {
|
||||
// It's not at all an equivalent to linux 'ps' on Windows
|
||||
if psArgs != "" {
|
||||
|
|
|
@ -14,7 +14,8 @@ type UAStringKey struct{}
|
|||
|
||||
// DockerUserAgent is the User-Agent the Docker client uses to identify itself.
|
||||
// In accordance with RFC 7231 (5.5.3) is of the form:
|
||||
// [docker client's UA] UpstreamClient([upstream client's UA])
|
||||
//
|
||||
// [docker client's UA] UpstreamClient([upstream client's UA])
|
||||
func DockerUserAgent(ctx context.Context) string {
|
||||
httpVersion := make([]useragent.VersionInfo, 0, 6)
|
||||
httpVersion = append(httpVersion, useragent.VersionInfo{Name: "docker", Version: Version})
|
||||
|
@ -68,7 +69,8 @@ func escapeStr(s string, charsToEscape string) string {
|
|||
|
||||
// insertUpstreamUserAgent adds the upstream client useragent to create a user-agent
|
||||
// string of the form:
|
||||
// $dockerUA UpstreamClient($upstreamUA)
|
||||
//
|
||||
// $dockerUA UpstreamClient($upstreamUA)
|
||||
func insertUpstreamUserAgent(upstreamUA string, dockerUA string) string {
|
||||
charsToEscape := `();\`
|
||||
upstreamUAEscaped := escapeStr(upstreamUA, charsToEscape)
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
|
||||
Package winresources is used to embed Windows resources into dockerd.exe.
|
||||
These resources are used to provide
|
||||
|
||||
* Version information
|
||||
* An icon
|
||||
* A Windows manifest declaring Windows version support
|
||||
- Version information
|
||||
- An icon
|
||||
- A Windows manifest declaring Windows version support
|
||||
|
||||
The resource object files are generated in hack/make/.go-autogen from
|
||||
source files in hack/make/.resources-windows. This occurs automatically
|
||||
|
@ -13,6 +12,5 @@ when you run hack/make.sh.
|
|||
|
||||
These object files are picked up automatically by go build when this package
|
||||
is included.
|
||||
|
||||
*/
|
||||
package winresources
|
||||
|
|
|
@ -93,9 +93,10 @@ func (s *DockerSuite) TestCpFromSymlinkDestination(c *testing.T) {
|
|||
// J | yes | yes | yes | yes | - | copy dir contents
|
||||
//
|
||||
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't
|
||||
// exist. This should create a file with the name DST and copy the
|
||||
// contents of the source file into it.
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should create a file with the name DST and copy the contents of the
|
||||
// source file into it.
|
||||
func (s *DockerSuite) TestCpFromCaseA(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -112,9 +113,10 @@ func (s *DockerSuite) TestCpFromCaseA(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1\n"))
|
||||
}
|
||||
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't
|
||||
// exist. This should cause an error because the copy operation cannot
|
||||
// create a directory when copying a single file.
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should cause an error because the copy operation cannot create a directory
|
||||
// when copying a single file.
|
||||
func (s *DockerSuite) TestCpFromCaseB(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
@ -130,8 +132,9 @@ func (s *DockerSuite) TestCpFromCaseB(c *testing.T) {
|
|||
assert.Assert(c, isCpDirNotExist(err), "expected DirNotExists error, but got %T: %s", err, err)
|
||||
}
|
||||
|
||||
// C. SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
// C. SRC specifies a file and DST exists as a file.
|
||||
//
|
||||
// This should overwrite the file at DST with the contents of the source file.
|
||||
func (s *DockerSuite) TestCpFromCaseC(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -152,9 +155,10 @@ func (s *DockerSuite) TestCpFromCaseC(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1\n"))
|
||||
}
|
||||
|
||||
// D. SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// D. SRC specifies a file and DST exists as a directory.
|
||||
//
|
||||
// This should place a copy of the source file inside it using the basename from
|
||||
// SRC. Ensure this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseD(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
@ -186,10 +190,11 @@ func (s *DockerSuite) TestCpFromCaseD(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1\n"))
|
||||
}
|
||||
|
||||
// E. SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
// E. SRC specifies a directory and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC directory
|
||||
// into the DST directory. Ensure this works whether DST has a trailing path
|
||||
// separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseE(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
@ -214,8 +219,10 @@ func (s *DockerSuite) TestCpFromCaseE(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n"))
|
||||
}
|
||||
|
||||
// F. SRC specifies a directory and DST exists as a file. This should cause an
|
||||
// error as it is not possible to overwrite a file with a directory.
|
||||
// F. SRC specifies a directory and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpFromCaseF(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -235,9 +242,10 @@ func (s *DockerSuite) TestCpFromCaseF(c *testing.T) {
|
|||
assert.Assert(c, isCpCannotCopyDir(err), "expected ErrCannotCopyDir error, but got %T: %s", err, err)
|
||||
}
|
||||
|
||||
// G. SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
// G. SRC specifies a directory and DST exists as a directory.
|
||||
//
|
||||
// This should copy the SRC directory and all its contents to the DST directory.
|
||||
// Ensure this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseG(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -268,10 +276,11 @@ func (s *DockerSuite) TestCpFromCaseG(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n"))
|
||||
}
|
||||
|
||||
// H. SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// H. SRC specifies a directory's contents only and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseH(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{addContent: true})
|
||||
|
@ -296,9 +305,10 @@ func (s *DockerSuite) TestCpFromCaseH(c *testing.T) {
|
|||
assert.NilError(c, fileContentEquals(c, dstPath, "file1-1\n"))
|
||||
}
|
||||
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file. This
|
||||
// should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpFromCaseI(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -319,9 +329,10 @@ func (s *DockerSuite) TestCpFromCaseI(c *testing.T) {
|
|||
}
|
||||
|
||||
// J. SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
//
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpFromCaseJ(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
|
|
@ -97,9 +97,10 @@ func (s *DockerSuite) TestCpToSymlinkDestination(c *testing.T) {
|
|||
// J | yes | yes | yes | yes | - | copy dir contents
|
||||
//
|
||||
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't
|
||||
// exist. This should create a file with the name DST and copy the
|
||||
// contents of the source file into it.
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should create a file with the name DST and copy the contents of the
|
||||
// source file into it.
|
||||
func (s *DockerSuite) TestCpToCaseA(c *testing.T) {
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
workDir: "/root", command: makeCatFileCommand("itWorks.txt"),
|
||||
|
@ -117,9 +118,10 @@ func (s *DockerSuite) TestCpToCaseA(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n"))
|
||||
}
|
||||
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't
|
||||
// exist. This should cause an error because the copy operation cannot
|
||||
// create a directory when copying a single file.
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should cause an error because the copy operation cannot create a
|
||||
// directory when copying a single file.
|
||||
func (s *DockerSuite) TestCpToCaseB(c *testing.T) {
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("testDir/file1"),
|
||||
|
@ -138,8 +140,9 @@ func (s *DockerSuite) TestCpToCaseB(c *testing.T) {
|
|||
assert.Assert(c, isCpDirNotExist(err), "expected DirNotExists error, but got %T: %s", err, err)
|
||||
}
|
||||
|
||||
// C. SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
// C. SRC specifies a file and DST exists as a file.
|
||||
//
|
||||
// This should overwrite the file at DST with the contents of the source file.
|
||||
func (s *DockerSuite) TestCpToCaseC(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -161,9 +164,10 @@ func (s *DockerSuite) TestCpToCaseC(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n"), "Should now contain file1's contents")
|
||||
}
|
||||
|
||||
// D. SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// D. SRC specifies a file and DST exists as a directory.
|
||||
//
|
||||
// This should place a copy of the source file inside it using the basename from
|
||||
// SRC. Ensure this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseD(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -198,10 +202,11 @@ func (s *DockerSuite) TestCpToCaseD(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1\n"), "Should now contain file1's contents")
|
||||
}
|
||||
|
||||
// E. SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
// E. SRC specifies a directory and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC
|
||||
// directory into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseE(c *testing.T) {
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
|
@ -231,8 +236,10 @@ func (s *DockerSuite) TestCpToCaseE(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents")
|
||||
}
|
||||
|
||||
// F. SRC specifies a directory and DST exists as a file. This should cause an
|
||||
// error as it is not possible to overwrite a file with a directory.
|
||||
// F. SRC specifies a directory and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpToCaseF(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -252,9 +259,10 @@ func (s *DockerSuite) TestCpToCaseF(c *testing.T) {
|
|||
assert.Assert(c, isCpCannotCopyDir(err), "expected ErrCannotCopyDir error, but got %T: %s", err, err)
|
||||
}
|
||||
|
||||
// G. SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
// G. SRC specifies a directory and DST exists as a directory.
|
||||
//
|
||||
// This should copy the SRC directory and all its contents to the DST directory.
|
||||
// Ensure this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseG(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -289,10 +297,11 @@ func (s *DockerSuite) TestCpToCaseG(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents")
|
||||
}
|
||||
|
||||
// H. SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// H. SRC specifies a directory's contents only and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseH(c *testing.T) {
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
command: makeCatFileCommand("/testDir/file1-1"),
|
||||
|
@ -322,9 +331,10 @@ func (s *DockerSuite) TestCpToCaseH(c *testing.T) {
|
|||
assert.NilError(c, containerStartOutputEquals(c, containerID, "file1-1\n"), "Should now contain file1-1's contents")
|
||||
}
|
||||
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file. This
|
||||
// should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func (s *DockerSuite) TestCpToCaseI(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
@ -345,9 +355,10 @@ func (s *DockerSuite) TestCpToCaseI(c *testing.T) {
|
|||
}
|
||||
|
||||
// J. SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
//
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func (s *DockerSuite) TestCpToCaseJ(c *testing.T) {
|
||||
testRequires(c, DaemonIsLinux)
|
||||
containerID := makeTestContainer(c, testContainerOptions{
|
||||
|
|
|
@ -505,8 +505,7 @@ func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverGetEmptyResponse(c *
|
|||
|
||||
// Ensure only cached paths are used in volume list to prevent N+1 calls to `VolumeDriver.Path`
|
||||
//
|
||||
// TODO(@cpuguy83): This test is testing internal implementation. In all the cases here, there may not even be a path
|
||||
// available because the volume is not even mounted. Consider removing this test.
|
||||
// TODO(@cpuguy83): This test is testing internal implementation. In all the cases here, there may not even be a path available because the volume is not even mounted. Consider removing this test.
|
||||
func (s *DockerExternalVolumeSuite) TestExternalVolumeDriverPathCalls(c *testing.T) {
|
||||
s.d.Start(c)
|
||||
assert.Equal(c, s.ec.paths, 0)
|
||||
|
|
|
@ -26,9 +26,9 @@ import (
|
|||
//
|
||||
// The format of /proc/self/mountinfo is like:
|
||||
//
|
||||
// 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
|
||||
// ^^^^\
|
||||
// - this is the minor:major we look for
|
||||
// 29 23 0:24 / /dev/shm rw,nosuid,nodev shared:4 - tmpfs tmpfs rw
|
||||
// ^^^^\
|
||||
// - this is the minor:major we look for
|
||||
func testIpcCheckDevExists(mm string) (bool, error) {
|
||||
f, err := os.Open("/proc/self/mountinfo")
|
||||
if err != nil {
|
||||
|
|
|
@ -115,7 +115,7 @@ func createTestImage(ctx context.Context, t testing.TB, store content.Store) ima
|
|||
}
|
||||
|
||||
// Make sure that pulling by an already cached digest but for a different ref (that should not have that digest)
|
||||
// verifies with the remote that the digest exists in that repo.
|
||||
// verifies with the remote that the digest exists in that repo.
|
||||
func TestImagePullStoredfDigestForOtherRepo(t *testing.T) {
|
||||
skip.If(t, testEnv.IsRemoteDaemon, "cannot run daemon when remote daemon")
|
||||
skip.If(t, testEnv.OSType == "windows", "We don't run a test registry on Windows")
|
||||
|
|
|
@ -33,8 +33,8 @@ func (res *ExecResult) Combined() string {
|
|||
|
||||
// Exec executes a command inside a container, returning the result
|
||||
// containing stdout, stderr, and exit code. Note:
|
||||
// - this is a synchronous operation;
|
||||
// - cmd stdin is closed.
|
||||
// - this is a synchronous operation;
|
||||
// - cmd stdin is closed.
|
||||
func Exec(ctx context.Context, cli client.APIClient, id string, cmd []string) (ExecResult, error) {
|
||||
// prepare exec
|
||||
execConfig := types.ExecConfig{
|
||||
|
|
|
@ -363,7 +363,7 @@ func TestCreateServiceConfigFileMode(t *testing.T) {
|
|||
//
|
||||
// To test this, we're going to create a service with the sysctl option
|
||||
//
|
||||
// {"net.ipv4.ip_nonlocal_bind": "0"}
|
||||
// {"net.ipv4.ip_nonlocal_bind": "0"}
|
||||
//
|
||||
// We'll get the service's tasks to get the container ID, and then we'll
|
||||
// inspect the container. If the output of the container inspect contains the
|
||||
|
@ -458,7 +458,7 @@ func TestCreateServiceSysctls(t *testing.T) {
|
|||
//
|
||||
// To test this, we're going to create a service with the capabilities option
|
||||
//
|
||||
// []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"}
|
||||
// []string{"CAP_NET_RAW", "CAP_SYS_CHROOT"}
|
||||
//
|
||||
// We'll get the service's tasks to get the container ID, and then we'll
|
||||
// inspect the container. If the output of the container inspect contains the
|
||||
|
|
|
@ -26,7 +26,7 @@ func hasSystemd() bool {
|
|||
|
||||
// TestCgroupDriverSystemdMemoryLimit checks that container
|
||||
// memory limit can be set when using systemd cgroupdriver.
|
||||
// https://github.com/moby/moby/issues/35123
|
||||
// https://github.com/moby/moby/issues/35123
|
||||
func TestCgroupDriverSystemdMemoryLimit(t *testing.T) {
|
||||
skip.If(t, testEnv.DaemonInfo.OSType == "windows")
|
||||
skip.If(t, !hasSystemd())
|
||||
|
|
|
@ -116,43 +116,43 @@ func (c *client) Version(ctx context.Context) (containerd.Version, error) {
|
|||
//
|
||||
// Isolation=Process example:
|
||||
//
|
||||
// {
|
||||
// "SystemType": "Container",
|
||||
// "Name": "5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776",
|
||||
// "Owner": "docker",
|
||||
// "VolumePath": "\\\\\\\\?\\\\Volume{66d1ef4c-7a00-11e6-8948-00155ddbef9d}",
|
||||
// "IgnoreFlushesDuringBoot": true,
|
||||
// "LayerFolderPath": "C:\\\\control\\\\windowsfilter\\\\5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776",
|
||||
// "Layers": [{
|
||||
// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526",
|
||||
// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c"
|
||||
// }],
|
||||
// "HostName": "5e0055c814a6",
|
||||
// "MappedDirectories": [],
|
||||
// "HvPartition": false,
|
||||
// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"],
|
||||
// }
|
||||
// {
|
||||
// "SystemType": "Container",
|
||||
// "Name": "5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776",
|
||||
// "Owner": "docker",
|
||||
// "VolumePath": "\\\\\\\\?\\\\Volume{66d1ef4c-7a00-11e6-8948-00155ddbef9d}",
|
||||
// "IgnoreFlushesDuringBoot": true,
|
||||
// "LayerFolderPath": "C:\\\\control\\\\windowsfilter\\\\5e0055c814a6005b8e57ac59f9a522066e0af12b48b3c26a9416e23907698776",
|
||||
// "Layers": [{
|
||||
// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526",
|
||||
// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c"
|
||||
// }],
|
||||
// "HostName": "5e0055c814a6",
|
||||
// "MappedDirectories": [],
|
||||
// "HvPartition": false,
|
||||
// "EndpointList": ["eef2649d-bb17-4d53-9937-295a8efe6f2c"],
|
||||
// }
|
||||
//
|
||||
// Isolation=Hyper-V example:
|
||||
//
|
||||
// {
|
||||
// "SystemType": "Container",
|
||||
// "Name": "475c2c58933b72687a88a441e7e0ca4bd72d76413c5f9d5031fee83b98f6045d",
|
||||
// "Owner": "docker",
|
||||
// "IgnoreFlushesDuringBoot": true,
|
||||
// "Layers": [{
|
||||
// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526",
|
||||
// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c"
|
||||
// }],
|
||||
// "HostName": "475c2c58933b",
|
||||
// "MappedDirectories": [],
|
||||
// "HvPartition": true,
|
||||
// "EndpointList": ["e1bb1e61-d56f-405e-b75d-fd520cefa0cb"],
|
||||
// "DNSSearchList": "a.com,b.com,c.com",
|
||||
// "HvRuntime": {
|
||||
// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
|
||||
// },
|
||||
// }
|
||||
// {
|
||||
// "SystemType": "Container",
|
||||
// "Name": "475c2c58933b72687a88a441e7e0ca4bd72d76413c5f9d5031fee83b98f6045d",
|
||||
// "Owner": "docker",
|
||||
// "IgnoreFlushesDuringBoot": true,
|
||||
// "Layers": [{
|
||||
// "ID": "18955d65-d45a-557b-bf1c-49d6dfefc526",
|
||||
// "Path": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c"
|
||||
// }],
|
||||
// "HostName": "475c2c58933b",
|
||||
// "MappedDirectories": [],
|
||||
// "HvPartition": true,
|
||||
// "EndpointList": ["e1bb1e61-d56f-405e-b75d-fd520cefa0cb"],
|
||||
// "DNSSearchList": "a.com,b.com,c.com",
|
||||
// "HvRuntime": {
|
||||
// "ImagePath": "C:\\\\control\\\\windowsfilter\\\\65bf96e5760a09edf1790cb229e2dfb2dbd0fcdc0bf7451bae099106bfbfea0c\\\\UtilityVM"
|
||||
// },
|
||||
// }
|
||||
func (c *client) Create(_ context.Context, id string, spec *specs.Spec, shim string, runtimeOptions interface{}, opts ...containerd.NewContainerOpts) error {
|
||||
if ctr := c.getContainer(id); ctr != nil {
|
||||
return errors.WithStack(errdefs.Conflict(errors.New("id already in use")))
|
||||
|
|
15
oci/oci.go
15
oci/oci.go
|
@ -8,13 +8,14 @@ import (
|
|||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
)
|
||||
|
||||
// TODO verify if this regex is correct for "a" (all); the docs (https://github.com/torvalds/linux/blob/v5.10/Documentation/admin-guide/cgroup-v1/devices.rst) describe:
|
||||
// "'all' means it applies to all types and all major and minor numbers", and shows an example
|
||||
// that *only* passes `a` as value: `echo a > /sys/fs/cgroup/1/devices.allow, which would be
|
||||
// the "implicit" equivalent of "a *:* rwm". Source-code also looks to confirm this, and returns
|
||||
// early for "a" (all); https://github.com/torvalds/linux/blob/v5.10/security/device_cgroup.c#L614-L642
|
||||
//nolint: gosimple
|
||||
var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$")
|
||||
// TODO verify if this regex is correct for "a" (all);
|
||||
//
|
||||
// The docs (https://github.com/torvalds/linux/blob/v5.10/Documentation/admin-guide/cgroup-v1/devices.rst) describe:
|
||||
// "'all' means it applies to all types and all major and minor numbers", and shows an example
|
||||
// that *only* passes `a` as value: `echo a > /sys/fs/cgroup/1/devices.allow, which would be
|
||||
// the "implicit" equivalent of "a *:* rwm". Source-code also looks to confirm this, and returns
|
||||
// early for "a" (all); https://github.com/torvalds/linux/blob/v5.10/security/device_cgroup.c#L614-L642
|
||||
var deviceCgroupRuleRegex = regexp.MustCompile("^([acb]) ([0-9]+|\\*):([0-9]+|\\*) ([rwm]{1,3})$") //nolint: gosimple
|
||||
|
||||
// SetCapabilities sets the provided capabilities on the spec
|
||||
// All capabilities are added if privileged is true.
|
||||
|
|
|
@ -1046,7 +1046,8 @@ loop:
|
|||
// Untar reads a stream of bytes from `archive`, parses it as a tar archive,
|
||||
// and unpacks it into the directory at `dest`.
|
||||
// The archive may be compressed with one of the following algorithms:
|
||||
// identity (uncompressed), gzip, bzip2, xz.
|
||||
// identity (uncompressed), gzip, bzip2, xz.
|
||||
//
|
||||
// FIXME: specify behavior when target path exists vs. doesn't exist.
|
||||
func Untar(tarArchive io.Reader, dest string, options *TarOptions) error {
|
||||
return untarHandler(tarArchive, dest, options, true)
|
||||
|
|
|
@ -15,13 +15,14 @@ import (
|
|||
|
||||
// setupOverlayTestDir creates files in a directory with overlay whiteouts
|
||||
// Tree layout
|
||||
// .
|
||||
// ├── d1 # opaque, 0700
|
||||
// │ └── f1 # empty file, 0600
|
||||
// ├── d2 # opaque, 0750
|
||||
// │ └── f1 # empty file, 0660
|
||||
// └── d3 # 0700
|
||||
// └── f1 # whiteout, 0644
|
||||
//
|
||||
// .
|
||||
// ├── d1 # opaque, 0700
|
||||
// │ └── f1 # empty file, 0600
|
||||
// ├── d2 # opaque, 0750
|
||||
// │ └── f1 # empty file, 0660
|
||||
// └── d3 # 0700
|
||||
// └── f1 # whiteout, 0644
|
||||
func setupOverlayTestDir(t *testing.T, src string) {
|
||||
skip.If(t, os.Getuid() != 0, "skipping test that requires root")
|
||||
skip.If(t, sys.RunningInUserNS(), "skipping test that requires initial userns (trusted.overlay.opaque xattr cannot be set in userns, even with Ubuntu kernel)")
|
||||
|
|
|
@ -297,9 +297,10 @@ func TestCopyLongDstFilename(t *testing.T) {
|
|||
// J | yes | yes | yes | yes | - | copy dir contents
|
||||
//
|
||||
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't
|
||||
// exist. This should create a file with the name DST and copy the
|
||||
// contents of the source file into it.
|
||||
// A. SRC specifies a file and DST (no trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should create a file with the name DST and copy the contents of the source
|
||||
// file into it.
|
||||
func TestCopyCaseA(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -339,9 +340,10 @@ func TestCopyCaseA(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't
|
||||
// exist. This should cause an error because the copy operation cannot
|
||||
// create a directory when copying a single file.
|
||||
// B. SRC specifies a file and DST (with trailing path separator) doesn't exist.
|
||||
//
|
||||
// This should cause an error because the copy operation cannot create a directory
|
||||
// when copying a single file.
|
||||
func TestCopyCaseB(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -373,8 +375,9 @@ func TestCopyCaseB(t *testing.T) {
|
|||
|
||||
}
|
||||
|
||||
// C. SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
// C. SRC specifies a file and DST exists as a file.
|
||||
//
|
||||
// This should overwrite the file at DST with the contents of the source file.
|
||||
func TestCopyCaseC(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -401,9 +404,9 @@ func TestCopyCaseC(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// C. Symbol link following version:
|
||||
// SRC specifies a file and DST exists as a file. This should overwrite
|
||||
// the file at DST with the contents of the source file.
|
||||
// C. Symbol link following version: SRC specifies a file and DST exists as a file.
|
||||
//
|
||||
// This should overwrite the file at DST with the contents of the source file.
|
||||
func TestCopyCaseCFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -438,9 +441,10 @@ func TestCopyCaseCFSym(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// D. SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// D. SRC specifies a file and DST exists as a directory.
|
||||
//
|
||||
// This should place a copy of the source file inside it using the basename from
|
||||
// SRC. Ensure this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseD(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -487,10 +491,10 @@ func TestCopyCaseD(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// D. Symbol link following version:
|
||||
// SRC specifies a file and DST exists as a directory. This should place
|
||||
// a copy of the source file inside it using the basename from SRC. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// D. Symbol link following version: SRC specifies a file and DST exists as a directory.
|
||||
//
|
||||
// This should place a copy of the source file inside it using the basename from
|
||||
// SRC. Ensure this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseDFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -538,10 +542,11 @@ func TestCopyCaseDFSym(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// E. SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
// E. SRC specifies a directory and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC directory
|
||||
// into the DST directory. Ensure this works whether DST has a trailing path
|
||||
// separator or not.
|
||||
func TestCopyCaseE(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -581,11 +586,11 @@ func TestCopyCaseE(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// E. Symbol link following version:
|
||||
// SRC specifies a directory and DST does not exist. This should create a
|
||||
// directory at DST and copy the contents of the SRC directory into the DST
|
||||
// directory. Ensure this works whether DST has a trailing path separator or
|
||||
// not.
|
||||
// E. Symbol link following version: SRC specifies a directory and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC directory
|
||||
// into the DST directory. Ensure this works whether DST has a trailing path
|
||||
// separator or not.
|
||||
func TestCopyCaseEFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -626,8 +631,10 @@ func TestCopyCaseEFSym(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// F. SRC specifies a directory and DST exists as a file. This should cause an
|
||||
// error as it is not possible to overwrite a file with a directory.
|
||||
// F. SRC specifies a directory and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func TestCopyCaseF(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -660,9 +667,10 @@ func TestCopyCaseF(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// G. SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
// G. SRC specifies a directory and DST exists as a directory.
|
||||
//
|
||||
// This should copy the SRC directory and all its contents to the DST directory.
|
||||
// Ensure this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseG(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -704,10 +712,10 @@ func TestCopyCaseG(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// G. Symbol link version:
|
||||
// SRC specifies a directory and DST exists as a directory. This should copy
|
||||
// the SRC directory and all its contents to the DST directory. Ensure this
|
||||
// works whether DST has a trailing path separator or not.
|
||||
// G. Symbol link version: SRC specifies a directory and DST exists as a directory.
|
||||
//
|
||||
// This should copy the SRC directory and all its contents to the DST directory.
|
||||
// Ensure this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseGFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -750,10 +758,11 @@ func TestCopyCaseGFSym(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// H. SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// H. SRC specifies a directory's contents only and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseH(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -797,11 +806,11 @@ func TestCopyCaseH(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// H. Symbol link following version:
|
||||
// SRC specifies a directory's contents only and DST does not exist. This
|
||||
// should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
// H. Symbol link following version: SRC specifies a directory's contents only and DST does not exist.
|
||||
//
|
||||
// This should create a directory at DST and copy the contents of the SRC
|
||||
// directory (but not the directory itself) into the DST directory. Ensure
|
||||
// this works whether DST has a trailing path separator or not.
|
||||
func TestCopyCaseHFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -846,9 +855,10 @@ func TestCopyCaseHFSym(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file. This
|
||||
// should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
// I. SRC specifies a directory's contents only and DST exists as a file.
|
||||
//
|
||||
// This should cause an error as it is not possible to overwrite a file with a
|
||||
// directory.
|
||||
func TestCopyCaseI(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -882,9 +892,10 @@ func TestCopyCaseI(t *testing.T) {
|
|||
}
|
||||
|
||||
// J. SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
//
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func TestCopyCaseJ(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
@ -930,11 +941,11 @@ func TestCopyCaseJ(t *testing.T) {
|
|||
assert.NilError(t, err)
|
||||
}
|
||||
|
||||
// J. Symbol link following version:
|
||||
// SRC specifies a directory's contents only and DST exists as a directory.
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
// J. Symbol link following version: SRC specifies a directory's contents only and DST exists as a directory.
|
||||
//
|
||||
// This should copy the contents of the SRC directory (but not the directory
|
||||
// itself) into the DST directory. Ensure this works whether DST has a
|
||||
// trailing path separator or not.
|
||||
func TestCopyCaseJFSym(t *testing.T) {
|
||||
tmpDirA, tmpDirB := getTestTempDirs(t)
|
||||
defer removeAllPaths(tmpDirA, tmpDirB)
|
||||
|
|
|
@ -17,8 +17,8 @@ import (
|
|||
// Generate("foo.txt", "hello world", "emptyfile")
|
||||
//
|
||||
// The above call will return an archive with 2 files:
|
||||
// * ./foo.txt with content "hello world"
|
||||
// * ./empty with empty content
|
||||
// - ./foo.txt with content "hello world"
|
||||
// - ./empty with empty content
|
||||
//
|
||||
// FIXME: stream content instead of buffering
|
||||
// FIXME: specify permissions and other archive metadata
|
||||
|
|
|
@ -33,7 +33,7 @@ func NewArchiver(idMapping *idtools.IdentityMapping) *archive.Archiver {
|
|||
// Untar reads a stream of bytes from `archive`, parses it as a tar archive,
|
||||
// and unpacks it into the directory at `dest`.
|
||||
// The archive may be compressed with one of the following algorithms:
|
||||
// identity (uncompressed), gzip, bzip2, xz.
|
||||
// identity (uncompressed), gzip, bzip2, xz.
|
||||
func Untar(tarArchive io.Reader, dest string, options *archive.TarOptions) error {
|
||||
return untarHandler(tarArchive, dest, options, true, dest)
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
// Same as DM_DEVICE_* enum values from libdevmapper.h
|
||||
//nolint: deadcode,unused,varcheck
|
||||
// nolint: deadcode,unused,varcheck
|
||||
const (
|
||||
deviceCreate TaskType = iota
|
||||
deviceReload
|
||||
|
|
|
@ -39,6 +39,7 @@ func LogInit(logger DevmapperLogger) {
|
|||
// because we are using callbacks, this function will be called for *every* log
|
||||
// in libdm (even debug ones because there's no way of setting the verbosity
|
||||
// level for an external logging callback).
|
||||
//
|
||||
//export DevmapperLogCallback
|
||||
func DevmapperLogCallback(level C.int, file *C.char, line, dmErrnoOrClass C.int, message *C.char) {
|
||||
msg := C.GoString(message)
|
||||
|
|
|
@ -22,6 +22,7 @@ type (
|
|||
)
|
||||
|
||||
// Deprecated: use github.com/moby/sys/mountinfo instead.
|
||||
//
|
||||
//nolint:golint
|
||||
var (
|
||||
Mounted = mountinfo.Mounted
|
||||
|
@ -34,6 +35,7 @@ var (
|
|||
// GetMounts is a function.
|
||||
//
|
||||
// Deprecated: use github.com/moby/sys/mountinfo.GetMounts() instead.
|
||||
//
|
||||
//nolint:golint
|
||||
func GetMounts(f FilterFunc) ([]*Info, error) {
|
||||
fi := func(i *mountinfo.Info) (skip, stop bool) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
)
|
||||
|
||||
// Deprecated: use github.com/moby/sys/mount instead.
|
||||
//
|
||||
//nolint:golint
|
||||
var (
|
||||
MakeMount = sysmount.MakeMount
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
)
|
||||
|
||||
// Deprecated: use github.com/moby/sys/mount instead.
|
||||
//
|
||||
//nolint:golint
|
||||
var (
|
||||
Mount = sysmount.Mount
|
||||
|
@ -20,6 +21,7 @@ var (
|
|||
)
|
||||
|
||||
// Deprecated: use github.com/moby/sys/mount instead.
|
||||
//
|
||||
//nolint:golint
|
||||
const (
|
||||
RDONLY = sysmount.RDONLY
|
||||
|
@ -47,6 +49,7 @@ const (
|
|||
)
|
||||
|
||||
// Deprecated: use github.com/moby/sys/mount instead.
|
||||
//
|
||||
//nolint:golint
|
||||
var (
|
||||
MergeTmpfsOptions = sysmount.MergeTmpfsOptions
|
||||
|
|
|
@ -25,13 +25,14 @@ func ParseKeyValueOpt(opt string) (string, string, error) {
|
|||
// set to `true`. Values larger than `maximum` cause an error if max is non zero,
|
||||
// in order to stop the map becoming excessively large.
|
||||
// Supported formats:
|
||||
// 7
|
||||
// 1-6
|
||||
// 0,3-4,7,8-10
|
||||
// 0-0,0,1-7
|
||||
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
||||
// 3,2,1
|
||||
// 0-2,3,1
|
||||
//
|
||||
// 7
|
||||
// 1-6
|
||||
// 0,3-4,7,8-10
|
||||
// 0-0,0,1-7
|
||||
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
||||
// 3,2,1
|
||||
// 0-2,3,1
|
||||
func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) {
|
||||
return parseUintList(val, maximum)
|
||||
}
|
||||
|
@ -42,13 +43,14 @@ func ParseUintListMaximum(val string, maximum int) (map[int]bool, error) {
|
|||
// input string. It returns a `map[int]bool` with available elements from `val`
|
||||
// set to `true`.
|
||||
// Supported formats:
|
||||
// 7
|
||||
// 1-6
|
||||
// 0,3-4,7,8-10
|
||||
// 0-0,0,1-7
|
||||
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
||||
// 3,2,1
|
||||
// 0-2,3,1
|
||||
//
|
||||
// 7
|
||||
// 1-6
|
||||
// 0,3-4,7,8-10
|
||||
// 0-0,0,1-7
|
||||
// 03,1-3 <- this is gonna get parsed as [1,2,3]
|
||||
// 3,2,1
|
||||
// 0-2,3,1
|
||||
func ParseUintList(val string) (map[int]bool, error) {
|
||||
return parseUintList(val, 0)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// A handshake is send at /Plugin.Activate, and plugins are expected to return
|
||||
// a Manifest with a list of Docker subsystems which this plugin implements.
|
||||
//
|
||||
// In order to use a plugins, you can use the ``Get`` with the name of the
|
||||
// In order to use a plugins, you can use the `Get` with the name of the
|
||||
// plugin and the subsystem it implements.
|
||||
//
|
||||
// plugin, err := plugins.Get("example", "VolumeDriver")
|
||||
|
|
|
@ -18,14 +18,13 @@ import (
|
|||
// behavior expected from a vanilla unix command-line tool in general
|
||||
// (and the Docker engine in particular).
|
||||
//
|
||||
// * If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated.
|
||||
// * If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is
|
||||
// skipped and the process is terminated immediately (allows force quit of stuck daemon)
|
||||
// * A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit.
|
||||
// * Ignore SIGPIPE events. These are generated by systemd when journald is restarted while
|
||||
// the docker daemon is not restarted and also running under systemd.
|
||||
// Fixes https://github.com/docker/docker/issues/19728
|
||||
//
|
||||
// - If SIGINT or SIGTERM are received, `cleanup` is called, then the process is terminated.
|
||||
// - If SIGINT or SIGTERM are received 3 times before cleanup is complete, then cleanup is
|
||||
// skipped and the process is terminated immediately (allows force quit of stuck daemon)
|
||||
// - A SIGQUIT always causes an exit without cleanup, with a goroutine dump preceding exit.
|
||||
// - Ignore SIGPIPE events. These are generated by systemd when journald is restarted while
|
||||
// the docker daemon is not restarted and also running under systemd.
|
||||
// Fixes https://github.com/docker/docker/issues/19728
|
||||
func Trap(cleanup func(), logger interface {
|
||||
Info(args ...interface{})
|
||||
}) {
|
||||
|
|
|
@ -27,7 +27,7 @@ type memorystatusex struct {
|
|||
}
|
||||
|
||||
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||
// MemInfo type.
|
||||
// MemInfo type.
|
||||
func ReadMemInfo() (*MemInfo, error) {
|
||||
msi := &memorystatusex{
|
||||
dwLength: 64,
|
||||
|
|
|
@ -14,16 +14,14 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
/* allowV1PluginsFallback determines daemon's support for V1 plugins.
|
||||
* When the time comes to remove support for V1 plugins, flipping
|
||||
* this bool is all that will be needed.
|
||||
*/
|
||||
// allowV1PluginsFallback determines daemon's support for V1 plugins.
|
||||
// When the time comes to remove support for V1 plugins, flipping
|
||||
// this bool is all that will be needed.
|
||||
const allowV1PluginsFallback = true
|
||||
|
||||
/* defaultAPIVersion is the version of the plugin API for volume, network,
|
||||
IPAM and authz. This is a very stable API. When we update this API, then
|
||||
pluginType should include a version. e.g. "networkdriver/2.0".
|
||||
*/
|
||||
// defaultAPIVersion is the version of the plugin API for volume, network,
|
||||
// IPAM and authz. This is a very stable API. When we update this API, then
|
||||
// pluginType should include a version. e.g. "networkdriver/2.0".
|
||||
const defaultAPIVersion = "1.0"
|
||||
|
||||
// GetV2Plugin retrieves a plugin by name, id or partial ID.
|
||||
|
|
|
@ -102,9 +102,10 @@ func (state *pquotaState) updateMinProjID(minProjectID uint32) {
|
|||
// This test will fail if the backing fs is not xfs.
|
||||
//
|
||||
// xfs_quota tool can be used to assign a project id to the driver home directory, e.g.:
|
||||
// echo 999:/var/lib/docker/overlay2 >> /etc/projects
|
||||
// echo docker:999 >> /etc/projid
|
||||
// xfs_quota -x -c 'project -s docker' /<xfs mount point>
|
||||
//
|
||||
// echo 999:/var/lib/docker/overlay2 >> /etc/projects
|
||||
// echo docker:999 >> /etc/projid
|
||||
// xfs_quota -x -c 'project -s docker' /<xfs mount point>
|
||||
//
|
||||
// In that case, the home directory project id will be used as a "start offset"
|
||||
// and all containers will be assigned larger project ids (e.g. >= 1000).
|
||||
|
@ -113,7 +114,6 @@ func (state *pquotaState) updateMinProjID(minProjectID uint32) {
|
|||
// Then try to create a test directory with the next project id and set a quota
|
||||
// on it. If that works, continue to scan existing containers to map allocated
|
||||
// project ids.
|
||||
//
|
||||
func NewControl(basePath string) (*Control, error) {
|
||||
//
|
||||
// If we are running in a user namespace quota won't be supported for
|
||||
|
|
|
@ -21,13 +21,13 @@ const extName = "VolumeDriver"
|
|||
// volumeDriver defines the available functions that volume plugins must implement.
|
||||
// This interface is only defined to generate the proxy objects.
|
||||
// It's not intended to be public or reused.
|
||||
//nolint: deadcode
|
||||
// nolint: deadcode,unused,varcheck
|
||||
type volumeDriver interface {
|
||||
// Create a volume with the given name
|
||||
Create(name string, opts map[string]string) (err error)
|
||||
// Remove the volume with the given name
|
||||
Remove(name string) (err error)
|
||||
// Get the mountpoint of the given volume
|
||||
// Path returns the mountpoint of the given volume.
|
||||
Path(name string) (mountpoint string, err error)
|
||||
// Mount the given volume and return the mountpoint
|
||||
Mount(name, id string) (mountpoint string, err error)
|
||||
|
|
|
@ -549,7 +549,7 @@ func volumeExists(ctx context.Context, store *drivers.Store, v volume.Volume) (b
|
|||
// create asks the given driver to create a volume with the name/opts.
|
||||
// If a volume with the name is already known, it will ask the stored driver for the volume.
|
||||
// If the passed in driver name does not match the driver name which is stored
|
||||
// for the given volume name, an error is returned after checking if the reference is stale.
|
||||
// for the given volume name, an error is returned after checking if the reference is stale.
|
||||
// If the reference is stale, it will be purged and this create can continue.
|
||||
// It is expected that callers of this function hold any necessary locks.
|
||||
func (s *VolumeStore) create(ctx context.Context, name, driverName string, opts, labels map[string]string) (volume.Volume, error) {
|
||||
|
@ -728,9 +728,9 @@ func (s *VolumeStore) getVolume(ctx context.Context, name, driverName string) (v
|
|||
|
||||
// lookupVolume gets the specified volume from the specified driver.
|
||||
// This will only return errors related to communications with the driver.
|
||||
// If the driver returns an error that is not communication related the
|
||||
// error is logged but not returned.
|
||||
// If the volume is not found it will return `nil, nil``
|
||||
// If the driver returns an error that is not communication related, the error
|
||||
// is logged but not returned.
|
||||
// If the volume is not found it will return `nil, nil`
|
||||
// TODO(@cpuguy83): plumb through the context to lower level components
|
||||
func lookupVolume(ctx context.Context, store *drivers.Store, driverName, volumeName string) (volume.Volume, error) {
|
||||
if driverName == "" {
|
||||
|
|
Loading…
Reference in a new issue