Skip to content

Commit

Permalink
Add option to pull a new image
Browse files Browse the repository at this point in the history
We can now pull new images, not just pull existing ones.

Closes #17

Signed-off-by: Joe Block <jpb@unixorn.net>
  • Loading branch information
unixorn committed Oct 3, 2021
1 parent 4f6735d commit 7927625
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Makefile
@@ -1,4 +1,4 @@
i: lint install
i: format install
install: format
cp lima-plugin ~/Library/Application\ Support/xbar/plugins/lima-plugin.10s

Expand Down
7 changes: 6 additions & 1 deletion README.md
Expand Up @@ -22,14 +22,19 @@

## Description

This plugin is compatible with [xbar](https://xbarapp.com/) and [SwiftBar](https://github.com/swiftbar/SwiftBar), and provides a menubar app that creates a Lima menubar option with submenus for each Lima VM on your machine. For each VM, you can:

- start/stop the VM
- stop, start or remove stopped containers
- pull or remove images from the VM

### Screen shots

![Screen shot of xbar menu with container submenu for a running vm](https://raw.githubusercontent.com/unixorn/unixorn.github.io/master/images/lima-xbar/containers-submenu.png)

![Screen shot of xbar menu with image submenu for a running vm](https://raw.githubusercontent.com/unixorn/unixorn.github.io/master/images/lima-xbar/images-submenu.png)


This plugin is compatible with [xbar](https://xbarapp.com/) and [SwiftBar](https://github.com/swiftbar/SwiftBar), and provides a menubar app that creates submenus for each Lima VM on your machine. For each VM, you can start/stop the VM, stop (and start or remove stopped containers) containers, and pull or remove images from the VM.

## Installation

Expand Down
73 changes: 63 additions & 10 deletions lima-plugin
Expand Up @@ -34,7 +34,7 @@ RUNNING_VM_COLOR = "#29cc00"
# Stopped VM color (default red)
STOPPED_VM_COLOR = "#ff0033"

VERSION = "1.1.1"
VERSION = "1.2.0"


def logSetup(level: str = "INFO"):
Expand Down Expand Up @@ -87,6 +87,7 @@ def parseCLI():
parser.add_argument(
"--image-action", choices=["pull", "rm"], help="Action to perform on image"
)
parser.add_argument("--pull-new-image", action="store_true")
parser.add_argument(
"--vm-action",
choices=["start", "stop"],
Expand Down Expand Up @@ -121,12 +122,35 @@ def displayNotification(title: str, message: str):
runCommand(command=["osascript", "-e", alertCommand])


def inputDialog(user_prompt: str, icon: str = "note"):
"""
Uses osascript to present a dialog with a prompt and returns the user's answer.
:param str prompt:
:param str icon: note,
:return str:
"""
valid_icons = ["caution", "note", "stop"]
if icon.lower() not in valid_icons:
icon = "note"

applescript = f"""set dialogText to text returned of (display dialog "{user_prompt}" default answer "")
return dialogText
"""

answer = runCommand(command=["osascript", "-e", applescript]).strip()
logging.debug(f"Asked {user_prompt} , got answer: {answer}")
return answer


def runCommand(command: list, env=dict(os.environ)):
"""
Run a command and decode the json output
Run a command and return the decoded output
:param list command:
:return dict:
:return str:
"""
return subprocess.run(command, env=env, stdout=subprocess.PIPE).stdout.decode(
"utf-8"
Expand Down Expand Up @@ -243,7 +267,7 @@ def listVMs():
env["PATH"] = newpath

vmRaw = subprocess.run(
["/usr/local/bin/limactl", "list", "--json"], env=env, stdout=subprocess.PIPE
["limactl", "list", "--json"], env=env, stdout=subprocess.PIPE
).stdout.decode("utf-8")

for vm in vmRaw.splitlines():
Expand Down Expand Up @@ -346,6 +370,26 @@ def vmOps(action: str, vm: str = "default"):
displayNotification(title="Task completed", message=" ".join(command))


def pullNewImage(vm: str = "default"):
"""
Pulls a new image.
Args:
vm (str, optional): Which VM to pull the new image into. Defaults to 'default'.
"""
env = prep_environment_for_lima(vm=vm)
image = inputDialog(user_prompt=f"What image should we pull into VM {vm}?")
if image != "":
pull_command = ["lima", "nerdctl", "image", "pull", image]
displayNotification(
title=f"Pulling image {image}", message=" ".join(pull_command)
)
runCommand(command=pull_command, env=env)
displayNotification(title=f"Pulling image {image}", message="Completed")
else:
displayAlert(title="Error!", message="No image specified")


# Actual Xbar-compatible output


Expand Down Expand Up @@ -434,6 +478,9 @@ def vmImageSubMenu(vm: str = "default"):
logging.debug("images: %s", images)

print("-- Images")
print(
f'---- pull new image| bash="{plugin_f}" param1=--vm param2={vm} param3=--pull-new-image terminal=false refresh=true'
)
for image in images:
print("---- %s" % image)
print(
Expand Down Expand Up @@ -484,30 +531,36 @@ def main():
"""
Main program driver
"""
logSetup(level="DEBUG")

logging.debug("plugin path: %s" % __file__)

cli = parseCLI()
logging.warning("VERSON: %s", VERSION)
logSetup(level=cli.log_level)

logging.debug("plugin path: %s" % __file__)
logging.debug("VERSON: %s", VERSION)

logging.debug("cli: %s" % cli)

logging.warning("argv[0] %s" % sys.argv[0])
logging.info("argv[0] %s" % sys.argv[0])

xbarMenu()

if cli.container_action:
logging.info("container action: %s", cli.container_action)
containerOps(vm=cli.vm, action=cli.container_action, container=cli.target)
sys.exit()

if cli.image_action:
logging.info("image action: %s", cli.image_action)
imageOps(action=cli.image_action, image=cli.target, vm=cli.vm)
sys.exit()

if cli.vm_action:
logging.info("vm action: %s", cli.vm_action)
vmOps(action=cli.vm_action, vm=cli.vm)
sys.exit()

xbarMenu()
if cli.pull_new_image:
pullNewImage(vm=cli.vm)


if __name__ == "__main__":
Expand Down

0 comments on commit 7927625

Please sign in to comment.