diff --git a/internal/containerd/network.go b/internal/containerd/network.go index 7dc5ab7c..c895dbe4 100644 --- a/internal/containerd/network.go +++ b/internal/containerd/network.go @@ -61,6 +61,16 @@ func SetupNetwork(ctx context.Context, task client.Task, containerID string) err return err } _, err = cni.Setup(ctx, containerID, netnsPath) + if err == nil { + return nil + } + if !isDuplicateAllocationError(err) { + return err + } + if rmErr := cni.Remove(ctx, containerID, netnsPath); rmErr != nil { + return rmErr + } + _, err = cni.Setup(ctx, containerID, netnsPath) return err } @@ -84,9 +94,25 @@ func setupNetworkWithCLI(ctx context.Context, containerID string, pid uint32) er cmd.Stderr = &stderr if err := cmd.Run(); err != nil { if stderr.Len() > 0 { - return fmt.Errorf("cni cli failed: %s", strings.TrimSpace(stderr.String())) + cniErr := fmt.Errorf("cni cli failed: %s", strings.TrimSpace(stderr.String())) + if !isDuplicateAllocationError(cniErr) { + return cniErr + } + } else if !isDuplicateAllocationError(err) { + return err + } + if rmErr := removeNetworkWithCLI(ctx, containerID, pid); rmErr != nil { + return rmErr + } + cmd = exec.CommandContext(ctx, "limactl", args...) + stderr.Reset() + cmd.Stderr = &stderr + if err := cmd.Run(); err != nil { + if stderr.Len() > 0 { + return fmt.Errorf("cni cli failed: %s", strings.TrimSpace(stderr.String())) + } + return err } - return err } return nil } @@ -162,3 +188,10 @@ func removeNetworkWithCLI(ctx context.Context, containerID string, pid uint32) e } return nil } + +func isDuplicateAllocationError(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), "duplicate allocation") +} diff --git a/scripts/lima-up.sh b/scripts/lima-up.sh index 2aa6ce34..8829d8e7 100644 --- a/scripts/lima-up.sh +++ b/scripts/lima-up.sh @@ -5,7 +5,52 @@ if [ "$(uname -s)" != "Darwin" ]; then exit 0 fi +host_yaml="$HOME/.lima/default/lima.yaml" +if [ -f "$host_yaml" ]; then + if ! awk ' + BEGIN {in=0; entries=0} + /^portForwards:/ {in=1; next} + in && /^[^ ]/ {in=0} + in && /^ - / {entries=1; exit} + END {if (entries) exit 0; else exit 1} + ' "$host_yaml"; then + tmp="${host_yaml}.tmp" + awk ' + BEGIN {found=0; inserted=0} + /^portForwards: *\[/ { + found=1 + print "portForwards:" + if (!inserted) { + print " - guestSocket: \"/run/containerd/containerd.sock\"" + print " hostSocket: \"{{.Dir}}/sock/containerd/containerd.sock\"" + inserted=1 + } + next + } + /^portForwards:/ { + found=1 + print + if (!inserted) { + print " - guestSocket: \"/run/containerd/containerd.sock\"" + print " hostSocket: \"{{.Dir}}/sock/containerd/containerd.sock\"" + inserted=1 + } + next + } + {print} + END { + if (!found) { + print "portForwards:" + print " - guestSocket: \"/run/containerd/containerd.sock\"" + print " hostSocket: \"{{.Dir}}/sock/containerd/containerd.sock\"" + } + } + ' "$host_yaml" > "$tmp" && mv "$tmp" "$host_yaml" + fi +fi + limactl start default +limactl shell default -- sudo -n chmod 666 /run/containerd/containerd.sock if ! limactl shell default -- sh -lc 'command -v memoh-cli >/dev/null 2>&1'; then vm_arch=$(limactl shell default -- uname -m)