Rename product to dockmv (container, image, module, env vars)
Container/image/service name, Go module path, CLI binary name, and DOCKER_MIGRATE_* env vars still used the old working name; the project is branded DockMV everywhere else (README, logo, Gitea repo). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
.git
|
.git
|
||||||
.gitignore
|
.gitignore
|
||||||
dist/
|
dist/
|
||||||
docker-migrate
|
dockmv
|
||||||
docker-migrate.exe
|
dockmv.exe
|
||||||
web/node_modules
|
web/node_modules
|
||||||
internal/webui/dist
|
internal/webui/dist
|
||||||
*.test
|
*.test
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
# Binaries
|
# Binaries
|
||||||
/docker-migrate
|
/dockmv
|
||||||
/docker-migrate.exe
|
/dockmv.exe
|
||||||
/dist/
|
/dist/
|
||||||
*.test
|
*.test
|
||||||
*.test.exe
|
*.test.exe
|
||||||
|
|||||||
+4
-4
@@ -18,22 +18,22 @@ COPY --from=ui /src/internal/webui/dist ./internal/webui/dist
|
|||||||
# artifact be copied onto a bare-metal host.
|
# artifact be copied onto a bare-metal host.
|
||||||
RUN CGO_ENABLED=0 go build -trimpath \
|
RUN CGO_ENABLED=0 go build -trimpath \
|
||||||
-ldflags "-s -w -X main.version=${VERSION}" \
|
-ldflags "-s -w -X main.version=${VERSION}" \
|
||||||
-o /out/docker-migrate .
|
-o /out/dockmv .
|
||||||
|
|
||||||
FROM alpine:3.22
|
FROM alpine:3.22
|
||||||
RUN apk add --no-cache ca-certificates tzdata && \
|
RUN apk add --no-cache ca-certificates tzdata && \
|
||||||
adduser -D -u 10001 migrate
|
adduser -D -u 10001 migrate
|
||||||
COPY --from=build /out/docker-migrate /usr/local/bin/docker-migrate
|
COPY --from=build /out/dockmv /usr/local/bin/dockmv
|
||||||
|
|
||||||
# The container talks to the Docker socket mounted from the host, which is
|
# The container talks to the Docker socket mounted from the host, which is
|
||||||
# owned by root:docker. It therefore runs as root by default; set --user to
|
# owned by root:docker. It therefore runs as root by default; set --user to
|
||||||
# override when the socket permissions on your host allow it.
|
# override when the socket permissions on your host allow it.
|
||||||
ENV DOCKER_MIGRATE_DATA=/data
|
ENV DOCKMV_DATA=/data
|
||||||
VOLUME ["/data"]
|
VOLUME ["/data"]
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s \
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=5s \
|
||||||
CMD wget -qO- http://127.0.0.1:8080/api/health >/dev/null || exit 1
|
CMD wget -qO- http://127.0.0.1:8080/api/health >/dev/null || exit 1
|
||||||
|
|
||||||
ENTRYPOINT ["docker-migrate"]
|
ENTRYPOINT ["dockmv"]
|
||||||
CMD ["serve", "--addr", "0.0.0.0:8080"]
|
CMD ["serve", "--addr", "0.0.0.0:8080"]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
|
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
|
||||||
LDFLAGS := -s -w -X main.version=$(VERSION)
|
LDFLAGS := -s -w -X main.version=$(VERSION)
|
||||||
BIN := docker-migrate
|
BIN := dockmv
|
||||||
OUT := dist
|
OUT := dist
|
||||||
|
|
||||||
# PowerShell 7+. The publish path lives in scripts/*.ps1 because uploading a
|
# PowerShell 7+. The publish path lives in scripts/*.ps1 because uploading a
|
||||||
@@ -47,7 +47,7 @@ fmt:
|
|||||||
cd web && npx tsc -b --noEmit
|
cd web && npx tsc -b --noEmit
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
docker build --build-arg VERSION=$(VERSION) -t docker-migrate:$(VERSION) -t docker-migrate:latest .
|
docker build --build-arg VERSION=$(VERSION) -t dockmv:$(VERSION) -t dockmv:latest .
|
||||||
|
|
||||||
release: ui
|
release: ui
|
||||||
@mkdir -p $(OUT)
|
@mkdir -p $(OUT)
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ CLI, `bash` and `gzip`.
|
|||||||
On the **source** host:
|
On the **source** host:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <this repo> docker-migrate && cd docker-migrate
|
git clone <this repo> dockmv && cd dockmv
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
docker compose logs docker-migrate # prints the URL, including the access token
|
docker compose logs dockmv # prints the URL, including the access token
|
||||||
```
|
```
|
||||||
|
|
||||||
Then open the printed URL. It binds to `127.0.0.1` only; reach it from your laptop with a tunnel:
|
Then open the printed URL. It binds to `127.0.0.1` only; reach it from your laptop with a tunnel:
|
||||||
@@ -42,16 +42,16 @@ The binary is fully static and embeds the web UI, so there is nothing to install
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
make build # needs Go 1.25+ and Node 20+ ... or just `go build .` if you skip the UI rebuild
|
make build # needs Go 1.25+ and Node 20+ ... or just `go build .` if you skip the UI rebuild
|
||||||
./docker-migrate serve
|
./dockmv serve
|
||||||
```
|
```
|
||||||
|
|
||||||
Prebuilt for several platforms:
|
Prebuilt for several platforms:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
make release # dist/docker-migrate-linux-amd64, -linux-arm64, -darwin-arm64, -windows-amd64
|
make release # dist/dockmv-linux-amd64, -linux-arm64, -darwin-arm64, -windows-amd64
|
||||||
```
|
```
|
||||||
|
|
||||||
`docker-migrate` needs access to the Docker socket on the source host, so run it as a user in the
|
`dockmv` needs access to the Docker socket on the source host, so run it as a user in the
|
||||||
`docker` group (or as root).
|
`docker` group (or as root).
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -206,9 +206,9 @@ free disk space and architecture.
|
|||||||
## Command line
|
## Command line
|
||||||
|
|
||||||
```
|
```
|
||||||
docker-migrate [serve] [flags] start the web interface (default)
|
dockmv [serve] [flags] start the web interface (default)
|
||||||
docker-migrate inspect [flags] print the source inventory as JSON
|
dockmv inspect [flags] print the source inventory as JSON
|
||||||
docker-migrate version
|
dockmv version
|
||||||
```
|
```
|
||||||
|
|
||||||
`serve` flags:
|
`serve` flags:
|
||||||
@@ -225,7 +225,7 @@ docker-migrate version
|
|||||||
`inspect` is handy for scripting and for reporting bugs:
|
`inspect` is handy for scripting and for reporting bugs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-migrate inspect --sizes | jq '.containers[] | {name, image, mounts}'
|
dockmv inspect --sizes | jq '.containers[] | {name, image, mounts}'
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
+6
-6
@@ -1,20 +1,20 @@
|
|||||||
# docker-migrate, running on the SOURCE host.
|
# dockmv, running on the SOURCE host.
|
||||||
#
|
#
|
||||||
# docker compose up -d
|
# docker compose up -d
|
||||||
# docker compose logs docker-migrate # the URL and access token are printed here
|
# docker compose logs dockmv # the URL and access token are printed here
|
||||||
#
|
#
|
||||||
# The container needs the Docker socket to read containers and stream their
|
# The container needs the Docker socket to read containers and stream their
|
||||||
# data. That is equivalent to root on this host, so the UI is protected by a
|
# data. That is equivalent to root on this host, so the UI is protected by a
|
||||||
# generated token and should not be published to an untrusted network.
|
# generated token and should not be published to an untrusted network.
|
||||||
|
|
||||||
services:
|
services:
|
||||||
docker-migrate:
|
dockmv:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
args:
|
args:
|
||||||
VERSION: ${VERSION:-dev}
|
VERSION: ${VERSION:-dev}
|
||||||
image: docker-migrate:latest
|
image: dockmv:latest
|
||||||
container_name: docker-migrate
|
container_name: dockmv
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
# Bind to loopback only. Use an SSH tunnel to reach it from elsewhere:
|
# Bind to loopback only. Use an SSH tunnel to reach it from elsewhere:
|
||||||
@@ -26,7 +26,7 @@ services:
|
|||||||
- migrate-data:/data
|
- migrate-data:/data
|
||||||
environment:
|
environment:
|
||||||
# Set a fixed token to keep the same URL across restarts.
|
# Set a fixed token to keep the same URL across restarts.
|
||||||
# DOCKER_MIGRATE_TOKEN: change-me
|
# DOCKMV_TOKEN: change-me
|
||||||
TZ: ${TZ:-UTC}
|
TZ: ${TZ:-UTC}
|
||||||
command:
|
command:
|
||||||
- serve
|
- serve
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
module github.com/arescom/docker-migrate
|
module github.com/arescom/dockmv
|
||||||
|
|
||||||
go 1.25.0
|
go 1.25.0
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/migrate"
|
"github.com/arescom/dockmv/internal/migrate"
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
"github.com/arescom/docker-migrate/internal/store"
|
"github.com/arescom/dockmv/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
"github.com/arescom/docker-migrate/internal/store"
|
"github.com/arescom/dockmv/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config configures the HTTP server.
|
// Config configures the HTTP server.
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
dockertypes "github.com/docker/docker/api/types"
|
dockertypes "github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
imagetypes "github.com/docker/docker/api/types/image"
|
imagetypes "github.com/docker/docker/api/types/image"
|
||||||
|
|||||||
@@ -7,15 +7,15 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestLiveInventory is a smoke test against whatever daemon the environment
|
// TestLiveInventory is a smoke test against whatever daemon the environment
|
||||||
// points at. It is skipped unless DOCKER_MIGRATE_LIVE_TEST is set, because it
|
// points at. It is skipped unless DOCKMV_LIVE_TEST is set, because it
|
||||||
// needs a real Docker host.
|
// needs a real Docker host.
|
||||||
func TestLiveInventory(t *testing.T) {
|
func TestLiveInventory(t *testing.T) {
|
||||||
if os.Getenv("DOCKER_MIGRATE_LIVE_TEST") == "" {
|
if os.Getenv("DOCKMV_LIVE_TEST") == "" {
|
||||||
t.Skip("set DOCKER_MIGRATE_LIVE_TEST=1 to run against the local daemon")
|
t.Skip("set DOCKMV_LIVE_TEST=1 to run against the local daemon")
|
||||||
}
|
}
|
||||||
c, err := New("")
|
c, err := New("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// renderInstaller generates the shell script shipped inside a migration
|
// renderInstaller generates the shell script shipped inside a migration
|
||||||
@@ -451,14 +451,14 @@ seed_readonly() { # container image destination relpath compressed
|
|||||||
store="$(resolve_mount "$1" "$3")" || { err "cannot resolve storage behind $3"; return 1; }
|
store="$(resolve_mount "$1" "$3")" || { err "cannot resolve storage behind $3"; return 1; }
|
||||||
base="${3##*/}"
|
base="${3##*/}"
|
||||||
stage="dm-stage-$$-${RANDOM}"
|
stage="dm-stage-$$-${RANDOM}"
|
||||||
mountat="/__docker_migrate/$base"
|
mountat="/__dockmv/$base"
|
||||||
$DOCKER create --name "$stage" --volume "$store:$mountat" "$2" >/dev/null \
|
$DOCKER create --name "$stage" --volume "$store:$mountat" "$2" >/dev/null \
|
||||||
|| { err "could not create staging container for $3"; return 1; }
|
|| { err "could not create staging container for $3"; return 1; }
|
||||||
local rc=0
|
local rc=0
|
||||||
if [ "$5" = 1 ]; then
|
if [ "$5" = 1 ]; then
|
||||||
gzip -dc -- "$PKGDIR/$4" | $DOCKER cp -a - "$stage:/__docker_migrate" || rc=$?
|
gzip -dc -- "$PKGDIR/$4" | $DOCKER cp -a - "$stage:/__dockmv" || rc=$?
|
||||||
else
|
else
|
||||||
$DOCKER cp -a - "$stage:/__docker_migrate" < "$PKGDIR/$4" || rc=$?
|
$DOCKER cp -a - "$stage:/__dockmv" < "$PKGDIR/$4" || rc=$?
|
||||||
fi
|
fi
|
||||||
$DOCKER rm -f "$stage" >/dev/null 2>&1 || true
|
$DOCKER rm -f "$stage" >/dev/null 2>&1 || true
|
||||||
if [ "$rc" != 0 ]; then
|
if [ "$rc" != 0 ]; then
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildPrepared(t *testing.T, c *spec.Container, vols []spec.Volume, nets []spec.Network) *Prepared {
|
func buildPrepared(t *testing.T, c *spec.Container, vols []spec.Volume, nets []spec.Network) *Prepared {
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PackageFormat selects how the finished package is laid out on disk.
|
// PackageFormat selects how the finished package is laid out on disk.
|
||||||
@@ -102,7 +102,7 @@ func (p *Packager) Run(ctx context.Context, j *job.Job) (*Result, error) {
|
|||||||
man := spec.Manifest{
|
man := spec.Manifest{
|
||||||
FormatVersion: 1,
|
FormatVersion: 1,
|
||||||
CreatedAt: time.Now(),
|
CreatedAt: time.Now(),
|
||||||
CreatedBy: "docker-migrate",
|
CreatedBy: "dockmv",
|
||||||
SourceHost: p.SourceHost,
|
SourceHost: p.SourceHost,
|
||||||
Options: opts,
|
Options: opts,
|
||||||
Items: p.Plan.Items,
|
Items: p.Plan.Items,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Prepared is one container resolved against the user's selection: the spec as
|
// Prepared is one container resolved against the user's selection: the spec as
|
||||||
@@ -189,7 +189,7 @@ func Prepare(
|
|||||||
|
|
||||||
// StagingMountPath is where a read-only destination is mounted inside the
|
// StagingMountPath is where a read-only destination is mounted inside the
|
||||||
// temporary staging container used to seed it.
|
// temporary staging container used to seed it.
|
||||||
const stagingRoot = "/__docker_migrate"
|
const stagingRoot = "/__dockmv"
|
||||||
|
|
||||||
// StagingPaths returns the mount point and the extraction directory used when
|
// StagingPaths returns the mount point and the extraction directory used when
|
||||||
// seeding a read-only mount through a staging container. The volume is mounted
|
// seeding a read-only mount through a staging container. The volume is mounted
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
func sample() *spec.Container {
|
func sample() *spec.Container {
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SSHRunner migrates containers straight from the local daemon to a target
|
// SSHRunner migrates containers straight from the local daemon to a target
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RemoteDocker drives the docker CLI on a target host over SSH. It assumes
|
// RemoteDocker drives the docker CLI on a target host over SSH. It assumes
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotFound is returned for an unknown connection id.
|
// ErrNotFound is returned for an unknown connection id.
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -6,7 +6,7 @@
|
|||||||
<meta name="color-scheme" content="dark light" />
|
<meta name="color-scheme" content="dark light" />
|
||||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
<title>DockMV</title>
|
<title>DockMV</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DJVzxyBi.js"></script>
|
<script type="module" crossorigin src="/assets/index-2w4y0Lpg.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CKzWD9Xt.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-CKzWD9Xt.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Command docker-migrate moves Docker containers, together with their volumes
|
// Command dockmv moves Docker containers, together with their volumes
|
||||||
// and bind mounts, from one host to another.
|
// and bind mounts, from one host to another.
|
||||||
//
|
//
|
||||||
// It runs either as a web application (the default) or as a one-shot inventory
|
// It runs either as a web application (the default) or as a one-shot inventory
|
||||||
@@ -26,9 +26,9 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/api"
|
"github.com/arescom/dockmv/internal/api"
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/webui"
|
"github.com/arescom/dockmv/internal/webui"
|
||||||
)
|
)
|
||||||
|
|
||||||
// version is overridden at build time with -ldflags "-X main.version=...".
|
// version is overridden at build time with -ldflags "-X main.version=...".
|
||||||
@@ -55,7 +55,7 @@ func run(args []string) error {
|
|||||||
case "inspect":
|
case "inspect":
|
||||||
return inspect(args)
|
return inspect(args)
|
||||||
case "version":
|
case "version":
|
||||||
fmt.Printf("docker-migrate %s (%s %s/%s)\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
fmt.Printf("dockmv %s (%s %s/%s)\n", version, runtime.Version(), runtime.GOOS, runtime.GOARCH)
|
||||||
return nil
|
return nil
|
||||||
case "help", "-h", "--help":
|
case "help", "-h", "--help":
|
||||||
usage()
|
usage()
|
||||||
@@ -67,14 +67,14 @@ func run(args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func usage() {
|
func usage() {
|
||||||
fmt.Fprint(os.Stderr, `docker-migrate - move Docker containers and their data between hosts
|
fmt.Fprint(os.Stderr, `dockmv - move Docker containers and their data between hosts
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
docker-migrate [serve] [flags] start the web interface (default)
|
dockmv [serve] [flags] start the web interface (default)
|
||||||
docker-migrate inspect [flags] print the source inventory as JSON
|
dockmv inspect [flags] print the source inventory as JSON
|
||||||
docker-migrate version print the version
|
dockmv version print the version
|
||||||
|
|
||||||
Run "docker-migrate serve -h" for the server flags.
|
Run "dockmv serve -h" for the server flags.
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ func serve(args []string) error {
|
|||||||
dockerHost := fs.String("docker-host", "", "source docker daemon (default: the DOCKER_HOST environment)")
|
dockerHost := fs.String("docker-host", "", "source docker daemon (default: the DOCKER_HOST environment)")
|
||||||
verbose := fs.Bool("v", false, "verbose logging")
|
verbose := fs.Bool("v", false, "verbose logging")
|
||||||
fs.Usage = func() {
|
fs.Usage = func() {
|
||||||
fmt.Fprintln(os.Stderr, "Usage: docker-migrate serve [flags]\n\nFlags:")
|
fmt.Fprintln(os.Stderr, "Usage: dockmv serve [flags]\n\nFlags:")
|
||||||
fs.PrintDefaults()
|
fs.PrintDefaults()
|
||||||
}
|
}
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
@@ -148,7 +148,7 @@ func serve(args []string) error {
|
|||||||
if authToken != "" {
|
if authToken != "" {
|
||||||
url += "/?token=" + authToken
|
url += "/?token=" + authToken
|
||||||
}
|
}
|
||||||
fmt.Fprintf(os.Stderr, "\n docker-migrate %s\n open %s\n data: %s\n\n", version, url, *dataDir)
|
fmt.Fprintf(os.Stderr, "\n dockmv %s\n open %s\n data: %s\n\n", version, url, *dataDir)
|
||||||
|
|
||||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||||
defer stop()
|
defer stop()
|
||||||
@@ -176,7 +176,7 @@ func inspect(args []string) error {
|
|||||||
dockerHost := fs.String("docker-host", "", "docker daemon to read (default: the DOCKER_HOST environment)")
|
dockerHost := fs.String("docker-host", "", "docker daemon to read (default: the DOCKER_HOST environment)")
|
||||||
sizes := fs.Bool("sizes", false, "also measure volume sizes (slower)")
|
sizes := fs.Bool("sizes", false, "also measure volume sizes (slower)")
|
||||||
fs.Usage = func() {
|
fs.Usage = func() {
|
||||||
fmt.Fprintln(os.Stderr, "Usage: docker-migrate inspect [flags]\n\nFlags:")
|
fmt.Fprintln(os.Stderr, "Usage: dockmv inspect [flags]\n\nFlags:")
|
||||||
fs.PrintDefaults()
|
fs.PrintDefaults()
|
||||||
}
|
}
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
@@ -207,15 +207,15 @@ func inspect(args []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// defaultDataDir picks a per-user location, honouring the container-friendly
|
// defaultDataDir picks a per-user location, honouring the container-friendly
|
||||||
// DOCKER_MIGRATE_DATA override.
|
// DOCKMV_DATA override.
|
||||||
func defaultDataDir() string {
|
func defaultDataDir() string {
|
||||||
if v := os.Getenv("DOCKER_MIGRATE_DATA"); v != "" {
|
if v := os.Getenv("DOCKMV_DATA"); v != "" {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
if dir, err := os.UserConfigDir(); err == nil {
|
if dir, err := os.UserConfigDir(); err == nil {
|
||||||
return filepath.Join(dir, "docker-migrate")
|
return filepath.Join(dir, "dockmv")
|
||||||
}
|
}
|
||||||
return ".docker-migrate"
|
return ".dockmv"
|
||||||
}
|
}
|
||||||
|
|
||||||
func randomToken() string {
|
func randomToken() string {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
#requires -Version 5.1
|
#requires -Version 5.1
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Build the docker-migrate web UI and cross-compile release binaries.
|
Build the dockmv web UI and cross-compile release binaries.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
Produces dist/docker-migrate-<os>-<arch>[.exe] for every target, one archive
|
Produces dist/dockmv-<os>-<arch>[.exe] for every target, one archive
|
||||||
per binary (.zip for Windows, .tar.gz elsewhere) and dist/SHA256SUMS.txt.
|
per binary (.zip for Windows, .tar.gz elsewhere) and dist/SHA256SUMS.txt.
|
||||||
|
|
||||||
The PowerShell equivalent of `make release`, so a Windows host without make
|
The PowerShell equivalent of `make release`, so a Windows host without make
|
||||||
@@ -130,11 +130,11 @@ try {
|
|||||||
if (-not $Tag) { $Tag = "dev" }
|
if (-not $Tag) { $Tag = "dev" }
|
||||||
}
|
}
|
||||||
|
|
||||||
$bin = "docker-migrate"
|
$bin = "dockmv"
|
||||||
$distDir = Join-Path $repoRoot "dist"
|
$distDir = Join-Path $repoRoot "dist"
|
||||||
$ldflags = "-s -w -X main.version=$Tag"
|
$ldflags = "-s -w -X main.version=$Tag"
|
||||||
|
|
||||||
Write-Host "docker-migrate release build" -ForegroundColor Cyan
|
Write-Host "dockmv release build" -ForegroundColor Cyan
|
||||||
Write-Host " go : $Go"
|
Write-Host " go : $Go"
|
||||||
Write-Host " tag : $Tag"
|
Write-Host " tag : $Tag"
|
||||||
Write-Host " targets : $($Targets -join ', ')"
|
Write-Host " targets : $($Targets -join ', ')"
|
||||||
@@ -152,13 +152,17 @@ try {
|
|||||||
# run before the compile — not after, and not in parallel with it.
|
# run before the compile — not after, and not in parallel with it.
|
||||||
if (-not $SkipUi) {
|
if (-not $SkipUi) {
|
||||||
Write-Host "Building web UI..." -ForegroundColor Cyan
|
Write-Host "Building web UI..." -ForegroundColor Cyan
|
||||||
if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
|
# npm.cmd, not npm(.ps1): the ps1 shim reparses $MyInvocation.Line as text
|
||||||
|
# when called via `& $Exe @Args`, which mangles splatted args into a bogus
|
||||||
|
# single token and makes npm print usage instead of running the command.
|
||||||
|
$npmCmd = (Get-Command npm.cmd -ErrorAction SilentlyContinue).Source
|
||||||
|
if (-not $npmCmd) {
|
||||||
throw "npm not found — install Node 22+, or pass -SkipUi to reuse the committed internal/webui/dist."
|
throw "npm not found — install Node 22+, or pass -SkipUi to reuse the committed internal/webui/dist."
|
||||||
}
|
}
|
||||||
Push-Location (Join-Path $repoRoot "web")
|
Push-Location (Join-Path $repoRoot "web")
|
||||||
try {
|
try {
|
||||||
Invoke-Checked npm @("ci", "--no-audit", "--no-fund")
|
Invoke-Checked $npmCmd @("ci", "--no-audit", "--no-fund")
|
||||||
Invoke-Checked npm @("run", "build")
|
Invoke-Checked $npmCmd @("run", "build")
|
||||||
}
|
}
|
||||||
finally { Pop-Location }
|
finally { Pop-Location }
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
|
|||||||
+7
-7
@@ -1,7 +1,7 @@
|
|||||||
#requires -Version 5.1
|
#requires -Version 5.1
|
||||||
<#
|
<#
|
||||||
.SYNOPSIS
|
.SYNOPSIS
|
||||||
Build the docker-migrate container image + release binaries; push the image to
|
Build the dockmv container image + release binaries; push the image to
|
||||||
the Gitea registry and attach the binaries to a Gitea release.
|
the Gitea registry and attach the binaries to a Gitea release.
|
||||||
|
|
||||||
.DESCRIPTION
|
.DESCRIPTION
|
||||||
@@ -58,7 +58,7 @@ param(
|
|||||||
[string]$Owner = "kawa",
|
[string]$Owner = "kawa",
|
||||||
|
|
||||||
# Image name.
|
# Image name.
|
||||||
[string]$Image = "docker-migrate",
|
[string]$Image = "dockmv",
|
||||||
|
|
||||||
# Repository name holding the releases. The image and the repo are not named
|
# Repository name holding the releases. The image and the repo are not named
|
||||||
# the same here, so this is separate from -Image.
|
# the same here, so this is separate from -Image.
|
||||||
@@ -242,7 +242,7 @@ function Publish-BinaryRelease {
|
|||||||
Write-Host " creating release $Tag in $RepoPath..." -ForegroundColor DarkGray
|
Write-Host " creating release $Tag in $RepoPath..." -ForegroundColor DarkGray
|
||||||
$release = Invoke-GiteaApi -Method POST -Uri $releasesUri -Token $Token -Body @{
|
$release = Invoke-GiteaApi -Method POST -Uri $releasesUri -Token $Token -Body @{
|
||||||
tag_name = $Tag
|
tag_name = $Tag
|
||||||
name = "docker-migrate $Tag"
|
name = "dockmv $Tag"
|
||||||
body = "Standalone binaries for linux, macOS and Windows. Container image: see the package registry."
|
body = "Standalone binaries for linux, macOS and Windows. Container image: see the package registry."
|
||||||
draft = $false
|
draft = $false
|
||||||
}
|
}
|
||||||
@@ -311,7 +311,7 @@ try {
|
|||||||
$tags = @("$base`:$Tag")
|
$tags = @("$base`:$Tag")
|
||||||
if (-not $NoLatest -and $Tag -ne "latest") { $tags += "$base`:latest" }
|
if (-not $NoLatest -and $Tag -ne "latest") { $tags += "$base`:latest" }
|
||||||
|
|
||||||
Write-Host "docker-migrate publish" -ForegroundColor Cyan
|
Write-Host "dockmv publish" -ForegroundColor Cyan
|
||||||
Write-Host " registry : $Registry"
|
Write-Host " registry : $Registry"
|
||||||
if ($pushImage) {
|
if ($pushImage) {
|
||||||
Write-Host " image : $base"
|
Write-Host " image : $base"
|
||||||
@@ -358,10 +358,10 @@ try {
|
|||||||
|
|
||||||
# Uploading a binary older than the code it claims to be is the one way
|
# Uploading a binary older than the code it claims to be is the one way
|
||||||
# this flag can quietly go wrong, so say so rather than assume.
|
# this flag can quietly go wrong, so say so rather than assume.
|
||||||
$oldest = (Get-ChildItem $distDir -Filter "docker-migrate-$Tag-*" -File |
|
$oldest = (Get-ChildItem $distDir -Filter "dockmv-$Tag-*" -File |
|
||||||
Sort-Object LastWriteTime | Select-Object -First 1)
|
Sort-Object LastWriteTime | Select-Object -First 1)
|
||||||
if (-not $oldest) {
|
if (-not $oldest) {
|
||||||
throw "no archives named docker-migrate-$Tag-* in $distDir — the exe on disk was built under a different tag. Drop -NoBinaryBuild."
|
throw "no archives named dockmv-$Tag-* in $distDir — the exe on disk was built under a different tag. Drop -NoBinaryBuild."
|
||||||
}
|
}
|
||||||
$newer = Get-ChildItem $repoRoot -Recurse -Include *.go, *.ts, *.tsx, *.css, *.html -File |
|
$newer = Get-ChildItem $repoRoot -Recurse -Include *.go, *.ts, *.tsx, *.css, *.html -File |
|
||||||
Where-Object {
|
Where-Object {
|
||||||
@@ -383,7 +383,7 @@ try {
|
|||||||
& (Join-Path $PSScriptRoot "build-release.ps1") -Tag $Tag -Targets $Targets -SkipUi:$SkipUi
|
& (Join-Path $PSScriptRoot "build-release.ps1") -Tag $Tag -Targets $Targets -SkipUi:$SkipUi
|
||||||
}
|
}
|
||||||
|
|
||||||
$artifacts = @(Get-ChildItem $distDir -Filter "docker-migrate-$Tag-*" -File | ForEach-Object FullName)
|
$artifacts = @(Get-ChildItem $distDir -Filter "dockmv-$Tag-*" -File | ForEach-Object FullName)
|
||||||
if (-not $artifacts.Count) { throw "no release archives for $Tag found in $distDir." }
|
if (-not $artifacts.Count) { throw "no release archives for $Tag found in $distDir." }
|
||||||
$sums = Join-Path $distDir "SHA256SUMS.txt"
|
$sums = Join-Path $distDir "SHA256SUMS.txt"
|
||||||
if (Test-Path $sums) { $artifacts += $sums }
|
if (Test-Path $sums) { $artifacts += $sums }
|
||||||
|
|||||||
+4
-4
@@ -20,10 +20,10 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/migrate"
|
"github.com/arescom/dockmv/internal/migrate"
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ package e2e
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// asHostKeyError unwraps err into a *sshx.HostKeyError if it is one.
|
// asHostKeyError unwraps err into a *sshx.HostKeyError if it is one.
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/arescom/docker-migrate/internal/dkr"
|
"github.com/arescom/dockmv/internal/dkr"
|
||||||
"github.com/arescom/docker-migrate/internal/job"
|
"github.com/arescom/dockmv/internal/job"
|
||||||
"github.com/arescom/docker-migrate/internal/migrate"
|
"github.com/arescom/dockmv/internal/migrate"
|
||||||
"github.com/arescom/docker-migrate/internal/spec"
|
"github.com/arescom/dockmv/internal/spec"
|
||||||
"github.com/arescom/docker-migrate/internal/sshx"
|
"github.com/arescom/dockmv/internal/sshx"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/mount"
|
"github.com/docker/docker/api/types/mount"
|
||||||
"github.com/docker/docker/api/types/volume"
|
"github.com/docker/docker/api/types/volume"
|
||||||
|
|||||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "docker-migrate-ui",
|
"name": "dockmv-ui",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "docker-migrate-ui",
|
"name": "dockmv-ui",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "docker-migrate-ui",
|
"name": "dockmv-ui",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
+2
-2
@@ -425,7 +425,7 @@ function ConnectionDialog({
|
|||||||
|
|
||||||
{c.auth === 'agent' && (
|
{c.auth === 'agent' && (
|
||||||
<div className="small muted">
|
<div className="small muted">
|
||||||
Uses the agent at <span className="mono">$SSH_AUTH_SOCK</span> of the process running docker-migrate.
|
Uses the agent at <span className="mono">$SSH_AUTH_SOCK</span> of the process running dockmv.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -452,7 +452,7 @@ function ConnectionDialog({
|
|||||||
</Notice>
|
</Notice>
|
||||||
) : (
|
) : (
|
||||||
<div className="small faint">
|
<div className="small faint">
|
||||||
Credentials stay in memory and are lost when docker-migrate restarts.
|
Credentials stay in memory and are lost when dockmv restarts.
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
/* docker-migrate UI.
|
/* dockmv UI.
|
||||||
An operations tool: dense, monospace-leaning, dark by default. Colour is
|
An operations tool: dense, monospace-leaning, dark by default. Colour is
|
||||||
reserved for state, never for decoration. */
|
reserved for state, never for decoration. */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user