Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix an issue on Windows, where dockerfile is not removed from daemon-side build context #3

Open
wants to merge 6 commits into
base: builder-remote-context-4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/server/router/build/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ type Backend interface {
// by the caller.
//
// TODO: make this return a reference instead of string
BuildFromContext(ctx context.Context, src io.ReadCloser, remote string, buildOptions *types.ImageBuildOptions, pg backend.ProgressWriter) (string, error)
BuildFromContext(ctx context.Context, src io.ReadCloser, buildOptions *types.ImageBuildOptions, pg backend.ProgressWriter) (string, error)
}
9 changes: 4 additions & 5 deletions api/server/router/build/build_routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/progress"
"github.com/docker/docker/pkg/streamformatter"
"github.com/docker/go-units"
units "github.com/docker/go-units"
"golang.org/x/net/context"
)

Expand Down Expand Up @@ -57,6 +57,7 @@ func newImageBuildOptions(ctx context.Context, r *http.Request) (*types.ImageBui
options.SecurityOpt = r.Form["securityopt"]
options.Squash = httputils.BoolValue(r, "squash")
options.Target = r.FormValue("target")
options.RemoteContext = r.FormValue("remote")

if r.Form.Get("shmsize") != "" {
shmSize, err := strconv.ParseInt(r.Form.Get("shmsize"), 10, 64)
Expand Down Expand Up @@ -184,16 +185,14 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
}
buildOptions.AuthConfigs = authConfigs

remoteURL := r.FormValue("remote")

// Currently, only used if context is from a remote url.
// Look at code in DetectContextFromRemoteURL for more information.
createProgressReader := func(in io.ReadCloser) io.ReadCloser {
progressOutput := sf.NewProgressOutput(output, true)
if buildOptions.SuppressOutput {
progressOutput = sf.NewProgressOutput(notVerboseBuffer, true)
}
return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", remoteURL)
return progress.NewProgressReader(in, progressOutput, r.ContentLength, "Downloading context", buildOptions.RemoteContext)
}

out := io.Writer(output)
Expand All @@ -211,7 +210,7 @@ func (br *buildRouter) postBuild(ctx context.Context, w http.ResponseWriter, r *
ProgressReaderFunc: createProgressReader,
}

imgID, err := br.backend.BuildFromContext(ctx, r.Body, remoteURL, buildOptions, pg)
imgID, err := br.backend.BuildFromContext(ctx, r.Body, buildOptions, pg)
if err != nil {
return errf(err)
}
Expand Down
12 changes: 12 additions & 0 deletions api/server/router/session/backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package session

import (
"net/http"

"golang.org/x/net/context"
)

// Backend abstracts an image builder whose only purpose is to build an image referenced by an imageID.
type Backend interface {
HandleHTTPRequest(ctx context.Context, w http.ResponseWriter, r *http.Request) error
}
29 changes: 29 additions & 0 deletions api/server/router/session/session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package session

import "github.com/docker/docker/api/server/router"

// sessionRouter is a router to talk with the session controller
type sessionRouter struct {
backend Backend
routes []router.Route
}

// NewRouter initializes a new session router
func NewRouter(b Backend) router.Router {
r := &sessionRouter{
backend: b,
}
r.initRoutes()
return r
}

// Routes returns the available routers to the session controller
func (r *sessionRouter) Routes() []router.Route {
return r.routes
}

func (r *sessionRouter) initRoutes() {
r.routes = []router.Route{
router.Experimental(router.NewPostRoute("/session", r.startSession)),
}
}
11 changes: 11 additions & 0 deletions api/server/router/session/session_routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package session

import (
"net/http"

"golang.org/x/net/context"
)

func (sr *sessionRouter) startSession(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
return sr.backend.HandleHTTPRequest(ctx, w, r)
}
92 changes: 10 additions & 82 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package builder

import (
"io"
"os"
"time"

"github.com/docker/distribution/reference"
Expand All @@ -22,85 +21,17 @@ const (
DefaultDockerfileName string = "Dockerfile"
)

// Context represents a file system tree.
type Context interface {
// Source defines a location that can be used as a source for the ADD/COPY
// instructions in the builder.
type Source interface {
// Root returns root path for accessing source
Root() string
// Close allows to signal that the filesystem tree won't be used anymore.
// For Context implementations using a temporary directory, it is recommended to
// delete the temporary directory in Close().
Close() error
// Stat returns an entry corresponding to path if any.
// It is recommended to return an error if path was not found.
// If path is a symlink it also returns the path to the target file.
Stat(path string) (string, FileInfo, error)
// Open opens path from the context and returns a readable stream of it.
Open(path string) (io.ReadCloser, error)
// Walk walks the tree of the context with the function passed to it.
Walk(root string, walkFn WalkFunc) error
}

// WalkFunc is the type of the function called for each file or directory visited by Context.Walk().
type WalkFunc func(path string, fi FileInfo, err error) error

// ModifiableContext represents a modifiable Context.
// TODO: remove this interface once we can get rid of Remove()
type ModifiableContext interface {
Context
// Remove deletes the entry specified by `path`.
// It is usual for directory entries to delete all its subentries.
Remove(path string) error
}

// FileInfo extends os.FileInfo to allow retrieving an absolute path to the file.
// TODO: remove this interface once pkg/archive exposes a walk function that Context can use.
type FileInfo interface {
os.FileInfo
Path() string
}

// PathFileInfo is a convenience struct that implements the FileInfo interface.
type PathFileInfo struct {
os.FileInfo
// FilePath holds the absolute path to the file.
FilePath string
// FileName holds the basename for the file.
FileName string
}

// Path returns the absolute path to the file.
func (fi PathFileInfo) Path() string {
return fi.FilePath
}

// Name returns the basename of the file.
func (fi PathFileInfo) Name() string {
if fi.FileName != "" {
return fi.FileName
}
return fi.FileInfo.Name()
}

// Hashed defines an extra method intended for implementations of os.FileInfo.
type Hashed interface {
// Hash returns the hash of a file.
Hash() string
SetHash(string)
}

// HashedFileInfo is a convenient struct that augments FileInfo with a field.
type HashedFileInfo struct {
FileInfo
// FileHash represents the hash of a file.
FileHash string
}

// Hash returns the hash of a file.
func (fi HashedFileInfo) Hash() string {
return fi.FileHash
}

// SetHash sets the hash of a file.
func (fi *HashedFileInfo) SetHash(h string) {
fi.FileHash = h
// Hash returns a checksum for a file
Hash(path string) (string, error)
}

// Backend abstracts calls to a Docker Daemon.
Expand Down Expand Up @@ -134,12 +65,9 @@ type Backend interface {

// ContainerCopy copies/extracts a source FileInfo to a destination path inside a container
// specified by a container object.
// TODO: make an Extract method instead of passing `decompress`
// TODO: do not pass a FileInfo, instead refactor the archive package to export a Walk function that can be used
// with Context.Walk
// ContainerCopy(name string, res string) (io.ReadCloser, error)
// TODO: use copyBackend api
CopyOnBuild(containerID string, destPath string, src FileInfo, decompress bool) error
// TODO: extract in the builder instead of passing `decompress`
// TODO: use containerd/fs.changestream instead as a source
CopyOnBuild(containerID string, destPath string, srcRoot string, srcPath string, decompress bool) error

// HasExperimental checks if the backend supports experimental features
HasExperimental() bool
Expand Down
Loading