Skip to content

Commit

Permalink
containerd: Use exec to copy files instead of mounting FS
Browse files Browse the repository at this point in the history
  • Loading branch information
cezarsa committed Jan 25, 2021
1 parent e438374 commit 27b4cee
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 31 deletions.
25 changes: 24 additions & 1 deletion internal/containerd/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"io/ioutil"

"github.com/containerd/containerd"
"github.com/containerd/containerd/cio"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/tsuru/tsuru/exec"
Expand Down Expand Up @@ -62,6 +63,11 @@ func (e *containerdExecutor) ExecuteAsUser(user string, opts exec.ExecuteOptions
if opts.Stderr == nil {
opts.Stderr = ioutil.Discard
}
var stdinCloser *readerCloser
if opts.Stdin != nil {
stdinCloser = &readerCloser{reader: opts.Stdin, ctx: e.ctx}
opts.Stdin = stdinCloser
}
ioCreator := cio.NewCreator(cio.WithStreams(opts.Stdin, opts.Stdout, opts.Stderr))

execID := "exec-" + randID()
Expand All @@ -70,6 +76,9 @@ func (e *containerdExecutor) ExecuteAsUser(user string, opts exec.ExecuteOptions
return err
}
defer process.Delete(e.ctx)
if stdinCloser != nil {
stdinCloser.process = process
}

statusCh, err := process.Wait(e.ctx)
if err != nil {
Expand All @@ -84,7 +93,7 @@ func (e *containerdExecutor) ExecuteAsUser(user string, opts exec.ExecuteOptions
select {
case status := <-statusCh:
if status.ExitCode() != 0 {
return fmt.Errorf("unexpected exit code %#+v while running %v", status.ExitCode(), fullCmd)
return fmt.Errorf("unexpected exit code %d while running %v", status.ExitCode(), fullCmd)
}
case <-e.ctx.Done():
return e.ctx.Err()
Expand All @@ -97,3 +106,17 @@ func randID() string {
io.CopyN(h, rand.Reader, 10)
return fmt.Sprintf("%x", h.Sum(nil))[:20]
}

type readerCloser struct {
reader io.Reader
process containerd.Process
ctx context.Context
}

func (r *readerCloser) Read(p []byte) (int, error) {
n, err := r.reader.Read(p)
if err == io.EOF && r.process != nil {
r.process.CloseIO(r.ctx, containerd.WithStdinCloser)
}
return n, err
}
10 changes: 6 additions & 4 deletions internal/containerd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package containerd
import (
"context"
"encoding/json"
"fmt"
"io"
"sync"
"time"
Expand Down Expand Up @@ -74,6 +75,7 @@ func pushWithProgress(ctx context.Context, client *containerd.Client, ref string
}

if done {
fw.Encode(imageProgess{Status: fmt.Sprintf("Pushed %s", ref)})
return nil
}
case <-doneCh:
Expand Down Expand Up @@ -118,10 +120,10 @@ type progressDetail struct {
}

type imageProgess struct {
Status string `json:"status"`
ProgressDetail progressDetail `json:"progressDetail"`
Progress string `json:"progress"`
ID string `json:"id"`
Status string `json:"status,omitempty"`
ProgressDetail progressDetail `json:"progressDetail,omitempty"`
Progress string `json:"progress,omitempty"`
ID string `json:"id,omitempty"`
}

func (j *pushjobs) status() []imageProgess {
Expand Down
40 changes: 14 additions & 26 deletions internal/containerd/sidecar.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import (
"io"
"net/http"
"os"
"path/filepath"
"strings"
"time"

"github.com/AkihiroSuda/nerdctl/pkg/imgutil/commit"
"github.com/containerd/containerd"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
refDocker "github.com/containerd/containerd/reference/docker"
remoteDocker "github.com/containerd/containerd/remotes/docker"
"github.com/pkg/errors"
Expand Down Expand Up @@ -127,38 +125,28 @@ func (s *containerdSidecar) Commit(ctx context.Context, image string) (string, e
}

func (s *containerdSidecar) Upload(ctx context.Context, fileName string) error {
container, err := s.client.LoadContainer(ctx, s.primaryContainerID)
if err != nil {
return err
}
info, err := container.Info(ctx)
executor := s.Executor(ctx)
srcFile, err := os.Open(fileName)
if err != nil {
return err
}
mounts, err := s.client.SnapshotService(info.Snapshotter).Mounts(ctx, s.primaryContainerID)
defer srcFile.Close()
info, err := srcFile.Stat()
if err != nil {
return err
return errors.Wrap(err, "failed to stat input file")
}
srcFile, err := os.Open(fileName)
if err != nil {
return err
var stdin io.Reader
if info.Size() > 0 {
stdin = srcFile
}
defer srcFile.Close()
err = mount.WithTempMount(ctx, mounts, func(root string) error {
dstFileName := filepath.Join(root, srcFile.Name())
var dstFile *os.File
dstFile, err = os.Create(dstFileName)
if err != nil {
return err
}
_, err = io.Copy(dstFile, srcFile)
if err != nil {
return err
}
return dstFile.Close()
err = executor.Execute(exec.ExecuteOptions{
Cmd: "/bin/sh",
Args: []string{"-c", fmt.Sprintf("cat >%s", srcFile.Name())},
Stdin: stdin,
Dir: "/",
})
if err != nil {
return errors.Wrapf(err, "unable to mount %#v", mounts)
return errors.Wrap(err, "failed to execute copy command")
}
return nil
}
Expand Down

0 comments on commit 27b4cee

Please sign in to comment.