mirror of
https://github.com/docker/cli.git
synced 2026-08-25 10:05:26 -05:00
Compare commits
46
Commits
v19.03.13-beta2
...
19.03
+1
-1
@@ -4,7 +4,7 @@ clone_folder: c:\gopath\src\github.com\docker\cli
|
||||
|
||||
environment:
|
||||
GOPATH: c:\gopath
|
||||
GOVERSION: 1.13.14
|
||||
GOVERSION: 1.13.15
|
||||
DEPVERSION: v0.4.1
|
||||
|
||||
install:
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
// ListOptions contains options for the docker config ls command.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -30,20 +26,3 @@ func NewContextCommand(dockerCli command.Cli) *cobra.Command {
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = regexp.MustCompile(restrictedNamePattern)
|
||||
|
||||
func validateContextName(name string) error {
|
||||
if name == "" {
|
||||
return errors.New("context name cannot be empty")
|
||||
}
|
||||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ func createNewContext(o *CreateOptions, stackOrchestrator command.Orchestrator,
|
||||
}
|
||||
|
||||
func checkContextNameForCreation(s store.Reader, name string) error {
|
||||
if err := validateContextName(name); err != nil {
|
||||
if err := store.ValidateContextName(name); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := s.GetMetadata(name); !store.IsErrContextDoesNotExist(err) {
|
||||
|
||||
@@ -77,7 +77,7 @@ func writeTo(dockerCli command.Cli, reader io.Reader, dest string) error {
|
||||
|
||||
// RunExport exports a Docker context
|
||||
func RunExport(dockerCli command.Cli, opts *ExportOptions) error {
|
||||
if err := validateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName {
|
||||
if err := store.ValidateContextName(opts.ContextName); err != nil && opts.ContextName != command.DefaultContextName {
|
||||
return err
|
||||
}
|
||||
ctxMeta, err := dockerCli.ContextStore().GetMetadata(opts.ContextName)
|
||||
|
||||
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/cli/context/docker"
|
||||
kubecontext "github.com/docker/cli/cli/context/kubernetes"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -68,7 +68,7 @@ func newUpdateCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
// RunUpdate updates a Docker context
|
||||
func RunUpdate(cli command.Cli, o *UpdateOptions) error {
|
||||
if err := validateContextName(o.Name); err != nil {
|
||||
if err := store.ValidateContextName(o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
s := cli.ContextStore()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/context/store"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -23,7 +24,7 @@ func newUseCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
// RunUse set the current Docker context
|
||||
func RunUse(dockerCli command.Cli, name string) error {
|
||||
if err := validateContextName(name); err != nil && name != "default" {
|
||||
if err := store.ValidateContextName(name); err != nil && name != "default" {
|
||||
return err
|
||||
}
|
||||
if _, err := dockerCli.ContextStore().GetMetadata(name); err != nil && name != "default" {
|
||||
|
||||
@@ -81,6 +81,14 @@ func TestNewImportCommandSuccess(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "change",
|
||||
args: []string{"--change", "ENV DEBUG=true", "-"},
|
||||
imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
|
||||
assert.Check(t, is.Equal("ENV DEBUG=true", options.Changes[0]))
|
||||
return ioutil.NopCloser(strings.NewReader("")), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "change legacy syntax",
|
||||
args: []string{"--change", "ENV DEBUG true", "-"},
|
||||
imageImportFunc: func(source types.ImageImportSource, ref string, options types.ImageImportOptions) (io.ReadCloser, error) {
|
||||
assert.Check(t, is.Equal("ENV DEBUG true", options.Changes[0]))
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"vbom.ml/util/sortorder"
|
||||
|
||||
"github.com/docker/cli/cli"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
@@ -14,6 +12,7 @@ import (
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
"github.com/docker/cli/cli/command/stack/kubernetes"
|
||||
"github.com/docker/cli/cli/command/stack/options"
|
||||
"github.com/docker/cli/cli/command/stack/swarm"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
func newListCommand(dockerCli command.Cli, common *commonOptions) *cobra.Command {
|
||||
|
||||
@@ -16,8 +16,8 @@ import (
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/docker/docker/api/types/versions"
|
||||
"github.com/docker/go-units"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type pruneOptions struct {
|
||||
|
||||
@@ -10,11 +10,11 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/image"
|
||||
"github.com/docker/cli/cli/trust"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
// trustTagKey represents a unique signed tag and hex-encoded hash pair
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
func prettyPrintTrustInfo(cli command.Cli, remote string) error {
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/docker/cli/cli/command/formatter"
|
||||
"github.com/docker/cli/opts"
|
||||
"github.com/fvbommel/sortorder"
|
||||
"github.com/spf13/cobra"
|
||||
"vbom.ml/util/sortorder"
|
||||
)
|
||||
|
||||
type listOptions struct {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"vbom.ml/util/sortorder"
|
||||
"github.com/fvbommel/sortorder"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -7,19 +7,24 @@ import (
|
||||
"bytes"
|
||||
_ "crypto/sha256" // ensure ids can be computed
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/docker/errdefs"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const restrictedNamePattern = "^[a-zA-Z0-9][a-zA-Z0-9_.+-]+$"
|
||||
|
||||
var restrictedNameRegEx = regexp.MustCompile(restrictedNamePattern)
|
||||
|
||||
// Store provides a context store for easily remembering endpoints configuration
|
||||
type Store interface {
|
||||
Reader
|
||||
@@ -184,6 +189,20 @@ func (s *store) GetStorageInfo(contextName string) StorageInfo {
|
||||
}
|
||||
}
|
||||
|
||||
// ValidateContextName checks a context name is valid.
|
||||
func ValidateContextName(name string) error {
|
||||
if name == "" {
|
||||
return errors.New("context name cannot be empty")
|
||||
}
|
||||
if name == "default" {
|
||||
return errors.New(`"default" is a reserved context name`)
|
||||
}
|
||||
if !restrictedNameRegEx.MatchString(name) {
|
||||
return fmt.Errorf("context name %q is invalid, names are validated against regexp %q", name, restrictedNamePattern)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Export exports an existing namespace into an opaque data stream
|
||||
// This stream is actually a tarball containing context metadata and TLS materials, but it does
|
||||
// not map 1:1 the layout of the context store (don't try to restore it manually without calling store.Import)
|
||||
@@ -295,6 +314,19 @@ func Import(name string, s Writer, reader io.Reader) error {
|
||||
}
|
||||
}
|
||||
|
||||
func isValidFilePath(p string) error {
|
||||
if p != metaFile && !strings.HasPrefix(p, "tls/") {
|
||||
return errors.New("unexpected context file")
|
||||
}
|
||||
if path.Clean(p) != p {
|
||||
return errors.New("unexpected path format")
|
||||
}
|
||||
if strings.Contains(p, `\`) {
|
||||
return errors.New(`unexpected '\' in path`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func importTar(name string, s Writer, reader io.Reader) error {
|
||||
tr := tar.NewReader(&LimitedReader{R: reader, N: maxAllowedFileSizeToImport})
|
||||
tlsData := ContextTLSData{
|
||||
@@ -309,10 +341,13 @@ func importTar(name string, s Writer, reader io.Reader) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hdr.Typeflag == tar.TypeDir {
|
||||
if hdr.Typeflag != tar.TypeReg {
|
||||
// skip this entry, only taking files into account
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(hdr.Name); err != nil {
|
||||
return errors.Wrap(err, hdr.Name)
|
||||
}
|
||||
if hdr.Name == metaFile {
|
||||
data, err := ioutil.ReadAll(tr)
|
||||
if err != nil {
|
||||
@@ -358,10 +393,13 @@ func importZip(name string, s Writer, reader io.Reader) error {
|
||||
var importedMetaFile bool
|
||||
for _, zf := range zr.File {
|
||||
fi := zf.FileInfo()
|
||||
if fi.IsDir() {
|
||||
// skip this entry, only taking files into account
|
||||
if !fi.Mode().IsRegular() {
|
||||
// skip this entry, only taking regular files into account
|
||||
continue
|
||||
}
|
||||
if err := isValidFilePath(zf.Name); err != nil {
|
||||
return errors.Wrap(err, zf.Name)
|
||||
}
|
||||
if zf.Name == metaFile {
|
||||
f, err := zf.Open()
|
||||
if err != nil {
|
||||
@@ -408,6 +446,9 @@ func parseMetadata(data []byte, name string) (Metadata, error) {
|
||||
if err := json.Unmarshal(data, &meta); err != nil {
|
||||
return meta, err
|
||||
}
|
||||
if err := ValidateContextName(name); err != nil {
|
||||
return Metadata{}, err
|
||||
}
|
||||
meta.Name = name
|
||||
return meta, nil
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ func TestImportTarInvalid(t *testing.T) {
|
||||
var r io.Reader = source
|
||||
s := New(testDir, testCfg)
|
||||
err = Import("tarInvalid", s, r)
|
||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
||||
assert.ErrorContains(t, err, "unexpected context file")
|
||||
}
|
||||
|
||||
func TestImportZip(t *testing.T) {
|
||||
@@ -254,5 +254,5 @@ func TestImportZipInvalid(t *testing.T) {
|
||||
var r io.Reader = source
|
||||
s := New(testDir, testCfg)
|
||||
err = Import("zipInvalid", s, r)
|
||||
assert.ErrorContains(t, err, "invalid context: no metadata found")
|
||||
assert.ErrorContains(t, err, "unexpected context file")
|
||||
}
|
||||
|
||||
@@ -29,3 +29,32 @@ func TestConfigModification(t *testing.T) {
|
||||
assert.Equal(t, &testEP2{}, cfgCopy.endpointTypes["ep1"]())
|
||||
assert.Equal(t, &testEP3{}, cfgCopy.endpointTypes["ep2"]())
|
||||
}
|
||||
|
||||
func TestValidFilePaths(t *testing.T) {
|
||||
paths := map[string]bool{
|
||||
"tls/_/../../something": false,
|
||||
"tls/../../something": false,
|
||||
"../../something": false,
|
||||
"/tls/absolute/unix/path": false,
|
||||
`C:\tls\absolute\windows\path`: false,
|
||||
"C:/tls/absolute/windows/path": false,
|
||||
"tls/kubernetes/key.pem": true,
|
||||
}
|
||||
for p, expectedValid := range paths {
|
||||
err := isValidFilePath(p)
|
||||
assert.Equal(t, err == nil, expectedValid, "%q should report valid as: %v", p, expectedValid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateContextName(t *testing.T) {
|
||||
names := map[string]bool{
|
||||
"../../invalid/escape": false,
|
||||
"/invalid/absolute": false,
|
||||
`\invalid\windows`: false,
|
||||
"validname": true,
|
||||
}
|
||||
for n, expectedValid := range names {
|
||||
err := ValidateContextName(n)
|
||||
assert.Equal(t, err == nil, expectedValid, "%q should report valid as: %v", n, expectedValid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,55 +831,58 @@ __docker_complete_local_ips() {
|
||||
# not granted by default and may be added.
|
||||
# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
|
||||
__docker_complete_capabilities_addable() {
|
||||
COMPREPLY=( $( compgen -W "
|
||||
local capabilities=(
|
||||
ALL
|
||||
AUDIT_CONTROL
|
||||
BLOCK_SUSPEND
|
||||
DAC_READ_SEARCH
|
||||
IPC_LOCK
|
||||
IPC_OWNER
|
||||
LEASE
|
||||
LINUX_IMMUTABLE
|
||||
MAC_ADMIN
|
||||
MAC_OVERRIDE
|
||||
NET_ADMIN
|
||||
NET_BROADCAST
|
||||
SYS_ADMIN
|
||||
SYS_BOOT
|
||||
SYSLOG
|
||||
SYS_MODULE
|
||||
SYS_NICE
|
||||
SYS_PACCT
|
||||
SYS_PTRACE
|
||||
SYS_RAWIO
|
||||
SYS_RESOURCE
|
||||
SYS_TIME
|
||||
SYS_TTY_CONFIG
|
||||
WAKE_ALARM
|
||||
" -- "$cur" ) )
|
||||
CAP_AUDIT_CONTROL
|
||||
CAP_AUDIT_READ
|
||||
CAP_BLOCK_SUSPEND
|
||||
CAP_DAC_READ_SEARCH
|
||||
CAP_IPC_LOCK
|
||||
CAP_IPC_OWNER
|
||||
CAP_LEASE
|
||||
CAP_LINUX_IMMUTABLE
|
||||
CAP_MAC_ADMIN
|
||||
CAP_MAC_OVERRIDE
|
||||
CAP_NET_ADMIN
|
||||
CAP_NET_BROADCAST
|
||||
CAP_SYS_ADMIN
|
||||
CAP_SYS_BOOT
|
||||
CAP_SYSLOG
|
||||
CAP_SYS_MODULE
|
||||
CAP_SYS_NICE
|
||||
CAP_SYS_PACCT
|
||||
CAP_SYS_PTRACE
|
||||
CAP_SYS_RAWIO
|
||||
CAP_SYS_RESOURCE
|
||||
CAP_SYS_TIME
|
||||
CAP_SYS_TTY_CONFIG
|
||||
CAP_WAKE_ALARM
|
||||
)
|
||||
COMPREPLY=( $( compgen -W "${capabilities[*]} ${capabilities[*]#CAP_}" -- "$cur" ) )
|
||||
}
|
||||
|
||||
# __docker_complete_capabilities_droppable completes Linux capability options which are
|
||||
# allowed by default and can be dropped.
|
||||
# see https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities
|
||||
__docker_complete_capabilities_droppable() {
|
||||
COMPREPLY=( $( compgen -W "
|
||||
local capabilities=(
|
||||
ALL
|
||||
AUDIT_WRITE
|
||||
CHOWN
|
||||
DAC_OVERRIDE
|
||||
FOWNER
|
||||
FSETID
|
||||
KILL
|
||||
MKNOD
|
||||
NET_BIND_SERVICE
|
||||
NET_RAW
|
||||
SETFCAP
|
||||
SETGID
|
||||
SETPCAP
|
||||
SETUID
|
||||
SYS_CHROOT
|
||||
" -- "$cur" ) )
|
||||
CAP_AUDIT_WRITE
|
||||
CAP_CHOWN
|
||||
CAP_DAC_OVERRIDE
|
||||
CAP_FOWNER
|
||||
CAP_FSETID
|
||||
CAP_KILL
|
||||
CAP_MKNOD
|
||||
CAP_NET_BIND_SERVICE
|
||||
CAP_NET_RAW
|
||||
CAP_SETFCAP
|
||||
CAP_SETGID
|
||||
CAP_SETPCAP
|
||||
CAP_SETUID
|
||||
CAP_SYS_CHROOT
|
||||
)
|
||||
COMPREPLY=( $( compgen -W "${capabilities[*]} ${capabilities[*]#CAP_}" -- "$cur" ) )
|
||||
}
|
||||
|
||||
__docker_complete_detach_keys() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG GO_VERSION=1.13.14
|
||||
ARG GO_VERSION=1.13.15
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG GO_VERSION=1.13.14
|
||||
ARG GO_VERSION=1.13.15
|
||||
|
||||
FROM dockercore/golang-cross:${GO_VERSION}
|
||||
ENV DISABLE_WARN_OUTSIDE_CONTAINER=1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG GO_VERSION=1.13.14
|
||||
ARG GO_VERSION=1.13.15
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG GO_VERSION=1.13.14
|
||||
ARG GO_VERSION=1.13.15
|
||||
|
||||
# Use Debian based image as docker-compose requires glibc.
|
||||
FROM golang:${GO_VERSION}-buster
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# syntax=docker/dockerfile:1.1.3-experimental
|
||||
|
||||
ARG GO_VERSION=1.13.14
|
||||
ARG GO_VERSION=1.13.15
|
||||
ARG GOLANGCI_LINTER_SHA="v1.21.0"
|
||||
|
||||
FROM golang:${GO_VERSION}-alpine AS build
|
||||
|
||||
+63
-55
@@ -50,49 +50,55 @@ The table below provides an overview of the current status of deprecated feature
|
||||
|
||||
Status | Feature | Deprecated | Remove
|
||||
-----------|------------------------------------------------------------------------------------------------------------------------------------|------------|------------
|
||||
Deprecated | [Pushing and pulling with image manifest v2 schema 1](#pushing-and-pulling-with-image-manifest-v2-schema-1) | v19.03.0 | v20.03.0
|
||||
Deprecated | [`docker engine` subcommands](#docker-engine-subcommands) | v19.03.0 | v20.03.0
|
||||
Deprecated | [Top-level `docker deploy` subcommand (experimental)](#top-level-docker-deploy-subcommand-experimental) | v19.03.0 | v20.03.0
|
||||
Deprecated | [`docker stack deploy` using "dab" files (experimental)](#docker-stack-deploy-using-dab-files-experimental) | v19.03.0 | v20.03.0
|
||||
Deprecated | [AuFS storage driver](#aufs-storage-driver) | v19.03.0 | -
|
||||
Deprecated | [Legacy "overlay" storage driver](#legacy-overlay-storage-driver) | v18.09.0 | -
|
||||
Deprecated | [Device mapper storage driver](#device-mapper-storage-driver) | v18.09.0 | -
|
||||
Deprecated | [Reserved namespaces in engine labels](#reserved-namespaces-in-engine-labels) | v18.06.0 | v20.03.0
|
||||
Removed | [`--disable-legacy-registry` override daemon option](#--disable-legacy-registry-override-daemon-option) | v17.12.0 | v19.03.0
|
||||
Removed | [Interacting with V1 registries](#interacting-with-v1-registries) | v17.06.0 | v17.12.0
|
||||
Removed | [Asynchronous `service create` and `service update` as default](#asynchronous-service-create-and-service-update-as-default) | v17.05.0 | v17.10.0
|
||||
Removed | [`-g` and `--graph` flags on `dockerd`](#-g-and---graph-flags-on-dockerd) | v17.05.0 | -
|
||||
Deprecated | [Top-level network properties in NetworkSettings](#top-level-network-properties-in-networksettings) | v1.13.0 | v17.12.0
|
||||
Deprecated | [`filter` param for `/images/json` endpoint](#filter-param-for-imagesjson-endpoint) | v1.13.0 | v17.12.0
|
||||
Removed | [`repository:shortid` image references](#repositoryshortid-image-references) | v1.13.0 | v17.12.0
|
||||
Removed | [`docker daemon` subcommand](#docker-daemon-subcommand) | v1.13.0 | v17.12.0
|
||||
Removed | [Duplicate keys with conflicting values in engine labels](#duplicate-keys-with-conflicting-values-in-engine-labels) | v1.13.0 | v17.12.0
|
||||
Deprecated | [`MAINTAINER` in Dockerfile](#maintainer-in-dockerfile) | v1.13.0 | -
|
||||
Deprecated | [API calls without a version](#api-calls-without-a-version) | v1.13.0 | v17.12.0
|
||||
Removed | [Backing filesystem without `d_type` support for overlay/overlay2](#backing-filesystem-without-d_type-support-for-overlayoverlay2) | v1.13.0 | v17.12.0
|
||||
Deprecated | [`--automated` and `--stars` flags on `docker search`](#--automated-and---stars-flags-on-docker-search) | v1.12.0 | v17.09.0
|
||||
Deprecated | [`-h` shorthand for `--help`](#-h-shorthand-for---help) | v1.12.0 | v17.09.0
|
||||
Removed | [`-e` and `--email` flags on `docker login`](#-e-and---email-flags-on-docker-login) | v1.11.0 | v17.06.0
|
||||
Deprecated | [Separator (`:`) of `--security-opt` flag on `docker run`](#separator--of---security-opt-flag-on-docker-run) | v1.11.0 | v17.06.0
|
||||
Deprecated | [Ambiguous event fields in API](#ambiguous-event-fields-in-api) | v1.10.0 | -
|
||||
Removed | [`-f` flag on `docker tag`](#-f-flag-on-docker-tag) | v1.10.0 | v1.12.0
|
||||
Removed | [HostConfig at API container start](#hostconfig-at-api-container-start) | v1.10.0 | v1.12.0
|
||||
Removed | [`--before` and `--since` flags on `docker ps`](#--before-and---since-flags-on-docker-ps) | v1.10.0 | v1.12.0
|
||||
Removed | [Driver-specific log tags](#driver-specific-log-tags) | v1.9.0 | v1.12.0
|
||||
Removed | [Docker Content Trust `ENV` passphrase variables name change](#docker-content-trust-env-passphrase-variables-name-change) | v1.9.0 | v1.12.0
|
||||
Removed | [`/containers/(id or name)/copy` endpoint](#containersid-or-namecopy-endpoint) | v1.8.0 | v1.12.0
|
||||
Removed | [LXC built-in exec driver](#lxc-built-in-exec-driver) | v1.8.0 | v1.10.0
|
||||
Removed | [Old Command Line Options](#old-command-line-options) | v1.8.0 | v1.10.0
|
||||
Removed | [`--api-enable-cors` flag on `dockerd`](#--api-enable-cors-flag-on-dockerd) | v1.6.0 | v17.09.0
|
||||
Removed | [`--run` flag on `docker commit`](#--run-flag-on-docker-commit) | v0.10.0 | v1.13.0
|
||||
Removed | [Three arguments form in `docker import`](#three-arguments-form-in-docker-import) | v0.6.7 | v1.12.0
|
||||
Deprecated | [Configuration options for experimental CLI features](#configuration-options-for-experimental-cli-features) | v19.03 | v20.10
|
||||
Deprecated | [Pushing and pulling with image manifest v2 schema 1](#pushing-and-pulling-with-image-manifest-v2-schema-1) | v19.03 | v20.10
|
||||
Deprecated | [`docker engine` subcommands](#docker-engine-subcommands) | v19.03 | v20.10
|
||||
Deprecated | [Top-level `docker deploy` subcommand (experimental)](#top-level-docker-deploy-subcommand-experimental) | v19.03 | v20.10
|
||||
Deprecated | [`docker stack deploy` using "dab" files (experimental)](#docker-stack-deploy-using-dab-files-experimental) | v19.03 | v20.10
|
||||
Deprecated | [AuFS storage driver](#aufs-storage-driver) | v19.03 | -
|
||||
Deprecated | [Legacy "overlay" storage driver](#legacy-overlay-storage-driver) | v18.09 | -
|
||||
Deprecated | [Device mapper storage driver](#device-mapper-storage-driver) | v18.09 | -
|
||||
Deprecated | [Use of reserved namespaces in engine labels](#use-of-reserved-namespaces-in-engine-labels) | v18.06 | v20.10
|
||||
Removed | [`--disable-legacy-registry` override daemon option](#--disable-legacy-registry-override-daemon-option) | v17.12 | v19.03
|
||||
Removed | [Interacting with V1 registries](#interacting-with-v1-registries) | v17.06 | v17.12
|
||||
Removed | [Asynchronous `service create` and `service update` as default](#asynchronous-service-create-and-service-update-as-default) | v17.05 | v17.10
|
||||
Removed | [`-g` and `--graph` flags on `dockerd`](#-g-and---graph-flags-on-dockerd) | v17.05 | -
|
||||
Deprecated | [Top-level network properties in NetworkSettings](#top-level-network-properties-in-networksettings) | v1.13 | v17.12
|
||||
Deprecated | [`filter` param for `/images/json` endpoint](#filter-param-for-imagesjson-endpoint) | v1.13 | v20.10
|
||||
Removed | [`repository:shortid` image references](#repositoryshortid-image-references) | v1.13 | v17.12
|
||||
Removed | [`docker daemon` subcommand](#docker-daemon-subcommand) | v1.13 | v17.12
|
||||
Removed | [Duplicate keys with conflicting values in engine labels](#duplicate-keys-with-conflicting-values-in-engine-labels) | v1.13 | v17.12
|
||||
Deprecated | [`MAINTAINER` in Dockerfile](#maintainer-in-dockerfile) | v1.13 | -
|
||||
Deprecated | [API calls without a version](#api-calls-without-a-version) | v1.13 | v17.12
|
||||
Removed | [Backing filesystem without `d_type` support for overlay/overlay2](#backing-filesystem-without-d_type-support-for-overlayoverlay2) | v1.13 | v17.12
|
||||
Deprecated | [`--automated` and `--stars` flags on `docker search`](#--automated-and---stars-flags-on-docker-search) | v1.12 | v20.10
|
||||
Deprecated | [`-h` shorthand for `--help`](#-h-shorthand-for---help) | v1.12 | v17.09
|
||||
Removed | [`-e` and `--email` flags on `docker login`](#-e-and---email-flags-on-docker-login) | v1.11 | v17.06
|
||||
Deprecated | [Separator (`:`) of `--security-opt` flag on `docker run`](#separator--of---security-opt-flag-on-docker-run) | v1.11 | v17.06
|
||||
Deprecated | [Ambiguous event fields in API](#ambiguous-event-fields-in-api) | v1.10 | -
|
||||
Removed | [`-f` flag on `docker tag`](#-f-flag-on-docker-tag) | v1.10 | v1.12
|
||||
Removed | [HostConfig at API container start](#hostconfig-at-api-container-start) | v1.10 | v1.12
|
||||
Removed | [`--before` and `--since` flags on `docker ps`](#--before-and---since-flags-on-docker-ps) | v1.10 | v1.12
|
||||
Removed | [Driver-specific log tags](#driver-specific-log-tags) | v1.9 | v1.12
|
||||
Removed | [Docker Content Trust `ENV` passphrase variables name change](#docker-content-trust-env-passphrase-variables-name-change) | v1.9 | v1.12
|
||||
Removed | [`/containers/(id or name)/copy` endpoint](#containersid-or-namecopy-endpoint) | v1.8 | v1.12
|
||||
Removed | [LXC built-in exec driver](#lxc-built-in-exec-driver) | v1.8 | v1.10
|
||||
Removed | [Old Command Line Options](#old-command-line-options) | v1.8 | v1.10
|
||||
Removed | [`--api-enable-cors` flag on `dockerd`](#--api-enable-cors-flag-on-dockerd) | v1.6 | v17.09
|
||||
Removed | [`--run` flag on `docker commit`](#--run-flag-on-docker-commit) | v0.10 | v1.13
|
||||
Removed | [Three arguments form in `docker import`](#three-arguments-form-in-docker-import) | v0.6.7 | v1.12
|
||||
|
||||
### Configuration options for experimental CLI features
|
||||
|
||||
The `DOCKER_CLI_EXPERIMENTAL` environment variable and the corresponding `experimental`
|
||||
field in the CLI configuration file are deprecated. Experimental features will be
|
||||
enabled by default, and these configuration options will no longer be functional.
|
||||
|
||||
### Pushing and pulling with image manifest v2 schema 1
|
||||
|
||||
**Deprecated in Release: v19.03.0**
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
**Target For Removal In Release: v20.03.0**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The image manifest
|
||||
[v2 schema 1](https://github.com/docker/distribution/blob/fda42e5ef908bdba722d435ff1f330d40dfcd56c/docs/spec/manifest-v2-1.md)
|
||||
@@ -104,9 +110,9 @@ If the registry you are using still supports v2 schema 1, urge their administrat
|
||||
|
||||
### `docker engine` subcommands
|
||||
|
||||
**Deprecated in Release: v19.03.0**
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
**Target For Removal In Release: v20.03.0**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The `docker engine activate`, `docker engine check`, and `docker engine update`
|
||||
provided an alternative installation method to upgrade Docker Community engines
|
||||
@@ -120,9 +126,9 @@ standard package managers.
|
||||
|
||||
### Top-level `docker deploy` subcommand (experimental)
|
||||
|
||||
**Deprecated in Release: v19.03.0**
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
**Target For Removal In Release: v20.03.0**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The top-level `docker deploy` command (using the "Docker Application Bundle"
|
||||
(.dab) file format was introduced as an experimental feature in Docker 1.13 /
|
||||
@@ -132,9 +138,9 @@ subcommand.
|
||||
|
||||
### `docker stack deploy` using "dab" files (experimental)
|
||||
|
||||
**Deprecated in Release: v19.03.0**
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
**Target For Removal In Release: v20.03.0**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
With no development being done on this feature, and no active use of the file
|
||||
format, support for the DAB file format and the top-level docker deploy command
|
||||
@@ -144,7 +150,7 @@ using compose files.
|
||||
|
||||
### AuFS storage driver
|
||||
|
||||
**Deprecated in Release: v19.03.0**
|
||||
**Deprecated in Release: v19.03**
|
||||
|
||||
The `aufs` storage driver is deprecated in favor of `overlay2`, and will
|
||||
be removed in a future release. Users of the `aufs` storage driver are
|
||||
@@ -163,7 +169,7 @@ maintenance of the `aufs` storage driver.
|
||||
|
||||
### Legacy "overlay" storage driver
|
||||
|
||||
**Deprecated in Release: v18.09.0**
|
||||
**Deprecated in Release: v18.09**
|
||||
|
||||
The `overlay` storage driver is deprecated in favor of the `overlay2` storage
|
||||
driver, which has all the benefits of `overlay`, without its limitations (excessive
|
||||
@@ -178,7 +184,7 @@ backported), there is no reason to keep maintaining the `overlay` storage driver
|
||||
|
||||
### Device mapper storage driver
|
||||
|
||||
**Deprecated in Release: v18.09.0**
|
||||
**Deprecated in Release: v18.09**
|
||||
|
||||
The `devicemapper` storage driver is deprecated in favor of `overlay2`, and will
|
||||
be removed in a future release. Users of the `devicemapper` storage driver are
|
||||
@@ -193,15 +199,17 @@ either on kernel 4.x, or have support for multiple lowerdirs backported), there
|
||||
is no reason to continue maintenance of the `devicemapper` storage driver.
|
||||
|
||||
|
||||
### Reserved namespaces in engine labels
|
||||
### Use of reserved namespaces in engine labels
|
||||
|
||||
**Deprecated in Release: v18.06.0**
|
||||
**Deprecated in Release: v18.06**
|
||||
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The namespaces `com.docker.*`, `io.docker.*`, and `org.dockerproject.*` in engine labels
|
||||
were always documented to be reserved, but there was never any enforcement.
|
||||
|
||||
Usage of these namespaces will now cause a warning in the engine logs to discourage their
|
||||
use, and will error instead in v20.03.0 and above.
|
||||
use, and will error instead in v20.10 and above.
|
||||
|
||||
|
||||
### `--disable-legacy-registry` override daemon option
|
||||
@@ -237,11 +245,11 @@ start when set.
|
||||
|
||||
### Asynchronous `service create` and `service update` as default
|
||||
|
||||
**Deprecated In Release: v17.05.0**
|
||||
**Deprecated In Release: v17.05**
|
||||
|
||||
**Disabled by default in release: [v17.10](https://github.com/docker/docker-ce/releases/tag/v17.10.0-ce)**
|
||||
|
||||
Docker 17.05.0 added an optional `--detach=false` option to make the
|
||||
Docker 17.05 added an optional `--detach=false` option to make the
|
||||
`docker service create` and `docker service update` work synchronously. This
|
||||
option will be enabled by default in Docker 17.10, at which point the `--detach`
|
||||
flag can be used to use the previous (asynchronous) behavior.
|
||||
@@ -251,7 +259,7 @@ and `docker service scale` in Docker 17.10.
|
||||
|
||||
### `-g` and `--graph` flags on `dockerd`
|
||||
|
||||
**Deprecated In Release: v17.05.0**
|
||||
**Deprecated In Release: v17.05**
|
||||
|
||||
The `-g` or `--graph` flag for the `dockerd` or `docker daemon` command was
|
||||
used to indicate the directory in which to store persistent data and resource
|
||||
@@ -283,7 +291,7 @@ information.
|
||||
### `filter` param for `/images/json` endpoint
|
||||
**Deprecated In Release: [v1.13.0](https://github.com/docker/docker/releases/tag/v1.13.0)**
|
||||
|
||||
**Target For Removal In Release: v17.12**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The `filter` param to filter the list of image by reference (name or name:tag) is now implemented as a regular filter, named `reference`.
|
||||
|
||||
@@ -348,7 +356,7 @@ further information.
|
||||
|
||||
**Deprecated in Release: [v1.12.0](https://github.com/docker/docker/releases/tag/v1.12.0)**
|
||||
|
||||
**Target For Removal In Release: v17.09**
|
||||
**Target For Removal In Release: v20.10**
|
||||
|
||||
The `docker search --automated` and `docker search --stars` options are deprecated.
|
||||
Use `docker search --filter=is-automated=...` and `docker search --filter=stars=...` instead.
|
||||
|
||||
+63
-43
@@ -500,10 +500,10 @@ Example (parsed representation is displayed after the `#`):
|
||||
|
||||
```dockerfile
|
||||
FROM busybox
|
||||
ENV foo /bar
|
||||
WORKDIR ${foo} # WORKDIR /bar
|
||||
ADD . $foo # ADD . /bar
|
||||
COPY \$foo /quux # COPY $foo /quux
|
||||
ENV FOO=/bar
|
||||
WORKDIR ${FOO} # WORKDIR /bar
|
||||
ADD . $FOO # ADD . /bar
|
||||
COPY \$FOO /quux # COPY $FOO /quux
|
||||
```
|
||||
|
||||
Environment variables are supported by the following list of instructions in
|
||||
@@ -666,7 +666,7 @@ the [*Public Repositories*](https://docs.docker.com/engine/tutorials/dockerrepos
|
||||
instructions.
|
||||
- Optionally a name can be given to a new build stage by adding `AS name` to the
|
||||
`FROM` instruction. The name can be used in subsequent `FROM` and
|
||||
`COPY --from=<name|index>` instructions to refer to the image built in this stage.
|
||||
`COPY --from=<name>` instructions to refer to the image built in this stage.
|
||||
- The `tag` or `digest` values are optional. If you omit either of them, the
|
||||
builder assumes a `latest` tag by default. The builder returns an error if it
|
||||
cannot find the `tag` value.
|
||||
@@ -994,53 +994,74 @@ port. For detailed information, see the
|
||||
## ENV
|
||||
|
||||
```dockerfile
|
||||
ENV <key> <value>
|
||||
ENV <key>=<value> ...
|
||||
```
|
||||
|
||||
The `ENV` instruction sets the environment variable `<key>` to the value
|
||||
`<value>`. This value will be in the environment for all subsequent instructions
|
||||
in the build stage and can be [replaced inline](#environment-replacement) in
|
||||
many as well.
|
||||
|
||||
The `ENV` instruction has two forms. The first form, `ENV <key> <value>`,
|
||||
will set a single variable to a value. The entire string after the first
|
||||
space will be treated as the `<value>` - including whitespace characters. The
|
||||
value will be interpreted for other environment variables, so quote characters
|
||||
will be removed if they are not escaped.
|
||||
|
||||
The second form, `ENV <key>=<value> ...`, allows for multiple variables to
|
||||
be set at one time. Notice that the second form uses the equals sign (=)
|
||||
in the syntax, while the first form does not. Like command line parsing,
|
||||
many as well. The value will be interpreted for other environment variables, so
|
||||
quote characters will be removed if they are not escaped. Like command line parsing,
|
||||
quotes and backslashes can be used to include spaces within values.
|
||||
|
||||
For example:
|
||||
Example:
|
||||
|
||||
```dockerfile
|
||||
ENV myName="John Doe" myDog=Rex\ The\ Dog \
|
||||
myCat=fluffy
|
||||
ENV MY_NAME="John Doe"
|
||||
ENV MY_DOG=Rex\ The\ Dog
|
||||
ENV MY_CAT=fluffy
|
||||
```
|
||||
|
||||
and
|
||||
The `ENV` instruction allows for multiple `<key>=<value> ...` variables to be set
|
||||
at one time, and the example below will yield the same net results in the final
|
||||
image:
|
||||
|
||||
```dockerfile
|
||||
ENV myName John Doe
|
||||
ENV myDog Rex The Dog
|
||||
ENV myCat fluffy
|
||||
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \
|
||||
MY_CAT=fluffy
|
||||
```
|
||||
|
||||
will yield the same net results in the final image.
|
||||
|
||||
The environment variables set using `ENV` will persist when a container is run
|
||||
from the resulting image. You can view the values using `docker inspect`, and
|
||||
change them using `docker run --env <key>=<value>`.
|
||||
|
||||
> **Note**
|
||||
Environment variable persistence can cause unexpected side effects. For example,
|
||||
setting `ENV DEBIAN_FRONTEND=noninteractive` changes the behavior of `apt-get`,
|
||||
and may confuse users of your image.
|
||||
|
||||
If an environment variable is only needed during build, and not in the final
|
||||
image, consider setting a value for a single command instead:
|
||||
|
||||
```dockerfile
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y ...
|
||||
```
|
||||
|
||||
Or using [`ARG`](#arg), which is not persisted in the final image:
|
||||
|
||||
```dockerfile
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install -y ...
|
||||
```
|
||||
|
||||
> **Alternative syntax**
|
||||
>
|
||||
> Environment persistence can cause unexpected side effects. For example,
|
||||
> setting `ENV DEBIAN_FRONTEND noninteractive` may confuse apt-get
|
||||
> users on a Debian-based image. To set a value for a single command, use
|
||||
> `RUN <key>=<value> <command>`.
|
||||
> The `ENV` instruction also allows an alternative syntax `ENV <key> <value>`,
|
||||
> omitting the `=`. For example:
|
||||
>
|
||||
> ```dockerfile
|
||||
> ENV MY_VAR my-value
|
||||
> ```
|
||||
>
|
||||
> This syntax does not allow for multiple environment-variables to be set in a
|
||||
> single `ENV` instruction, and can be confusing. For example, the following
|
||||
> sets a single environment variable (`ONE`) with value `"TWO= THREE=world"`:
|
||||
>
|
||||
> ```dockerfile
|
||||
> ENV ONE TWO= THREE=world
|
||||
> ```
|
||||
>
|
||||
> The alternative syntax is supported for backward compatibility, but discouraged
|
||||
> for the reasons outlined above, and may be removed in a future release.
|
||||
|
||||
## ADD
|
||||
|
||||
@@ -1276,11 +1297,11 @@ COPY test.txt /absoluteDir/
|
||||
|
||||
When copying files or directories that contain special characters (such as `[`
|
||||
and `]`), you need to escape those paths following the Golang rules to prevent
|
||||
them from being treated as a matching pattern. For example, to add a file
|
||||
them from being treated as a matching pattern. For example, to copy a file
|
||||
named `arr[0].txt`, use the following;
|
||||
|
||||
```dockerfile
|
||||
ADD arr[[]0].txt /mydir/
|
||||
COPY arr[[]0].txt /mydir/
|
||||
```
|
||||
|
||||
All new files and directories are created with a UID and GID of 0, unless the
|
||||
@@ -1311,12 +1332,11 @@ no lookup and does not depend on container root filesystem content.
|
||||
> If you build using STDIN (`docker build - < somefile`), there is no
|
||||
> build context, so `COPY` can't be used.
|
||||
|
||||
Optionally `COPY` accepts a flag `--from=<name|index>` that can be used to set
|
||||
Optionally `COPY` accepts a flag `--from=<name>` that can be used to set
|
||||
the source location to a previous build stage (created with `FROM .. AS <name>`)
|
||||
that will be used instead of a build context sent by the user. The flag also
|
||||
accepts a numeric index assigned for all previous build stages started with
|
||||
`FROM` instruction. In case a build stage with a specified name can't be found an
|
||||
image with the same name is attempted to be used instead.
|
||||
that will be used instead of a build context sent by the user. In case a build
|
||||
stage with a specified name can't be found an image with the same name is
|
||||
attempted to be used instead.
|
||||
|
||||
`COPY` obeys the following rules:
|
||||
|
||||
@@ -1769,7 +1789,7 @@ The `WORKDIR` instruction can resolve environment variables previously set using
|
||||
For example:
|
||||
|
||||
```dockerfile
|
||||
ENV DIRPATH /path
|
||||
ENV DIRPATH=/path
|
||||
WORKDIR $DIRPATH/$DIRNAME
|
||||
RUN pwd
|
||||
```
|
||||
@@ -1874,7 +1894,7 @@ this Dockerfile with an `ENV` and `ARG` instruction.
|
||||
```dockerfile
|
||||
FROM ubuntu
|
||||
ARG CONT_IMG_VER
|
||||
ENV CONT_IMG_VER v1.0.0
|
||||
ENV CONT_IMG_VER=v1.0.0
|
||||
RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
@@ -1895,7 +1915,7 @@ useful interactions between `ARG` and `ENV` instructions:
|
||||
```dockerfile
|
||||
FROM ubuntu
|
||||
ARG CONT_IMG_VER
|
||||
ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
|
||||
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
|
||||
RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
@@ -2031,7 +2051,7 @@ Consider another example under the same command line:
|
||||
```dockerfile
|
||||
FROM ubuntu
|
||||
ARG CONT_IMG_VER
|
||||
ENV CONT_IMG_VER $CONT_IMG_VER
|
||||
ENV CONT_IMG_VER=$CONT_IMG_VER
|
||||
RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
@@ -2046,7 +2066,7 @@ this Dockerfile:
|
||||
```dockerfile
|
||||
FROM ubuntu
|
||||
ARG CONT_IMG_VER
|
||||
ENV CONT_IMG_VER hello
|
||||
ENV CONT_IMG_VER=hello
|
||||
RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
|
||||
@@ -110,6 +110,11 @@ Build Syntax Suffix | Commit Used | Build Context Used
|
||||
`myrepo.git#mytag:myfolder` | `refs/tags/mytag` | `/myfolder`
|
||||
`myrepo.git#mybranch:myfolder` | `refs/heads/mybranch` | `/myfolder`
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> You cannot specify the build-context directory (`myfolder` in the examples above)
|
||||
> when using BuildKit as builder (`DOCKER_BUILDKIT=1`). Support for this feature
|
||||
> is tracked in [buildkit#1684](https://github.com/moby/buildkit/issues/1684).
|
||||
|
||||
### Tarball contexts
|
||||
|
||||
@@ -397,14 +402,12 @@ the command line.
|
||||
### Use a custom parent cgroup (--cgroup-parent)
|
||||
|
||||
When `docker build` is run with the `--cgroup-parent` option the containers
|
||||
used in the build will be run with the [corresponding `docker run`
|
||||
flag](../run.md#specify-custom-cgroups).
|
||||
used in the build will be run with the [corresponding `docker run` flag](../run.md#specify-custom-cgroups).
|
||||
|
||||
### Set ulimits in container (--ulimit)
|
||||
|
||||
Using the `--ulimit` option with `docker build` will cause each build step's
|
||||
container to be started using those [`--ulimit`
|
||||
flag values](run.md#set-ulimits-in-container---ulimit).
|
||||
container to be started using those [`--ulimit` flag values](run.md#set-ulimits-in-container---ulimit).
|
||||
|
||||
### Set build-time variables (--build-arg)
|
||||
|
||||
@@ -737,7 +740,7 @@ FROM busybox
|
||||
RUN echo hello > /hello
|
||||
RUN echo world >> /hello
|
||||
RUN touch remove_me /remove_me
|
||||
ENV HELLO world
|
||||
ENV HELLO=world
|
||||
RUN rm /remove_me
|
||||
```
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
title: "Use the Docker command line"
|
||||
description: "Docker's CLI command description and usage"
|
||||
keywords: "Docker, Docker documentation, CLI, command line"
|
||||
redirect_from:
|
||||
- /go/experimental/
|
||||
---
|
||||
|
||||
<!-- This file is maintained within the docker/cli GitHub
|
||||
|
||||
@@ -73,7 +73,7 @@ $ docker inspect -f "{{ .Config.Env }}" c3f279d17e0a
|
||||
|
||||
[HOME=/ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]
|
||||
|
||||
$ docker commit --change "ENV DEBUG true" c3f279d17e0a svendowideit/testimage:version3
|
||||
$ docker commit --change "ENV DEBUG=true" c3f279d17e0a svendowideit/testimage:version3
|
||||
|
||||
f5283438590d
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ sourced from the file `/home/me/my-kube-config`:
|
||||
$ docker context create \
|
||||
--docker host=unix:///var/run/docker.sock \
|
||||
--kubernetes config-file=/home/me/my-kube-config \
|
||||
my-context
|
||||
my-context
|
||||
```
|
||||
|
||||
### Create a context based on an existing context
|
||||
@@ -76,7 +76,7 @@ an existing context. The example below creates a new context named `my-context`
|
||||
from the existing context `existing-context`:
|
||||
|
||||
```bash
|
||||
$ docker context create --from existing-context my-context
|
||||
$ docker context create --from existing-context my-context
|
||||
```
|
||||
|
||||
If the `--from` option is not set, the `context` is created from the current context:
|
||||
|
||||
@@ -72,7 +72,7 @@ $ sudo tar -c . | docker import - exampleimagedir
|
||||
### Import from a local directory with new configurations
|
||||
|
||||
```bash
|
||||
$ sudo tar -c . | docker import --change "ENV DEBUG true" - exampleimagedir
|
||||
$ sudo tar -c . | docker import --change "ENV DEBUG=true" - exampleimagedir
|
||||
```
|
||||
|
||||
Note the `sudo` in this example – you must preserve
|
||||
|
||||
@@ -53,7 +53,7 @@ $ cat ~/my_password.txt | docker login --username foo --password-stdin
|
||||
`docker login` requires user to use `sudo` or be `root`, except when:
|
||||
|
||||
1. connecting to a remote daemon, such as a `docker-machine` provisioned `docker engine`.
|
||||
2. user is added to the `docker` group. This will impact the security of your system; the `docker` group is `root` equivalent. See [Docker Daemon Attack Surface](https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface) for details.
|
||||
2. user is added to the `docker` group. This will impact the security of your system; the `docker` group is `root` equivalent. See [Docker Daemon Attack Surface](https://docs.docker.com/engine/security/#docker-daemon-attack-surface) for details.
|
||||
|
||||
You can log into any public or private repository for which you have
|
||||
credentials. When you log in, the command stores credentials in
|
||||
|
||||
@@ -71,7 +71,7 @@ In order to retrieve logs before a specific point in time, run:
|
||||
$ docker run --name test -d busybox sh -c "while true; do $(echo date); sleep 1; done"
|
||||
$ date
|
||||
Tue 14 Nov 2017 16:40:00 CET
|
||||
$ docker logs -f --until=2s
|
||||
$ docker logs -f --until=2s test
|
||||
Tue 14 Nov 2017 16:40:00 CET
|
||||
Tue 14 Nov 2017 16:40:01 CET
|
||||
Tue 14 Nov 2017 16:40:02 CET
|
||||
|
||||
@@ -160,7 +160,7 @@ Digest can also be used in the `FROM` of a Dockerfile, for example:
|
||||
|
||||
```dockerfile
|
||||
FROM ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
|
||||
MAINTAINER some maintainer <maintainer@example.com>
|
||||
LABEL maintainer="some maintainer <maintainer@example.com>"
|
||||
```
|
||||
|
||||
> **Note**
|
||||
|
||||
+33
-24
@@ -1287,58 +1287,67 @@ options which are allowed by default and can be dropped.
|
||||
|
||||
| Capability Key | Capability Description |
|
||||
|:-----------------|:------------------------------------------------------------------------------------------------------------------------------|
|
||||
| SETPCAP | Modify process capabilities. |
|
||||
| MKNOD | Create special files using mknod(2). |
|
||||
| AUDIT_WRITE | Write records to kernel auditing log. |
|
||||
| CHOWN | Make arbitrary changes to file UIDs and GIDs (see chown(2)). |
|
||||
| NET_RAW | Use RAW and PACKET sockets. |
|
||||
| DAC_OVERRIDE | Bypass file read, write, and execute permission checks. |
|
||||
| FOWNER | Bypass permission checks on operations that normally require the file system UID of the process to match the UID of the file. |
|
||||
| FSETID | Don't clear set-user-ID and set-group-ID permission bits when a file is modified. |
|
||||
| KILL | Bypass permission checks for sending signals. |
|
||||
| SETGID | Make arbitrary manipulations of process GIDs and supplementary GID list. |
|
||||
| SETUID | Make arbitrary manipulations of process UIDs. |
|
||||
| MKNOD | Create special files using mknod(2). |
|
||||
| NET_BIND_SERVICE | Bind a socket to internet domain privileged ports (port numbers less than 1024). |
|
||||
| SYS_CHROOT | Use chroot(2), change root directory. |
|
||||
| NET_RAW | Use RAW and PACKET sockets. |
|
||||
| SETFCAP | Set file capabilities. |
|
||||
| SETGID | Make arbitrary manipulations of process GIDs and supplementary GID list. |
|
||||
| SETPCAP | Modify process capabilities. |
|
||||
| SETUID | Make arbitrary manipulations of process UIDs. |
|
||||
| SYS_CHROOT | Use chroot(2), change root directory. |
|
||||
|
||||
The next table shows the capabilities which are not granted by default and may be added.
|
||||
|
||||
| Capability Key | Capability Description |
|
||||
|:----------------|:----------------------------------------------------------------------------------------------------------------|
|
||||
| SYS_MODULE | Load and unload kernel modules. |
|
||||
| SYS_RAWIO | Perform I/O port operations (iopl(2) and ioperm(2)). |
|
||||
| SYS_PACCT | Use acct(2), switch process accounting on or off. |
|
||||
| SYS_ADMIN | Perform a range of system administration operations. |
|
||||
| SYS_NICE | Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes. |
|
||||
| SYS_RESOURCE | Override resource Limits. |
|
||||
| SYS_TIME | Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock. |
|
||||
| SYS_TTY_CONFIG | Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals. |
|
||||
| AUDIT_CONTROL | Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules. |
|
||||
| AUDIT_READ | Allow reading audit messages from the kernel. |
|
||||
| BLOCK_SUSPEND | Employ features that can block system suspend. |
|
||||
| DAC_READ_SEARCH | Bypass file read permission checks and directory read and execute permission checks. |
|
||||
| IPC_LOCK | Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). |
|
||||
| IPC_OWNER | Bypass permission checks for operations on System V IPC objects. |
|
||||
| LEASE | Establish leases on arbitrary files (see fcntl(2)). |
|
||||
| LINUX_IMMUTABLE | Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags. |
|
||||
| MAC_ADMIN | Allow MAC configuration or state changes. Implemented for the Smack LSM. |
|
||||
| MAC_OVERRIDE | Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM). |
|
||||
| NET_ADMIN | Perform various network-related operations. |
|
||||
| SYSLOG | Perform privileged syslog(2) operations. |
|
||||
| DAC_READ_SEARCH | Bypass file read permission checks and directory read and execute permission checks. |
|
||||
| LINUX_IMMUTABLE | Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags. |
|
||||
| NET_BROADCAST | Make socket broadcasts, and listen to multicasts. |
|
||||
| IPC_LOCK | Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). |
|
||||
| IPC_OWNER | Bypass permission checks for operations on System V IPC objects. |
|
||||
| SYS_PTRACE | Trace arbitrary processes using ptrace(2). |
|
||||
| SYS_ADMIN | Perform a range of system administration operations. |
|
||||
| SYS_BOOT | Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution. |
|
||||
| LEASE | Establish leases on arbitrary files (see fcntl(2)). |
|
||||
| SYS_MODULE | Load and unload kernel modules. |
|
||||
| SYS_NICE | Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes. |
|
||||
| SYS_PACCT | Use acct(2), switch process accounting on or off. |
|
||||
| SYS_PTRACE | Trace arbitrary processes using ptrace(2). |
|
||||
| SYS_RAWIO | Perform I/O port operations (iopl(2) and ioperm(2)). |
|
||||
| SYS_RESOURCE | Override resource Limits. |
|
||||
| SYS_TIME | Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock. |
|
||||
| SYS_TTY_CONFIG | Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals. |
|
||||
| SYSLOG | Perform privileged syslog(2) operations. |
|
||||
| WAKE_ALARM | Trigger something that will wake up the system. |
|
||||
| BLOCK_SUSPEND | Employ features that can block system suspend. |
|
||||
|
||||
Further reference information is available on the [capabilities(7) - Linux man page](http://man7.org/linux/man-pages/man7/capabilities.7.html)
|
||||
|
||||
Both flags support the value `ALL`, so if the
|
||||
operator wants to have all capabilities but `MKNOD` they could use:
|
||||
Both flags support the value `ALL`, so to allow a container to use all capabilities
|
||||
except for `MKNOD`:
|
||||
|
||||
```bash
|
||||
$ docker run --cap-add=ALL --cap-drop=MKNOD ...
|
||||
```
|
||||
|
||||
The `--cap-add` and `--cap-drop` flags accept capabilities to be specified with
|
||||
a `CAP_` prefix. The following examples are therefore equivalent:
|
||||
|
||||
```bash
|
||||
$ docker run --cap-add=SYS_ADMIN ...
|
||||
$ docker run --cap-add=CAP_SYS_ADMIN ...
|
||||
```
|
||||
|
||||
For interacting with the network stack, instead of using `--privileged` they
|
||||
should use `--cap-add=NET_ADMIN` to modify the network interfaces.
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/v3/assert"
|
||||
"gotest.tools/v3/golden"
|
||||
"gotest.tools/v3/icmd"
|
||||
)
|
||||
@@ -19,3 +22,73 @@ func TestContextList(t *testing.T) {
|
||||
})
|
||||
golden.Assert(t, result.Stdout(), "context-ls.golden")
|
||||
}
|
||||
|
||||
func TestContextImportNoTLS(t *testing.T) {
|
||||
d, _ := ioutil.TempDir("", "")
|
||||
defer func() {
|
||||
os.RemoveAll(d)
|
||||
}()
|
||||
cmd := icmd.Command("docker", "context", "import", "remote", "./testdata/test-dockerconfig.tar")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
|
||||
cmd = icmd.Command("docker", "context", "ls")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
"KUBECONFIG=./testdata/test-kubeconfig", // Allows reuse of context-ls.golden
|
||||
)
|
||||
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
golden.Assert(t, result.Stdout(), "context-ls.golden")
|
||||
}
|
||||
|
||||
func TestContextImportTLS(t *testing.T) {
|
||||
d, _ := ioutil.TempDir("", "")
|
||||
defer func() {
|
||||
os.RemoveAll(d)
|
||||
}()
|
||||
cmd := icmd.Command("docker", "context", "import", "test", "./testdata/test-dockerconfig-tls.tar")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
|
||||
cmd = icmd.Command("docker", "context", "ls")
|
||||
cmd.Env = append(cmd.Env,
|
||||
"DOCKER_CONFIG="+d,
|
||||
)
|
||||
result := icmd.RunCmd(cmd).Assert(t, icmd.Success)
|
||||
golden.Assert(t, result.Stdout(), "context-ls-tls.golden")
|
||||
|
||||
b, err := ioutil.ReadFile(d + "/contexts/tls/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08/kubernetes/key.pem")
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, string(b), `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEArQk77K5sgrQYY6HiQ1y7AC+67HrRB36oEvR+Fq60RsFcc3cZ
|
||||
xAvMkRSBPjQyskjdYY7kfykGHhfJxGKopb3cDJx3eDBxjgAniwnnOMmHVWbf8Eik
|
||||
o0sNxkgzQPGq83nL3QvVxm3xgqe4nlTdR/Swoq6Pv0oaVYvPPMnaZIF89SJ/wlNT
|
||||
myCs6Uq00dICi20II+M2Nw9b+EVEK4ENl+SlrsK7iuoBIh/H0ZghxOthO9J/HeBb
|
||||
hmM4wcs1OonhPDYKHEaChYA7/Q3/8OBp3bAdlQJ1ziyP3ROAKHL2NwwkGZ8o8HP8
|
||||
u0ex/NAb8w5J5WNePqYQd/sqfisfNpA5VIKcEQIDAQABAoIBABLo4W2aGi2mdMve
|
||||
kxV9esoobSsOuO0ywDdiFK1x5i2dT/cmWuB70Z1BOmaL2cZ2BAt3TC1BVHPRcbFO
|
||||
ftOuDfAq4Tt3P9Ge3rNpH6WrEGka1voxVhyqRRUYKtG8F0yIUOkVNAV9WllG7vwO
|
||||
ligY63y7yuXCuWID51/jR0SYiglXz6G4gcJKFXtugXXiLUIg08GVWkwOsrACC+hR
|
||||
mhcHly1926VhN5+ozjNU/GZ1LaTuK6erBZakH5bqlN97s5rrk0ZRwk/JtnkoRRdI
|
||||
cq0918Za2vqGDHZ3MqLttL52YfDXPIEJPwlFdvC/+sXK2NhUB/xY4yuliU3sY0sf
|
||||
XsIvIWECgYEAwD8AnZI0hnGv8hc6zJppHFRwhrtLZ+09SJwPv5Y4wxuuk5dzNkpf
|
||||
xCNo5hjSVYA1MMmWG8p/sEXo2IyCT8sWDNCn9kieTXihxRxbj88Y2qA5O4N46Zy4
|
||||
kPngjkP5PPDMkwaQQgUr9LvlWS7P6OJkH18ZN8s3QhMaKcHu9FFT44UCgYEA5mte
|
||||
mMSDf9hUK3IK+yrGX62qc2H+ecXN3Zf3nehyiz+dX4ZXhBwBkwJ/mHvuAZPfoFUN
|
||||
Xg6cdyWFJg9ynm45JXnDjmYPGmFLn0mP3Mje/+SbbW2fdFWHJW/maqj4uUqqgQd+
|
||||
pGNzKXq34MzDrpsqIJ7AHu3LYVMOoLAVqC7LXh0CgYEAnLF9ZfFqQH7fgvouIeBl
|
||||
dgLZKOf2AUJcJheVunnN0DF67K+P55tdTTfzY0CuB6SVNivI3uQBiYKh1AdKm5ET
|
||||
auSTUmlEJi8B4/BGLQQG5QOdQoXZgsgLo5cX0b1To7k9dUTvRfCDMFoKCNPgAJiu
|
||||
NOfFXTWU15VMSObaRmcXciUCgYEA5e1cXwsxwUAodZX+eTXs8ArHHQ47Nl55GFeN
|
||||
wufybRuUuX7AE9cyhvUmSA3aqX5a144noaTo40fwftNJZ+jLY6cGyjDzfzp5kMCC
|
||||
KynSxPzlUCPkytyR2Hy6K9LjJ1rnm4vUBswqXcjUdiE+Xxz8w8JGKlbV7Q9JeHVd
|
||||
lw7i5s0CgYAn9T9ySI3xCbrUa/XV/ZY2hopUdH5CDPeTd2eH+L+lctkD9nlzLrpj
|
||||
qij+jaEUweymNx0uttgv02J3DYcIIvVq3RNAwORy5Mp9KasHmjbW2xq+HAq5yFOO
|
||||
1ma82F5zeUl+bKqjMRCY8IVZ349VxRZtb2RVVEKyVswb7HmKp6gGbA==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
|
||||
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
|
||||
remote my remote cluster ssh://someserver https://someserver (default) kubernetes
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
NAME DESCRIPTION DOCKER ENDPOINT KUBERNETES ENDPOINT ORCHESTRATOR
|
||||
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock swarm
|
||||
test unix:///var/run/docker.sock https://kubernetes.docker.internal:6443 (default) swarm
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -116,8 +116,8 @@ func TestBuildIidFileSquash(t *testing.T) {
|
||||
buildDir := fs.NewDir(t, "test-iidfile-squash-build",
|
||||
fs.WithFile("Dockerfile", fmt.Sprintf(`
|
||||
FROM %s
|
||||
ENV FOO FOO
|
||||
ENV BAR BAR
|
||||
ENV FOO=FOO
|
||||
ENV BAR=BAR
|
||||
RUN touch /fiip
|
||||
RUN touch /foop`, fixtures.AlpineImage)),
|
||||
)
|
||||
|
||||
+3
-3
@@ -201,7 +201,7 @@ A Dockerfile is similar to a Makefile.
|
||||
from the resulting image. Use `docker inspect` to inspect these values, and
|
||||
change them using `docker run --env <key>=<value>`.
|
||||
|
||||
Note that setting "`ENV DEBIAN_FRONTEND noninteractive`" may cause
|
||||
Note that setting "`ENV DEBIAN_FRONTEND=noninteractive`" may cause
|
||||
unintended consequences, because it will persist when the container is run
|
||||
interactively, as with the following command: `docker run -t -i image bash`
|
||||
|
||||
@@ -388,7 +388,7 @@ A Dockerfile is similar to a Makefile.
|
||||
```
|
||||
1 FROM ubuntu
|
||||
2 ARG CONT_IMG_VER
|
||||
3 ENV CONT_IMG_VER v1.0.0
|
||||
3 ENV CONT_IMG_VER=v1.0.0
|
||||
4 RUN echo $CONT_IMG_VER
|
||||
```
|
||||
Then, assume this image is built with this command:
|
||||
@@ -408,7 +408,7 @@ A Dockerfile is similar to a Makefile.
|
||||
```
|
||||
1 FROM ubuntu
|
||||
2 ARG CONT_IMG_VER
|
||||
3 ENV CONT_IMG_VER ${CONT_IMG_VER:-v1.0.0}
|
||||
3 ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
|
||||
4 RUN echo $CONT_IMG_VER
|
||||
```
|
||||
|
||||
|
||||
@@ -27,4 +27,4 @@ variable set to "true", you can create a new image based on that
|
||||
container by first getting the container's ID with `docker ps` and
|
||||
then running:
|
||||
|
||||
$ docker container commit -c="ENV DEBUG true" 98bd7fc99854 debug-image
|
||||
$ docker container commit -c="ENV DEBUG=true" 98bd7fc99854 debug-image
|
||||
|
||||
@@ -33,7 +33,7 @@ In order to retrieve logs before a specific point in time, run:
|
||||
$ docker run --name test -d busybox sh -c "while true; do $(echo date); sleep 1; done"
|
||||
$ date
|
||||
Tue 14 Nov 2017 16:40:00 CET
|
||||
$ docker logs -f --until=2s
|
||||
$ docker logs -f --until=2s test
|
||||
Tue 14 Nov 2017 16:40:00 CET
|
||||
Tue 14 Nov 2017 16:40:01 CET
|
||||
Tue 14 Nov 2017 16:40:02 CET
|
||||
|
||||
@@ -36,7 +36,7 @@ Import to docker via pipe and stdin:
|
||||
## Apply specified Dockerfile instructions while importing the image
|
||||
This example sets the docker image ENV variable DEBUG to true by default.
|
||||
|
||||
# tar -c . | docker image import -c="ENV DEBUG true" - exampleimagedir
|
||||
# tar -c . | docker image import -c="ENV DEBUG=true" - exampleimagedir
|
||||
|
||||
## When the daemon supports multiple operating systems
|
||||
If the daemon supports multiple operating systems, and the image being imported
|
||||
|
||||
@@ -111,7 +111,7 @@ pull the above image by digest, run the following command:
|
||||
Digest can also be used in the `FROM` of a Dockerfile, for example:
|
||||
|
||||
FROM ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
|
||||
MAINTAINER some maintainer <maintainer@example.com>
|
||||
LABEL maintainer="some maintainer <maintainer@example.com>"
|
||||
|
||||
> **Note**: Using this feature "pins" an image to a specific version in time.
|
||||
> Docker will therefore not pull updated versions of an image, which may include
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ do not specify a `SERVER`, the command uses Docker's public registry located at
|
||||
`docker login` requires user to use `sudo` or be `root`, except when:
|
||||
|
||||
1. connecting to a remote daemon, such as a `docker-machine` provisioned `docker engine`.
|
||||
2. user is added to the `docker` group. This will impact the security of your system; the `docker` group is `root` equivalent. See [Docker Daemon Attack Surface](https://docs.docker.com/engine/security/security/#/docker-daemon-attack-surface) for details.
|
||||
2. user is added to the `docker` group. This will impact the security of your system; the `docker` group is `root` equivalent. See [Docker Daemon Attack Surface](https://docs.docker.com/engine/security/#docker-daemon-attack-surface) for details.
|
||||
|
||||
You can log into any public or private repository for which you have
|
||||
credentials. When you log in, the command stores encoded credentials in
|
||||
|
||||
+4
-4
@@ -15,7 +15,7 @@ github.com/davecgh/go-spew 8991bc29aa16c548c550c7ff7826
|
||||
github.com/dgrijalva/jwt-go a2c85815a77d0f951e33ba4db5ae93629a1530af
|
||||
github.com/docker/compose-on-kubernetes cc4914dfd1b6684a9750a59f3613fc0a95291824 # v0.4.23
|
||||
github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
||||
github.com/docker/docker a004854097417a591c3f6a3aeaab75efae3c5814 https://github.com/docker/engine.git # 19.03 branch
|
||||
github.com/docker/docker a004854097417a591c3f6a3aeaab75efae3c5814 # 19.03 branch
|
||||
github.com/docker/docker-credential-helpers 54f0238b6bf101fc3ad3b34114cb5520beb562f5 # v0.6.3
|
||||
github.com/docker/go d30aec9fd63c35133f8f79c3412ad91a3b08be06 # Contains a customized version of canonical/json and is used by Notary. The package is periodically rebased on current Go versions.
|
||||
github.com/docker/go-connections 7395e3f8aa162843a74ed6d48e79627d9792ac55 # v0.4.0
|
||||
@@ -26,6 +26,7 @@ github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a
|
||||
github.com/docker/licensing 9781369abdb5281cdc07a2a446c6df01347ec793
|
||||
github.com/docker/swarmkit 48eb1828ce81be20b25d647f6ca8f33d599f705c
|
||||
github.com/evanphx/json-patch 72bf35d0ff611848c1dc9df0f976c81192392fa5 # v4.1.0
|
||||
github.com/fvbommel/sortorder 6b6b45a52fcc54f788363c1880630248b63402a1 # v1.0.0
|
||||
github.com/gofrs/flock 7f43ea2e6a643ad441fc12d0ecc0d3388b300c53 # v0.7.0
|
||||
github.com/gogo/googleapis d31c731455cb061f42baff3bda55bad0118b126b # v1.2.0
|
||||
github.com/gogo/protobuf ba06b47c162d49f2af050fb4c75bcbc86a159d5c # v1.2.1
|
||||
@@ -53,7 +54,7 @@ github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5
|
||||
github.com/Microsoft/hcsshim 672e52e9209d1e53718c1b6a7d68cc9272654ab5
|
||||
github.com/miekg/pkcs11 cb39313ec884f2cd77f4762875fe96aecf68f8e3 # v1.0.2
|
||||
github.com/mitchellh/mapstructure fa473d140ef3c6adf42d6b391fe76707f1f243c8 # v1.0.0
|
||||
github.com/moby/buildkit ae10b292fefb00e0fbf9fecd1419c5f252e58895
|
||||
github.com/moby/buildkit df89d4dcf73ce414cd76837bfb0e9a0cc0ef3386 # v0.6.4-32-gdf89d4dc
|
||||
github.com/modern-go/concurrent bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94 # 1.0.3
|
||||
github.com/modern-go/reflect2 4b7aa43c6742a2c18fdef89dd197aaae7dac7ccd # 1.0.1
|
||||
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
|
||||
@@ -74,7 +75,7 @@ github.com/spf13/cobra ef82de70bb3f60c65fb8eebacbb2
|
||||
github.com/spf13/pflag 4cb166e4f25ac4e8016a3595bbf7ea2e9aa85a2c https://github.com/thaJeztah/pflag.git # temporary fork with https://github.com/spf13/pflag/pull/170 applied, which isn't merged yet upstream
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
github.com/theupdateframework/notary d6e1431feb32348e0650bf7551ac5cffd01d857b # v0.6.1
|
||||
github.com/tonistiigi/fsutil 3d2716dd0a4d06ff854241c7e8b6f3f904e1719f
|
||||
github.com/tonistiigi/fsutil 0f039a052ca1da01626278199624b62aed9b3729
|
||||
github.com/tonistiigi/units 6950e57a87eaf136bbe44ef2ec8e75b9e3569de2
|
||||
github.com/xeipuuv/gojsonpointer 4e3ac2762d5f479393488629ee9370b50873b3a6
|
||||
github.com/xeipuuv/gojsonreference bd5ef7bd5415a7ac448318e64f11a24cd21e594b
|
||||
@@ -99,6 +100,5 @@ k8s.io/kube-openapi 5e45bb682580c9be5ffa4d27d367
|
||||
k8s.io/kubernetes 641856db18352033a0d96dbc99153fa3b27298e5 # v1.14.0
|
||||
k8s.io/utils 21c4ce38f2a793ec01e925ddc31216500183b773
|
||||
sigs.k8s.io/yaml fd68e9863619f6ec2fdd8625fe1f02e7c877e480 # v1.1.0
|
||||
vbom.ml/util 256737ac55c46798123f754ab7d2c784e2c71783
|
||||
|
||||
# DO NOT EDIT BELOW THIS LINE -------- reserved for downstream projects --------
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
# sortorder [](https://godoc.org/github.com/fvbommel/sortorder)
|
||||
|
||||
import "github.com/fvbommel/sortorder"
|
||||
|
||||
Sort orders and comparison functions.
|
||||
Generated
Vendored
+1
-1
@@ -2,4 +2,4 @@
|
||||
//
|
||||
// Currently, it only implements so-called "natural order", where integers
|
||||
// embedded in strings are compared by value.
|
||||
package sortorder // import "vbom.ml/util/sortorder"
|
||||
package sortorder
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
module github.com/fvbommel/sortorder
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1
|
||||
Generated
Vendored
+1
-1
@@ -57,7 +57,7 @@ func NaturalLess(str1, str2 string) bool {
|
||||
if len1, len2 := idx1-nonZero1, idx2-nonZero2; len1 != len2 {
|
||||
return len1 < len2
|
||||
}
|
||||
// If they're not equal, string comparison is correct.
|
||||
// If they're equal, string comparison is correct.
|
||||
if nr1, nr2 := str1[nonZero1:idx1], str2[nonZero2:idx2]; nr1 != nr2 {
|
||||
return nr1 < nr2
|
||||
}
|
||||
+10
@@ -19,6 +19,9 @@ const (
|
||||
CapReadDir apicaps.CapID = "readdir"
|
||||
CapStatFile apicaps.CapID = "statfile"
|
||||
CapImportCaches apicaps.CapID = "importcaches"
|
||||
|
||||
// CapGatewaySolveMetadata can be used to check if solve calls from gateway reliably return metadata
|
||||
CapGatewaySolveMetadata apicaps.CapID = "gateway.solve.metadata"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -92,4 +95,11 @@ func init() {
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
|
||||
Caps.Init(apicaps.Cap{
|
||||
ID: CapGatewaySolveMetadata,
|
||||
Name: "gateway metadata",
|
||||
Enabled: true,
|
||||
Status: apicaps.CapStatusExperimental,
|
||||
})
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
module github.com/moby/buildkit
|
||||
|
||||
go 1.11
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/Microsoft/go-winio v0.4.13-0.20190408173621-84b4ab48a507
|
||||
github.com/Microsoft/hcsshim v0.8.5 // indirect
|
||||
github.com/apache/thrift v0.0.0-20161221203622-b2a4d4ae21c7 // indirect
|
||||
github.com/codahale/hdrhistogram v0.0.0-20160425231609-f8ad88b59a58 // indirect
|
||||
github.com/containerd/cgroups v0.0.0-20190226200435-dbea6f2bd416 // indirect
|
||||
@@ -53,7 +54,7 @@ require (
|
||||
github.com/sirupsen/logrus v1.3.0
|
||||
github.com/stretchr/testify v1.3.0
|
||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 // indirect
|
||||
github.com/tonistiigi/fsutil v0.0.0-20190819224149-3d2716dd0a4d
|
||||
github.com/tonistiigi/fsutil v0.0.0-20200128191323-6c909ab392c1
|
||||
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
|
||||
github.com/uber/jaeger-client-go v0.0.0-20180103221425-e02c85f9069e
|
||||
github.com/uber/jaeger-lib v1.2.1 // indirect
|
||||
|
||||
+7
-2
@@ -255,7 +255,7 @@ func (sp *fsSyncTarget) Register(server *grpc.Server) {
|
||||
RegisterFileSendServer(server, sp)
|
||||
}
|
||||
|
||||
func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) error {
|
||||
func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) (err error) {
|
||||
if sp.outdir != "" {
|
||||
return syncTargetDiffCopy(stream, sp.outdir)
|
||||
}
|
||||
@@ -277,7 +277,12 @@ func (sp *fsSyncTarget) DiffCopy(stream FileSend_DiffCopyServer) error {
|
||||
if wc == nil {
|
||||
return status.Errorf(codes.AlreadyExists, "target already exists")
|
||||
}
|
||||
defer wc.Close()
|
||||
defer func() {
|
||||
err1 := wc.Close()
|
||||
if err != nil {
|
||||
err = err1
|
||||
}
|
||||
}()
|
||||
return writeTargetFile(stream, wc)
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -75,6 +75,10 @@ func MountSSHSocket(ctx context.Context, c session.Caller, opt SocketOpt) (sockP
|
||||
}
|
||||
}()
|
||||
|
||||
if err := os.Chmod(dir, 0711); err != nil {
|
||||
return "", nil, errors.WithStack(err)
|
||||
}
|
||||
|
||||
sockPath = filepath.Join(dir, "ssh_auth_sock")
|
||||
|
||||
l, err := net.Listen("unix", sockPath)
|
||||
|
||||
+5
-1
@@ -178,7 +178,7 @@ type sock struct {
|
||||
}
|
||||
|
||||
type readOnlyAgent struct {
|
||||
agent.Agent
|
||||
agent.ExtendedAgent
|
||||
}
|
||||
|
||||
func (a *readOnlyAgent) Add(_ agent.AddedKey) error {
|
||||
@@ -196,3 +196,7 @@ func (a *readOnlyAgent) RemoveAll() error {
|
||||
func (a *readOnlyAgent) Lock(_ []byte) error {
|
||||
return errors.Errorf("locking agent not allowed by buildkit")
|
||||
}
|
||||
|
||||
func (a *readOnlyAgent) Extension(_ string, _ []byte) ([]byte, error) {
|
||||
return nil, errors.Errorf("extensions not allowed by buildkit")
|
||||
}
|
||||
|
||||
+3
@@ -548,6 +548,9 @@ func align(l, r string, w int) string {
|
||||
}
|
||||
|
||||
func wrapHeight(j []*job, limit int) []*job {
|
||||
if limit < 0 {
|
||||
return nil
|
||||
}
|
||||
var wrapped []*job
|
||||
wrapped = append(wrapped, j...)
|
||||
if len(j) > limit {
|
||||
|
||||
+7
-1
@@ -5,6 +5,7 @@ import (
|
||||
"hash"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/tonistiigi/fsutil/types"
|
||||
)
|
||||
|
||||
@@ -25,9 +26,14 @@ func GetWalkerFn(root string) walkerFn {
|
||||
return err
|
||||
}
|
||||
|
||||
stat, ok := f.Sys().(*types.Stat)
|
||||
if !ok {
|
||||
return errors.Errorf("%T invalid file without stat information", f.Sys())
|
||||
}
|
||||
|
||||
p := ¤tPath{
|
||||
path: path,
|
||||
f: f,
|
||||
stat: stat,
|
||||
}
|
||||
|
||||
select {
|
||||
|
||||
+22
-25
@@ -37,12 +37,12 @@ type ChangeFunc func(ChangeKind, string, os.FileInfo, error) error
|
||||
|
||||
type currentPath struct {
|
||||
path string
|
||||
f os.FileInfo
|
||||
stat *types.Stat
|
||||
// fullPath string
|
||||
}
|
||||
|
||||
// doubleWalkDiff walks both directories to create a diff
|
||||
func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (err error) {
|
||||
func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn, filter FilterFunc) (err error) {
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
var (
|
||||
@@ -86,14 +86,22 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (er
|
||||
continue
|
||||
}
|
||||
|
||||
var f os.FileInfo
|
||||
k, p := pathChange(f1, f2)
|
||||
var f *types.Stat
|
||||
var f2copy *currentPath
|
||||
if f2 != nil {
|
||||
statCopy := *f2.stat
|
||||
if filter != nil {
|
||||
filter(f2.path, &statCopy)
|
||||
}
|
||||
f2copy = ¤tPath{path: f2.path, stat: &statCopy}
|
||||
}
|
||||
k, p := pathChange(f1, f2copy)
|
||||
switch k {
|
||||
case ChangeKindAdd:
|
||||
if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f = f2.f
|
||||
f = f2.stat
|
||||
f2 = nil
|
||||
case ChangeKindDelete:
|
||||
// Check if this file is already removed by being
|
||||
@@ -101,30 +109,30 @@ func doubleWalkDiff(ctx context.Context, changeFn ChangeFunc, a, b walkerFn) (er
|
||||
if rmdir != "" && strings.HasPrefix(f1.path, rmdir) {
|
||||
f1 = nil
|
||||
continue
|
||||
} else if rmdir == "" && f1.f.IsDir() {
|
||||
} else if rmdir == "" && f1.stat.IsDir() {
|
||||
rmdir = f1.path + string(os.PathSeparator)
|
||||
} else if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f1 = nil
|
||||
case ChangeKindModify:
|
||||
same, err := sameFile(f1, f2)
|
||||
same, err := sameFile(f1, f2copy)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if f1.f.IsDir() && !f2.f.IsDir() {
|
||||
if f1.stat.IsDir() && !f2copy.stat.IsDir() {
|
||||
rmdir = f1.path + string(os.PathSeparator)
|
||||
} else if rmdir != "" {
|
||||
rmdir = ""
|
||||
}
|
||||
f = f2.f
|
||||
f = f2.stat
|
||||
f1 = nil
|
||||
f2 = nil
|
||||
if same {
|
||||
continue loop0
|
||||
}
|
||||
}
|
||||
if err := changeFn(k, p, f, nil); err != nil {
|
||||
if err := changeFn(k, p, &StatInfo{f}, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -159,28 +167,17 @@ func pathChange(lower, upper *currentPath) (ChangeKind, string) {
|
||||
|
||||
func sameFile(f1, f2 *currentPath) (same bool, retErr error) {
|
||||
// If not a directory also check size, modtime, and content
|
||||
if !f1.f.IsDir() {
|
||||
if f1.f.Size() != f2.f.Size() {
|
||||
if !f1.stat.IsDir() {
|
||||
if f1.stat.Size_ != f2.stat.Size_ {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
t1 := f1.f.ModTime()
|
||||
t2 := f2.f.ModTime()
|
||||
if t1.UnixNano() != t2.UnixNano() {
|
||||
if f1.stat.ModTime != f2.stat.ModTime {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
ls1, ok := f1.f.Sys().(*types.Stat)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
ls2, ok := f2.f.Sys().(*types.Stat)
|
||||
if !ok {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return compareStat(ls1, ls2)
|
||||
return compareStat(f1.stat, f2.stat)
|
||||
}
|
||||
|
||||
// compareStat returns whether the stats are equivalent,
|
||||
|
||||
+3
-3
@@ -194,7 +194,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
|
||||
|
||||
if isRegularFile {
|
||||
if dw.opt.AsyncDataCb != nil {
|
||||
dw.requestAsyncFileData(p, destPath, fi)
|
||||
dw.requestAsyncFileData(p, destPath, fi, &statCopy)
|
||||
}
|
||||
} else {
|
||||
return dw.processChange(kind, p, fi, nil)
|
||||
@@ -203,7 +203,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo) {
|
||||
func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo, st *types.Stat) {
|
||||
// todo: limit worker threads
|
||||
dw.eg.Go(func() error {
|
||||
if err := dw.processChange(ChangeKindAdd, p, fi, &lazyFileWriter{
|
||||
@@ -211,7 +211,7 @@ func (dw *DiskWriter) requestAsyncFileData(p, dest string, fi os.FileInfo) {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return chtimes(dest, fi.ModTime().UnixNano()) // TODO: parent dirs
|
||||
return chtimes(dest, st.ModTime) // TODO: parent dirs
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ require (
|
||||
github.com/pkg/errors v0.8.1
|
||||
github.com/sirupsen/logrus v1.0.3 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
golang.org/x/crypto v0.0.0-20190129210102-0709b304e793 // indirect
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793 // indirect
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
|
||||
|
||||
+4
-4
@@ -133,7 +133,7 @@ func (r *receiver) run(ctx context.Context) error {
|
||||
if !r.merge {
|
||||
destWalker = GetWalkerFn(r.dest)
|
||||
}
|
||||
err := doubleWalkDiff(ctx, dw.HandleChange, destWalker, w.fill)
|
||||
err := doubleWalkDiff(ctx, dw.HandleChange, destWalker, w.fill, r.filter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -180,11 +180,11 @@ func (r *receiver) run(ctx context.Context) error {
|
||||
r.mu.Unlock()
|
||||
}
|
||||
i++
|
||||
cp := ¤tPath{path: p.Stat.Path, f: &StatInfo{p.Stat}}
|
||||
if err := r.orderValidator.HandleChange(ChangeKindAdd, cp.path, cp.f, nil); err != nil {
|
||||
cp := ¤tPath{path: p.Stat.Path, stat: p.Stat}
|
||||
if err := r.orderValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.hlValidator.HandleChange(ChangeKindAdd, cp.path, cp.f, nil); err != nil {
|
||||
if err := r.hlValidator.HandleChange(ChangeKindAdd, cp.path, &StatInfo{cp.stat}, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := w.update(cp); err != nil {
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package types
|
||||
|
||||
import "os"
|
||||
|
||||
func (s Stat) IsDir() bool {
|
||||
return os.FileMode(s.Mode).IsDir()
|
||||
}
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
## util [](https://godoc.org/vbom.ml/util)
|
||||
|
||||
import "vbom.ml/util"
|
||||
|
||||
Go utility packages.
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
## sortorder [](https://godoc.org/vbom.ml/util/sortorder)
|
||||
|
||||
import "vbom.ml/util/sortorder"
|
||||
|
||||
Sort orders and comparison functions.
|
||||
Reference in New Issue
Block a user