Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

limactl shell: ask whether to start the instance if not running #2832

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

jandubois
Copy link
Member

@jandubois jandubois commented Nov 3, 2024

This is an edited version of #2763 with a simpler control flow.

It automatically picks the template corresponding to the desired instance name, if it exists. Otherwise it uses default:

$ limactl shell alpine
? Do you want to create and start the instance "alpine" using the "alpine" template now? Yes
? Creating an instance "alpine" Proceed with the current configuration

@afbjorklund
Copy link
Member

Could we add some "start-if-not-running" flag, perhaps? So that scripts could check that, to see that it's up OK.

Then the shell lines could be a limactl oneliner:

if [ "$(limactl ls -q "$LIMA_INSTANCE" 2>/dev/null)" != "$LIMA_INSTANCE" ]; then
  echo "instance \"$LIMA_INSTANCE\" does not exist, run \`limactl create --name=$LIMA_INSTANCE template://docker\` to create a new instance" >&2
  exit 1
elif [ "$(limactl ls -f '{{ .Status }}' "$LIMA_INSTANCE" 2>/dev/null)" != "Running" ]; then
  echo "instance \"$LIMA_INSTANCE\" is not running, run \`limactl start $LIMA_INSTANCE\` to start the existing instance" >&2
  exit 1
fi

To prompt for the create and start, like here.

Currently we are tying into shell (for use by lima), but that won't work for other clients like docker or podman:

DOCKER=$(command -v "$DOCKER" || true)
if [ -n "$DOCKER" ]; then
  DOCKER_HOST=$(limactl list "$LIMA_INSTANCE" --format 'unix://{{.Dir}}/sock/docker.sock')
  export DOCKER_HOST
  exec "$DOCKER" "$@"
else
  export LIMA_INSTANCE
  exec lima docker "$@"
fi

i.e. before running docker or podman (or kubectl, or ...) it needs to make sure that the instance is running

@jandubois
Copy link
Member Author

Could we add some "start-if-not-running" flag, perhaps? So that scripts could check that, to see that it's up OK.

How would this be different from running

$ export LIMA_INSTANCE=docker
$ lima true
? Do you want to create and start the instance "docker" using the "docker" template now? No
FATA[0002] open /Users/jan/.lima/docker/lima.yaml: no such file or directory
$ echo $?
1

@jandubois jandubois marked this pull request as ready for review November 3, 2024 09:29
@jandubois
Copy link
Member Author

I think this PR is now a possible replacement for #2763.

Changes to docker.lima, kubectl.lima, and nerdctl.lima should go into a separate PR.

@AkihiroSuda
Copy link
Member

It automatically picks the template corresponding to the desired instance name, if it exists.

This is inconsistent with limactl create.
Acceptable if they can be consistent

@jandubois
Copy link
Member Author

jandubois commented Nov 3, 2024

This is inconsistent with limactl create.
Acceptable if they can be consistent

Good point! I need to think about this for a while, as there are arguments for both choices.

The main reason I wanted to pick the template to match the instance name for limactl shell was because there is no way to say limactl shell foo --template docker; the only possible template would be default.

On the other hand, I think it is somewhat bad if commands have different semantics based on what files are installed. So limactl shell foo might create a template://foo instance on one machine, but a template://default instance on another.

However, this only happens in interactive use, the user is prompted, and the user can still change the template via the template picker in the next step.

Maybe we need to use a highlight colour for the template name in the message, to make it stand out better:

? Do you want to create and start the instance "docker" using the ${\color{blue}docker}$ template now?

And/or display a warning when the template name doesn't match the instance name?

@AkihiroSuda
Copy link
Member

And/or display a warning when the template name doesn't match the instance name?

Rather it should print a note when the template does match the instance name?

Instance names like "vm0", "vm1", ..., "dev", "tmp", should not print any warning.

@jandubois
Copy link
Member Author

jandubois commented Nov 3, 2024

Could we add some "start-if-not-running" flag, perhaps? So that scripts could check that, to see that it's up OK.

I think using lima true || exit 1 works well:

Patch
--- cmd/docker.lima
+++ cmd/docker.lima
@@ -7,19 +7,14 @@ set -eu
 : "${LIMA_INSTANCE:=docker}"
 : "${DOCKER:=docker}"

-if [ "$(limactl ls -q "$LIMA_INSTANCE" 2>/dev/null)" != "$LIMA_INSTANCE" ]; then
-  echo "instance \"$LIMA_INSTANCE\" does not exist, run \`limactl create --name=$LIMA_INSTANCE template://docker\` to create a new instance" >&2
-  exit 1
-elif [ "$(limactl ls -f '{{ .Status }}' "$LIMA_INSTANCE" 2>/dev/null)" != "Running" ]; then
-  echo "instance \"$LIMA_INSTANCE\" is not running, run \`limactl start $LIMA_INSTANCE\` to start the existing instance" >&2
-  exit 1
-fi
+export LIMA_INSTANCE
+lima true || exit 1
+
 DOCKER=$(command -v "$DOCKER" || true)
 if [ -n "$DOCKER" ]; then
   DOCKER_HOST=$(limactl list "$LIMA_INSTANCE" --format 'unix://{{.Dir}}/sock/docker.sock')
   export DOCKER_HOST
   exec "$DOCKER" "$@"
 else
-  export LIMA_INSTANCE
   exec lima docker "$@"
 fi

If docker is not running at all:

