feat(adapters/docker): add RenameContainer method to runtime
Add RenameContainer to ContainerRuntime interface and implement in Docker adapter. This enables renaming containers after zero-downtime deployment to restore canonical naming.
- commit
- e555572296dc08d0c9142320cfcfeca8b48bfea1
- author
- brice · · 2026-01-12 21:07 UTC
- committer
- brice · · 2026-01-12 18:34 UTC
- parent
- 22299cc
- signature
- unsigned
3 files · +84 -0
M internal/adapters/out/docker/runtime.go +20 -0
| @@ -208,6 +208,26 @@ func (r *Runtime) RemoveContainer(ctx context.Context, containerID string, force | |||
| 208 | 208 | return nil | |
| 209 | 209 | } | |
| 210 | 210 | ||
| 211 | + | // RenameContainer renames a container. | |
| 212 | + | func (r *Runtime) RenameContainer(ctx context.Context, containerID, newName string) error { | |
| 213 | + | ctx = zerowrap.CtxWithFields(ctx, map[string]any{ | |
| 214 | + | zerowrap.FieldLayer: "adapter", | |
| 215 | + | zerowrap.FieldAdapter: "docker", | |
| 216 | + | zerowrap.FieldAction: "RenameContainer", | |
| 217 | + | zerowrap.FieldEntityID: containerID, | |
| 218 | + | "new_name": newName, | |
| 219 | + | }) | |
| 220 | + | log := zerowrap.FromCtx(ctx) | |
| 221 | + | ||
| 222 | + | err := r.client.ContainerRename(ctx, containerID, newName) | |
| 223 | + | if err != nil { | |
| 224 | + | return log.WrapErr(err, "failed to rename container") | |
| 225 | + | } | |
| 226 | + | ||
| 227 | + | log.Info().Msg("container renamed") | |
| 228 | + | return nil | |
| 229 | + | } | |
| 230 | + | ||
| 211 | 231 | // ListContainers lists containers. | |
| 212 | 232 | func (r *Runtime) ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) { | |
| 213 | 233 | ctx = zerowrap.CtxWithFields(ctx, map[string]any{ | |
| @@ -208,6 +208,26 @@ func (r *Runtime) RemoveContainer(ctx context.Context, containerID string, force | |||||
| 208 | return nil | 208 | return nil | ||
| 209 | } | 209 | } | ||
| 210 | 210 | ||||
| 211 | + | // RenameContainer renames a container. | |||
| 212 | + | func (r *Runtime) RenameContainer(ctx context.Context, containerID, newName string) error { | |||
| 213 | + | ctx = zerowrap.CtxWithFields(ctx, map[string]any{ | |||
| 214 | + | zerowrap.FieldLayer: "adapter", | |||
| 215 | + | zerowrap.FieldAdapter: "docker", | |||
| 216 | + | zerowrap.FieldAction: "RenameContainer", | |||
| 217 | + | zerowrap.FieldEntityID: containerID, | |||
| 218 | + | "new_name": newName, | |||
| 219 | + | }) | |||
| 220 | + | log := zerowrap.FromCtx(ctx) | |||
| 221 | + | ||||
| 222 | + | err := r.client.ContainerRename(ctx, containerID, newName) | |||
| 223 | + | if err != nil { | |||
| 224 | + | return log.WrapErr(err, "failed to rename container") | |||
| 225 | + | } | |||
| 226 | + | ||||
| 227 | + | log.Info().Msg("container renamed") | |||
| 228 | + | return nil | |||
| 229 | + | } | |||
| 230 | + | ||||
| 211 | // ListContainers lists containers. | 231 | // ListContainers lists containers. | ||
| 212 | func (r *Runtime) ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) { | 232 | func (r *Runtime) ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) { | ||
| 213 | ctx = zerowrap.CtxWithFields(ctx, map[string]any{ | 233 | ctx = zerowrap.CtxWithFields(ctx, map[string]any{ | ||
M internal/boundaries/out/mocks/mock_container_runtime.go +63 -0
| @@ -1658,6 +1658,69 @@ func (_c *MockContainerRuntime_RemoveVolume_Call) RunAndReturn(run func(ctx cont | |||
| 1658 | 1658 | return _c | |
| 1659 | 1659 | } | |
| 1660 | 1660 | ||
| 1661 | + | // RenameContainer provides a mock function for the type MockContainerRuntime | |
| 1662 | + | func (_mock *MockContainerRuntime) RenameContainer(ctx context.Context, containerID string, newName string) error { | |
| 1663 | + | ret := _mock.Called(ctx, containerID, newName) | |
| 1664 | + | ||
| 1665 | + | if len(ret) == 0 { | |
| 1666 | + | panic("no return value specified for RenameContainer") | |
| 1667 | + | } | |
| 1668 | + | ||
| 1669 | + | var r0 error | |
| 1670 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) error); ok { | |
| 1671 | + | r0 = returnFunc(ctx, containerID, newName) | |
| 1672 | + | } else { | |
| 1673 | + | r0 = ret.Error(0) | |
| 1674 | + | } | |
| 1675 | + | return r0 | |
| 1676 | + | } | |
| 1677 | + | ||
| 1678 | + | // MockContainerRuntime_RenameContainer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RenameContainer' | |
| 1679 | + | type MockContainerRuntime_RenameContainer_Call struct { | |
| 1680 | + | *mock.Call | |
| 1681 | + | } | |
| 1682 | + | ||
| 1683 | + | // RenameContainer is a helper method to define mock.On call | |
| 1684 | + | // - ctx context.Context | |
| 1685 | + | // - containerID string | |
| 1686 | + | // - newName string | |
| 1687 | + | func (_e *MockContainerRuntime_Expecter) RenameContainer(ctx interface{}, containerID interface{}, newName interface{}) *MockContainerRuntime_RenameContainer_Call { | |
| 1688 | + | return &MockContainerRuntime_RenameContainer_Call{Call: _e.mock.On("RenameContainer", ctx, containerID, newName)} | |
| 1689 | + | } | |
| 1690 | + | ||
| 1691 | + | func (_c *MockContainerRuntime_RenameContainer_Call) Run(run func(ctx context.Context, containerID string, newName string)) *MockContainerRuntime_RenameContainer_Call { | |
| 1692 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1693 | + | var arg0 context.Context | |
| 1694 | + | if args[0] != nil { | |
| 1695 | + | arg0 = args[0].(context.Context) | |
| 1696 | + | } | |
| 1697 | + | var arg1 string | |
| 1698 | + | if args[1] != nil { | |
| 1699 | + | arg1 = args[1].(string) | |
| 1700 | + | } | |
| 1701 | + | var arg2 string | |
| 1702 | + | if args[2] != nil { | |
| 1703 | + | arg2 = args[2].(string) | |
| 1704 | + | } | |
| 1705 | + | run( | |
| 1706 | + | arg0, | |
| 1707 | + | arg1, | |
| 1708 | + | arg2, | |
| 1709 | + | ) | |
| 1710 | + | }) | |
| 1711 | + | return _c | |
| 1712 | + | } | |
| 1713 | + | ||
| 1714 | + | func (_c *MockContainerRuntime_RenameContainer_Call) Return(err error) *MockContainerRuntime_RenameContainer_Call { | |
| 1715 | + | _c.Call.Return(err) | |
| 1716 | + | return _c | |
| 1717 | + | } | |
| 1718 | + | ||
| 1719 | + | func (_c *MockContainerRuntime_RenameContainer_Call) RunAndReturn(run func(ctx context.Context, containerID string, newName string) error) *MockContainerRuntime_RenameContainer_Call { | |
| 1720 | + | _c.Call.Return(run) | |
| 1721 | + | return _c | |
| 1722 | + | } | |
| 1723 | + | ||
| 1661 | 1724 | // RestartContainer provides a mock function for the type MockContainerRuntime | |
| 1662 | 1725 | func (_mock *MockContainerRuntime) RestartContainer(ctx context.Context, containerID string) error { | |
| 1663 | 1726 | ret := _mock.Called(ctx, containerID) | |
| @@ -1658,6 +1658,69 @@ func (_c *MockContainerRuntime_RemoveVolume_Call) RunAndReturn(run func(ctx cont | |||||
| 1658 | return _c | 1658 | return _c | ||
| 1659 | } | 1659 | } | ||
| 1660 | 1660 | ||||
| 1661 | + | // RenameContainer provides a mock function for the type MockContainerRuntime | |||
| 1662 | + | func (_mock *MockContainerRuntime) RenameContainer(ctx context.Context, containerID string, newName string) error { | |||
| 1663 | + | ret := _mock.Called(ctx, containerID, newName) | |||
| 1664 | + | ||||
| 1665 | + | if len(ret) == 0 { | |||
| 1666 | + | panic("no return value specified for RenameContainer") | |||
| 1667 | + | } | |||
| 1668 | + | ||||
| 1669 | + | var r0 error | |||
| 1670 | + | if returnFunc, ok := ret.Get(0).(func(context.Context, string, string) error); ok { | |||
| 1671 | + | r0 = returnFunc(ctx, containerID, newName) | |||
| 1672 | + | } else { | |||
| 1673 | + | r0 = ret.Error(0) | |||
| 1674 | + | } | |||
| 1675 | + | return r0 | |||
| 1676 | + | } | |||
| 1677 | + | ||||
| 1678 | + | // MockContainerRuntime_RenameContainer_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RenameContainer' | |||
| 1679 | + | type MockContainerRuntime_RenameContainer_Call struct { | |||
| 1680 | + | *mock.Call | |||
| 1681 | + | } | |||
| 1682 | + | ||||
| 1683 | + | // RenameContainer is a helper method to define mock.On call | |||
| 1684 | + | // - ctx context.Context | |||
| 1685 | + | // - containerID string | |||
| 1686 | + | // - newName string | |||
| 1687 | + | func (_e *MockContainerRuntime_Expecter) RenameContainer(ctx interface{}, containerID interface{}, newName interface{}) *MockContainerRuntime_RenameContainer_Call { | |||
| 1688 | + | return &MockContainerRuntime_RenameContainer_Call{Call: _e.mock.On("RenameContainer", ctx, containerID, newName)} | |||
| 1689 | + | } | |||
| 1690 | + | ||||
| 1691 | + | func (_c *MockContainerRuntime_RenameContainer_Call) Run(run func(ctx context.Context, containerID string, newName string)) *MockContainerRuntime_RenameContainer_Call { | |||
| 1692 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1693 | + | var arg0 context.Context | |||
| 1694 | + | if args[0] != nil { | |||
| 1695 | + | arg0 = args[0].(context.Context) | |||
| 1696 | + | } | |||
| 1697 | + | var arg1 string | |||
| 1698 | + | if args[1] != nil { | |||
| 1699 | + | arg1 = args[1].(string) | |||
| 1700 | + | } | |||
| 1701 | + | var arg2 string | |||
| 1702 | + | if args[2] != nil { | |||
| 1703 | + | arg2 = args[2].(string) | |||
| 1704 | + | } | |||
| 1705 | + | run( | |||
| 1706 | + | arg0, | |||
| 1707 | + | arg1, | |||
| 1708 | + | arg2, | |||
| 1709 | + | ) | |||
| 1710 | + | }) | |||
| 1711 | + | return _c | |||
| 1712 | + | } | |||
| 1713 | + | ||||
| 1714 | + | func (_c *MockContainerRuntime_RenameContainer_Call) Return(err error) *MockContainerRuntime_RenameContainer_Call { | |||
| 1715 | + | _c.Call.Return(err) | |||
| 1716 | + | return _c | |||
| 1717 | + | } | |||
| 1718 | + | ||||
| 1719 | + | func (_c *MockContainerRuntime_RenameContainer_Call) RunAndReturn(run func(ctx context.Context, containerID string, newName string) error) *MockContainerRuntime_RenameContainer_Call { | |||
| 1720 | + | _c.Call.Return(run) | |||
| 1721 | + | return _c | |||
| 1722 | + | } | |||
| 1723 | + | ||||
| 1661 | // RestartContainer provides a mock function for the type MockContainerRuntime | 1724 | // RestartContainer provides a mock function for the type MockContainerRuntime | ||
| 1662 | func (_mock *MockContainerRuntime) RestartContainer(ctx context.Context, containerID string) error { | 1725 | func (_mock *MockContainerRuntime) RestartContainer(ctx context.Context, containerID string) error { | ||
| 1663 | ret := _mock.Called(ctx, containerID) | 1726 | ret := _mock.Called(ctx, containerID) | ||
M internal/boundaries/out/runtime.go +1 -0
| @@ -19,6 +19,7 @@ type ContainerRuntime interface { | |||
| 19 | 19 | StopContainer(ctx context.Context, containerID string) error | |
| 20 | 20 | RestartContainer(ctx context.Context, containerID string) error | |
| 21 | 21 | RemoveContainer(ctx context.Context, containerID string, force bool) error | |
| 22 | + | RenameContainer(ctx context.Context, containerID, newName string) error | |
| 22 | 23 | ||
| 23 | 24 | // Container inspection | |
| 24 | 25 | ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) | |
| @@ -19,6 +19,7 @@ type ContainerRuntime interface { | |||||
| 19 | StopContainer(ctx context.Context, containerID string) error | 19 | StopContainer(ctx context.Context, containerID string) error | ||
| 20 | RestartContainer(ctx context.Context, containerID string) error | 20 | RestartContainer(ctx context.Context, containerID string) error | ||
| 21 | RemoveContainer(ctx context.Context, containerID string, force bool) error | 21 | RemoveContainer(ctx context.Context, containerID string, force bool) error | ||
| 22 | + | RenameContainer(ctx context.Context, containerID, newName string) error | |||
| 22 | 23 | ||||
| 23 | // Container inspection | 24 | // Container inspection | ||
| 24 | ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) | 25 | ListContainers(ctx context.Context, all bool) ([]*domain.Container, error) | ||