mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
feat: Allow container matching by ID prefix (#175)
This commit is contained in:
@@ -28,7 +28,7 @@ func NewExecCommand() *cobra.Command {
|
|||||||
Use: "exec [OPTIONS] SERVICE [COMMAND ARGS...]",
|
Use: "exec [OPTIONS] SERVICE [COMMAND ARGS...]",
|
||||||
Short: "Execute a command in a running service container",
|
Short: "Execute a command in a running service container",
|
||||||
Long: `Execute a command (interactive shell by default) in a running container within a service.
|
Long: `Execute a command (interactive shell by default) in a running container within a service.
|
||||||
If the service has multiple replicas, the command will be executed in a random container.
|
If the service has multiple replicas and no container ID is specified, the command will be executed in a random container.
|
||||||
`,
|
`,
|
||||||
Example: `
|
Example: `
|
||||||
# Start an interactive shell ("bash" or "sh" will be tried by default)
|
# Start an interactive shell ("bash" or "sh" will be tried by default)
|
||||||
@@ -37,8 +37,8 @@ If the service has multiple replicas, the command will be executed in a random c
|
|||||||
# Start an interactive shell with explicit command
|
# Start an interactive shell with explicit command
|
||||||
uc exec web-service /bin/zsh
|
uc exec web-service /bin/zsh
|
||||||
|
|
||||||
# List files in the specific container of the service
|
# List files in the specific container of the service; --container accepts full ID or a (unique) prefix
|
||||||
uc exec --container d792ea7347e5 web-service ls -la
|
uc exec --container d792e web-service ls -la
|
||||||
|
|
||||||
# Pipe input to a command inside the service container
|
# Pipe input to a command inside the service container
|
||||||
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
||||||
|
|||||||
+14
-5
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/docker/compose/v2/pkg/progress"
|
"github.com/docker/compose/v2/pkg/progress"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
"github.com/docker/docker/pkg/stringid"
|
|
||||||
"github.com/psviderski/uncloud/internal/docker"
|
"github.com/psviderski/uncloud/internal/docker"
|
||||||
machinedocker "github.com/psviderski/uncloud/internal/machine/docker"
|
machinedocker "github.com/psviderski/uncloud/internal/machine/docker"
|
||||||
"github.com/psviderski/uncloud/internal/secret"
|
"github.com/psviderski/uncloud/internal/secret"
|
||||||
@@ -200,7 +199,7 @@ func toPullProgressEvent(jm jsonmessage.JSONMessage) *progress.Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// InspectContainer returns the information about the specified container within the service.
|
// InspectContainer returns the information about the specified container within the service.
|
||||||
// containerNameOrID can be name, ID, or truncated ID of the container.
|
// containerNameOrID can be name, full ID, or ID prefix of the container.
|
||||||
func (cli *Client) InspectContainer(
|
func (cli *Client) InspectContainer(
|
||||||
ctx context.Context, serviceNameOrID, containerNameOrID string,
|
ctx context.Context, serviceNameOrID, containerNameOrID string,
|
||||||
) (api.MachineServiceContainer, error) {
|
) (api.MachineServiceContainer, error) {
|
||||||
@@ -209,13 +208,23 @@ func (cli *Client) InspectContainer(
|
|||||||
return api.MachineServiceContainer{}, fmt.Errorf("inspect service: %w", err)
|
return api.MachineServiceContainer{}, fmt.Errorf("inspect service: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: support matching by any prefix of the container ID
|
prefixMatchCandidates := []api.MachineServiceContainer{}
|
||||||
for _, c := range svc.Containers {
|
for _, c := range svc.Containers {
|
||||||
if c.Container.ID == containerNameOrID ||
|
if c.Container.ID == containerNameOrID ||
|
||||||
c.Container.Name == containerNameOrID ||
|
c.Container.Name == containerNameOrID {
|
||||||
stringid.TruncateID(c.Container.ID) == containerNameOrID {
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(c.Container.ID, containerNameOrID) {
|
||||||
|
prefixMatchCandidates = append(prefixMatchCandidates, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(prefixMatchCandidates) == 1 {
|
||||||
|
return prefixMatchCandidates[0], nil
|
||||||
|
} else if len(prefixMatchCandidates) > 1 {
|
||||||
|
return api.MachineServiceContainer{}, fmt.Errorf(
|
||||||
|
"multiple containers found with ID prefix '%s'", containerNameOrID)
|
||||||
}
|
}
|
||||||
|
|
||||||
return api.MachineServiceContainer{}, api.ErrNotFound
|
return api.MachineServiceContainer{}, api.ErrNotFound
|
||||||
|
|||||||
@@ -224,7 +224,8 @@ func TestExecBasicCommands(t *testing.T) {
|
|||||||
|
|
||||||
var stdout, stderr bytes.Buffer
|
var stdout, stderr bytes.Buffer
|
||||||
|
|
||||||
containerID := service.Containers[1].Container.ID
|
// Use container prefix
|
||||||
|
containerIDPrefix := service.Containers[1].Container.ID[:3]
|
||||||
execOptions := api.ExecOptions{
|
execOptions := api.ExecOptions{
|
||||||
Command: []string{"hostname"},
|
Command: []string{"hostname"},
|
||||||
AttachStdout: true,
|
AttachStdout: true,
|
||||||
@@ -233,7 +234,7 @@ func TestExecBasicCommands(t *testing.T) {
|
|||||||
Stderr: &stderr,
|
Stderr: &stderr,
|
||||||
}
|
}
|
||||||
|
|
||||||
exitCode, err := cli.ExecContainer(ctx, multiServiceName, containerID, execOptions)
|
exitCode, err := cli.ExecContainer(ctx, multiServiceName, containerIDPrefix, execOptions)
|
||||||
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 0, exitCode)
|
assert.Equal(t, 0, exitCode)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Execute a command in a running service container
|
|||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
Execute a command (interactive shell by default) in a running container within a service.
|
Execute a command (interactive shell by default) in a running container within a service.
|
||||||
If the service has multiple replicas, the command will be executed in a random container.
|
If the service has multiple replicas and no container ID is specified, the command will be executed in a random container.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -22,8 +22,8 @@ uc exec [OPTIONS] SERVICE [COMMAND ARGS...] [flags]
|
|||||||
# Start an interactive shell with explicit command
|
# Start an interactive shell with explicit command
|
||||||
uc exec web-service /bin/zsh
|
uc exec web-service /bin/zsh
|
||||||
|
|
||||||
# List files in the specific container of the service
|
# List files in the specific container of the service; --container accepts full ID or a (unique) prefix
|
||||||
uc exec --container d792ea7347e5 web-service ls -la
|
uc exec --container d792e web-service ls -la
|
||||||
|
|
||||||
# Pipe input to a command inside the service container
|
# Pipe input to a command inside the service container
|
||||||
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ Execute a command in a running service container
|
|||||||
## Synopsis
|
## Synopsis
|
||||||
|
|
||||||
Execute a command (interactive shell by default) in a running container within a service.
|
Execute a command (interactive shell by default) in a running container within a service.
|
||||||
If the service has multiple replicas, the command will be executed in a random container.
|
If the service has multiple replicas and no container ID is specified, the command will be executed in a random container.
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -22,8 +22,8 @@ uc service exec [OPTIONS] SERVICE [COMMAND ARGS...] [flags]
|
|||||||
# Start an interactive shell with explicit command
|
# Start an interactive shell with explicit command
|
||||||
uc exec web-service /bin/zsh
|
uc exec web-service /bin/zsh
|
||||||
|
|
||||||
# List files in the specific container of the service
|
# List files in the specific container of the service; --container accepts full ID or a (unique) prefix
|
||||||
uc exec --container d792ea7347e5 web-service ls -la
|
uc exec --container d792e web-service ls -la
|
||||||
|
|
||||||
# Pipe input to a command inside the service container
|
# Pipe input to a command inside the service container
|
||||||
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
cat backup.sql | uc exec -T db-service psql -U postgres mydb
|
||||||
|
|||||||
Reference in New Issue
Block a user