$ docker.lima run hello-world
? Do you want to create and start the instance "docker" using the "docker" template now? Yes
? Creating an instance "docker" Proceed with the current configuration

------
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.
Full log
$ docker.lima run hello-world
? Do you want to create and start the instance "docker" using the "docker" template now? Yes
? Creating an instance "docker" Proceed with the current configuration
INFO[0005] Attempting to download the image              arch=x86_64 digest="sha256:0e25ca6ee9f08ec5d4f9910054b66ae7163c6152e81a3e67689d89bd6e4dfa69" location="https://cloud-images.ubuntu.com/releases/24.04/release-20240821/ubuntu-24.04-server-cloudimg-amd64.img"
INFO[0005] Using cache "/Users/jan/Library/Caches/lima/download/by-url-sha256/b2b185213b60ce48564393cf9eeb3c2ce4e92df4d2ca2edad8657c18d0e3052d/data"
INFO[0005] Run `limactl start docker` to start the instance.
INFO[0005] Using the existing instance "docker"
INFO[0005] Starting the instance "docker" with VM driver "qemu"
INFO[0005] QEMU binary "/usr/local/bin/qemu-system-x86_64" seems properly signed with the "com.apple.security.hypervisor" entitlement
INFO[0005] [hostagent] hostagent socket created at /Users/jan/.lima/docker/ha.sock
INFO[0005] [hostagent] Using system firmware ("/usr/local/share/qemu/edk2-x86_64-code.fd")
INFO[0005] [hostagent] Starting QEMU (hint: to watch the boot progress, see "/Users/jan/.lima/docker/serial*.log")
INFO[0006] SSH Local Port: 64363
INFO[0005] [hostagent] Waiting for the essential requirement 1 of 2: "ssh"
INFO[0024] [hostagent] The essential requirement 1 of 2 is satisfied
INFO[0024] [hostagent] Waiting for the essential requirement 2 of 2: "user session is ready for ssh"
INFO[0024] [hostagent] The essential requirement 2 of 2 is satisfied
INFO[0024] [hostagent] Waiting for the optional requirement 1 of 1: "user probe 1/1"
INFO[0024] [hostagent] Forwarding "/run/user/501/docker.sock" (guest) to "/Users/jan/.lima/docker/sock/docker.sock" (host)
INFO[0024] [hostagent] Forwarding "/run/lima-guestagent.sock" (guest) to "/Users/jan/.lima/docker/ga.sock" (host)
INFO[0024] [hostagent] Guest agent is running
INFO[0024] [hostagent] Not forwarding TCP 127.0.0.53:53
INFO[0024] [hostagent] Not forwarding TCP 127.0.0.54:53
INFO[0024] [hostagent] Not forwarding TCP [::]:22
INFO[0024] [hostagent] Not forwarding UDP 127.0.0.54:53
INFO[0024] [hostagent] Not forwarding UDP 127.0.0.53:53
INFO[0024] [hostagent] Not forwarding UDP 192.168.5.15:68
INFO[0064] [hostagent] Waiting for the optional requirement 1 of 1: "user probe 1/1"
INFO[0073] [hostagent] The optional requirement 1 of 1 is satisfied
INFO[0073] [hostagent] Waiting for the guest agent to be running
INFO[0074] [hostagent] Waiting for the final requirement 1 of 1: "boot scripts must have finished"
INFO[0080] [hostagent] The final requirement 1 of 1 is satisfied
INFO[0081] READY.
INFO[0081] Message from the instance "docker":
To run `docker` on the host (assumes docker-cli is installed), run the following commands:
------
docker context create lima-docker --docker "host=unix:///Users/jan/.lima/docker/sock/docker.sock"
docker context use lima-docker
docker run hello-world
------
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:d211f485f2dd1dee407a80973c8f129f00d54604d2c90732e8e320e5038a0348
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

And if you refuse to create or start the docker instance you get proper errors:

$ docker.lima run hello-world
? Do you want to create and start the instance "docker" using the "docker" template now? No
FATA[0001] open /Users/jan/.lima/docker/lima.yaml: no such file or directory


$ docker.lima run hello-world
? Do you want to start the instance "docker" now? No
FATA[0001] instance "docker" status is not "Running" but "Stopped"

Also does the right thing when STDOUT is not a terminal:

$ docker.lima run hello-world | cat
FATA[0000] instance "docker" does not exist, run `limactl create docker` to create a new instance


$ docker.lima run hello-world | cat
FATA[0000] instance "docker" is stopped, run `limactl start docker` to start the instance

I think this is an argument in favour of selecting a template matching the instance name (when possible) for limactl shell.

@afbjorklund This means for kubectl.lima we would have to pick an instance name if we want to offer the auto-create/start functionality. Personally I would want to use k3s, but I think k8s is probably a more canonical choice.

@jandubois
Copy link
Member Author

Maybe we need to use a highlight colour for the template name in the message, to make it stand out better:

? Do you want to create and start the instance "docker" using the ${\color{blue}docker}$ template now?

I couldn't find a way to colourize substrings in the survey.AskOne prompt.

Rather it should print a note when the template does match the instance name?
Instance names like "vm0", "vm1", ..., "dev", "tmp", should not print any warning.

Ok, sounds reasonable. Should this be a WARN to stand out more?

@AkihiroSuda
Copy link
Member

Should this be a WARN to stand out more?

Maybe looks too scary to some users who want to dismiss all the warnings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants