mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-07-09 21:17:09 +08:00
monitor: Enable to exec into the container
Signed-off-by: Kohei Tokunaga <ktokunaga.mail@gmail.com>
This commit is contained in:
@ -3,12 +3,15 @@ package local
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/containerd/console"
|
||||
"github.com/docker/buildx/build"
|
||||
cbuild "github.com/docker/buildx/controller/build"
|
||||
"github.com/docker/buildx/controller/control"
|
||||
controllerapi "github.com/docker/buildx/controller/pb"
|
||||
"github.com/docker/buildx/controller/processes"
|
||||
"github.com/docker/buildx/util/ioset"
|
||||
"github.com/docker/cli/cli/command"
|
||||
"github.com/moby/buildkit/client"
|
||||
"github.com/pkg/errors"
|
||||
@ -18,6 +21,7 @@ func NewLocalBuildxController(ctx context.Context, dockerCli command.Cli) contro
|
||||
return &localController{
|
||||
dockerCli: dockerCli,
|
||||
ref: "local",
|
||||
processes: processes.NewManager(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,9 +29,17 @@ type localController struct {
|
||||
dockerCli command.Cli
|
||||
ref string
|
||||
resultCtx *build.ResultContext
|
||||
processes *processes.Manager
|
||||
|
||||
buildOnGoing atomic.Bool
|
||||
}
|
||||
|
||||
func (b *localController) Build(ctx context.Context, options controllerapi.BuildOptions, in io.ReadCloser, w io.Writer, out console.File, progressMode string) (string, *client.SolveResponse, error) {
|
||||
if !b.buildOnGoing.CompareAndSwap(false, true) {
|
||||
return "", nil, errors.New("build ongoing")
|
||||
}
|
||||
defer b.buildOnGoing.Store(false)
|
||||
|
||||
resp, res, err := cbuild.RunBuild(ctx, b.dockerCli, options, in, progressMode, nil)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
@ -36,38 +48,64 @@ func (b *localController) Build(ctx context.Context, options controllerapi.Build
|
||||
return b.ref, resp, nil
|
||||
}
|
||||
|
||||
func (b *localController) Invoke(ctx context.Context, ref string, cfg controllerapi.ContainerConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
|
||||
func (b *localController) ListProcesses(ctx context.Context, ref string) (infos []*controllerapi.ProcessInfo, retErr error) {
|
||||
if ref != b.ref {
|
||||
return nil, errors.Errorf("unknown ref %q", ref)
|
||||
}
|
||||
return b.processes.ListProcesses(), nil
|
||||
}
|
||||
|
||||
func (b *localController) DisconnectProcess(ctx context.Context, ref, pid string) error {
|
||||
if ref != b.ref {
|
||||
return errors.Errorf("unknown ref %q", ref)
|
||||
}
|
||||
if b.resultCtx == nil {
|
||||
return errors.New("no build result is registered")
|
||||
return b.processes.DeleteProcess(pid)
|
||||
}
|
||||
|
||||
func (b *localController) cancelRunningProcesses() {
|
||||
b.processes.CancelRunningProcesses()
|
||||
}
|
||||
|
||||
func (b *localController) Invoke(ctx context.Context, ref string, pid string, cfg controllerapi.InvokeConfig, ioIn io.ReadCloser, ioOut io.WriteCloser, ioErr io.WriteCloser) error {
|
||||
if ref != b.ref {
|
||||
return errors.Errorf("unknown ref %q", ref)
|
||||
}
|
||||
ccfg := build.ContainerConfig{
|
||||
ResultCtx: b.resultCtx,
|
||||
Entrypoint: cfg.Entrypoint,
|
||||
Cmd: cfg.Cmd,
|
||||
Env: cfg.Env,
|
||||
Tty: cfg.Tty,
|
||||
Stdin: ioIn,
|
||||
Stdout: ioOut,
|
||||
Stderr: ioErr,
|
||||
|
||||
proc, ok := b.processes.Get(pid)
|
||||
if !ok {
|
||||
// Start a new process.
|
||||
if b.resultCtx == nil {
|
||||
return errors.New("no build result is registered")
|
||||
}
|
||||
var err error
|
||||
proc, err = b.processes.StartProcess(pid, b.resultCtx, &cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !cfg.NoUser {
|
||||
ccfg.User = &cfg.User
|
||||
|
||||
// Attach containerIn to this process
|
||||
ioCancelledCh := make(chan struct{})
|
||||
proc.ForwardIO(&ioset.In{Stdin: ioIn, Stdout: ioOut, Stderr: ioErr}, func() { close(ioCancelledCh) })
|
||||
|
||||
select {
|
||||
case <-ioCancelledCh:
|
||||
return errors.Errorf("io cancelled")
|
||||
case err := <-proc.Done():
|
||||
return err
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
if !cfg.NoCwd {
|
||||
ccfg.Cwd = &cfg.Cwd
|
||||
}
|
||||
return build.Invoke(ctx, ccfg)
|
||||
}
|
||||
|
||||
func (b *localController) Kill(context.Context) error {
|
||||
return nil // nop
|
||||
b.cancelRunningProcesses()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *localController) Close() error {
|
||||
// TODO: cancel current build and invoke
|
||||
b.cancelRunningProcesses()
|
||||
// TODO: cancel ongoing builds?
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -76,5 +114,6 @@ func (b *localController) List(ctx context.Context) (res []string, _ error) {
|
||||
}
|
||||
|
||||
func (b *localController) Disconnect(ctx context.Context, key string) error {
|
||||
return nil // nop
|
||||
b.cancelRunningProcesses()
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user