BREAKING CHANGE: resolve gRPC API proxy targets (machines) on server instead of client, needs upgrade to v0.20 (#247)

Co-authored-by: Pasha Sviderski <me@psviderski.name>
This commit is contained in:
Justin Bradford
2026-05-19 15:22:50 +10:00
committed by GitHub
co-authored by Pasha Sviderski
parent 03ff4cd51d
commit c95136eae6
29 changed files with 914 additions and 741 deletions
+43 -42
View File
@@ -74,7 +74,7 @@ func (cli *Client) createServiceContainerWithPull(
resp.Name = containerName
// Proxy Docker gRPC requests to the selected machine.
ctx = proxyToMachine(ctx, machine.Machine)
ctx = cli.ProxySingleMachineContext(ctx, machine.Machine.Id)
pw := progress.ContextWriter(ctx)
eventID := cliprogress.NewContainerEventID(ctx, containerName, machine.Machine.Name)
@@ -259,27 +259,43 @@ func (cli *Client) InspectContainer(
return svc.FindContainer(containerNameOrID)
}
// StartContainer starts the specified container within the service.
func (cli *Client) StartContainer(ctx context.Context, serviceNameOrID, containerNameOrID string) error {
// containerOperationContext holds the context needed to perform an operation on a container.
type containerOperationContext struct {
ctx context.Context
containerID string
eventID string
}
// resolveContainerOperation resolves a container by name/ID and prepares the context for an operation.
func (cli *Client) resolveContainerOperation(
ctx context.Context, serviceNameOrID, containerNameOrID string,
) (containerOperationContext, error) {
ctr, err := cli.InspectContainer(ctx, serviceNameOrID, containerNameOrID)
if err != nil {
return err
return containerOperationContext{}, err
}
machine, err := cli.InspectMachine(ctx, ctr.MachineID)
eventID := cliprogress.ContainerEventID(ctx, ctr.Container.ServiceSpec.Name, ctr.Container.ID, ctr.MachineName)
return containerOperationContext{
ctx: cli.ProxySingleMachineContext(ctx, ctr.MachineID),
containerID: ctr.Container.ID,
eventID: eventID,
}, nil
}
// StartContainer starts the specified container within the service.
func (cli *Client) StartContainer(ctx context.Context, serviceNameOrID, containerNameOrID string) error {
op, err := cli.resolveContainerOperation(ctx, serviceNameOrID, containerNameOrID)
if err != nil {
return fmt.Errorf("inspect machine '%s': %w", ctr.MachineID, err)
}
ctx = proxyToMachine(ctx, machine.Machine)
pw := progress.ContextWriter(ctx)
eventID := cliprogress.ContainerEventID(ctx, ctr.Container.ServiceSpec.Name, ctr.Container.ID, machine.Machine.Name)
pw.Event(progress.StartingEvent(eventID))
if err = cli.Docker.StartContainer(ctx, ctr.Container.ID, container.StartOptions{}); err != nil {
return err
}
pw.Event(progress.StartedEvent(eventID))
pw := progress.ContextWriter(op.ctx)
pw.Event(progress.StartingEvent(op.eventID))
if err = cli.Docker.StartContainer(op.ctx, op.containerID, container.StartOptions{}); err != nil {
return err
}
pw.Event(progress.StartedEvent(op.eventID))
return nil
}
@@ -290,25 +306,17 @@ func (cli *Client) StartContainer(ctx context.Context, serviceNameOrID, containe
func (cli *Client) StopContainer(
ctx context.Context, serviceNameOrID, containerNameOrID string, opts container.StopOptions,
) error {
ctr, err := cli.InspectContainer(ctx, serviceNameOrID, containerNameOrID)
op, err := cli.resolveContainerOperation(ctx, serviceNameOrID, containerNameOrID)
if err != nil {
return err
}
machine, err := cli.InspectMachine(ctx, ctr.MachineID)
if err != nil {
return fmt.Errorf("inspect machine '%s': %w", ctr.MachineID, err)
}
ctx = proxyToMachine(ctx, machine.Machine)
pw := progress.ContextWriter(ctx)
eventID := cliprogress.ContainerEventID(ctx, ctr.Container.ServiceSpec.Name, ctr.Container.ID, machine.Machine.Name)
pw.Event(progress.StoppingEvent(eventID))
if err = cli.Docker.StopContainer(ctx, ctr.Container.ID, opts); err != nil {
pw := progress.ContextWriter(op.ctx)
pw.Event(progress.StoppingEvent(op.eventID))
if err = cli.Docker.StopContainer(op.ctx, op.containerID, opts); err != nil {
return err
}
pw.Event(progress.StoppedEvent(eventID))
pw.Event(progress.StoppedEvent(op.eventID))
return nil
}
@@ -319,25 +327,18 @@ func (cli *Client) StopContainer(
func (cli *Client) RemoveContainer(
ctx context.Context, serviceNameOrID, containerNameOrID string, opts container.RemoveOptions,
) error {
ctr, err := cli.InspectContainer(ctx, serviceNameOrID, containerNameOrID)
op, err := cli.resolveContainerOperation(ctx, serviceNameOrID, containerNameOrID)
if err != nil {
return err
}
machine, err := cli.InspectMachine(ctx, ctr.MachineID)
if err != nil {
return fmt.Errorf("inspect machine '%s': %w", ctr.MachineID, err)
}
ctx = proxyToMachine(ctx, machine.Machine)
pw := progress.ContextWriter(op.ctx)
pw := progress.ContextWriter(ctx)
eventID := cliprogress.ContainerEventID(ctx, ctr.Container.ServiceSpec.Name, ctr.Container.ID, machine.Machine.Name)
pw.Event(progress.RemovingEvent(eventID))
if err = cli.Docker.RemoveServiceContainer(ctx, ctr.Container.ID, opts); err != nil {
pw.Event(progress.RemovingEvent(op.eventID))
if err = cli.Docker.RemoveServiceContainer(op.ctx, op.containerID, opts); err != nil {
return err
}
pw.Event(progress.RemovedEvent(eventID))
pw.Event(progress.RemovedEvent(op.eventID))
return nil
}
@@ -374,7 +375,7 @@ func (cli *Client) ExecContainer(
}
// Proxy Docker gRPC requests to the machine hosting the container
ctx = proxyToMachine(ctx, machine.Machine)
ctx = cli.ProxySingleMachineContext(ctx, machine.Machine.Id)
// Execute the command in the container
exitCode, err := cli.Docker.ExecContainer(ctx, machinedocker.ExecConfig{
@@ -451,7 +452,7 @@ func (cli *Client) WaitContainerHealthy(
}
// For containers with a health check, wait until Docker reports healthy or unhealthy.
mctx := proxyToMachine(ctx, machine.Machine)
mctx := cli.ProxySingleMachineContext(ctx, machine.Machine.Id)
mctx, cancel := context.WithTimeout(mctx, healthcheckTimeout(mc.Container.Config.Healthcheck))
defer cancel()
ticker := time.NewTicker(1 * time.Second)