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

Introduce gvltctl local-run command #59

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
Open

Conversation

aleasims
Copy link
Collaborator

@aleasims aleasims commented Feb 26, 2025

This PR implements gvltctl local-run command. This command is used to locally run VM generated by gvltctl build.

This tool is basically a new version of shim-executor for Firestarter. It runs VM according to Gevulot-compatible VM specification.

Features

  • Execute VM locally just like it will be executed on the Firestarter node
  • Handle input/output files - with local and remote sources
  • Control resources for the VM: CPU, memory, GPU
  • Reuse the same task.yaml file for local and on-chain execution
  • Capture stdout/stderr during VM execution

Design&usage notes

  • This command is designed to work with both: CLI arguments and task specification from task.yaml file. If task.yaml is provided, CLI arguments will overwrite or complete definitions from file.

    Note: some of the fields from task.yaml are always ignored because they make no sense in local execution:

    • spec.resources.gpus - use --gpu argument to pass certain PCI deviced
    • spec.resources.time - currently there is no timeout for local execution
    • spec.outputContexts.retentionPeriod - makes no sense here
  • --input/--output arguments are designed to provide input/output contexts in a more convenient way. Values passed to them are not the same as specified in task.yaml. Task file is expected to always have a proper URI. Example: --input file.txt:file.txt is equivalent to this in task.yaml:

    source: file:///path/to/file.txt
    target: /mnt/gevulot/input/file.txt
  • Output of the command looks a bit similar to task status, which is used on-chain:

    $ gvltctl local-run --format prettyjson disk.img
    {
      "execution_time": 1,
      "message": "VM program exited successfully",
      "output_contexts": [
        "output/output.txt"
      ],
      "stderr": "output/stderr",
      "stdout": "output/stdout"
    }
    
  • To run gvltctl local-run you will need qemu-system-x64_64 available in PATH.

  • You can use remote inputs and VM images, if they are specified in task.yaml:

    spec:
      image: https://storage.googleapis.com/my-assets/vm.img # This works
      inputContexts:
        - source: https://storage.googleapis.com/my-assets/input.txt # This also works
          target: /mnt/gevulot/input/input.txt

    They will be downloaded before execution. This makes re-using task.yaml easier. However note that no caching is implemented at the moment: each file will be re-downloaded and removed at the end of execution.

Examples

CLI only:

gvltctl local-run disk.img \
    --smp 1 \
    --mem 512 \
    --store-stdout \
    --input inputs/input.txt:input.txt \
    --output output.txt

The same with task.yaml:

# task.yaml
kind: Task
version: v0
metadata:
  name: ""
  description: ""
  tags: []
  labels: []
spec:
  image: file:///home/user/disk.img
  command: ["sh"]
  args: ["/main.sh"]
  env: []
  resources:
    cpus: 1
    gpus: 0
    memory: 512
    time: 0
  inputContexts:
    - source: file:///home/user/inputs/input.txt
      target: /mnt/gevulot/input/input.txt
  outputContexts:
    - source: /mnt/gevulot/output/output.txt
      retentionPeriod: -1
  storeStdout: true
  storeStderr: true
gvltctl local-run --file task.yaml

Usage

$ gvltctl local-run --help
Run VM locally

Usage: gvltctl local-run [OPTIONS] [FILE]

Arguments:
  [FILE]
          VM image to run

Options:
      --qemu-path <QEMU_PATH>
          Path to QEMU executable.
          
          If not specified, it will be auto-detected.

      --qemu-arg <ARGS>
          Additional QEMU arguments

  -f, --file <FILE>
          Task file. Only task specification is taken into account.
          
          Options passed directly through CLI will overwrite options in file.

  -s, --smp <NUM>
          Number of CPU cores to allocate to VM. If no task file provided, defaults to 1

  -m, --mem <MEM>
          Memory in MBs. If no task file provided, defaults to 512

  -g, --gpu <GPU>
          PCI device path to GPU device

  -e, --env <KEY=VALUE>
          Environment variables to set for main program. Appends to provided in task file.
          
          Example: --env KEY=VALUE

      --command <COMMAND>
          Command to execute in VM (e.g. /bin/uptime)

      --args <ARGS>
          Arguments for command

  -i, --input <SOURCE:TARGET>
          Input file passed to VM.
          
          SOURCE is path to a local file and TARGET is a path inside VM where this file will be put.
          
          If TARGET is an absolute path, it must start with prefix /mnt/gevulot/input. If it is relative, it will be treated as relative to /mnt/gevulot/input direcotry.
          
          Examples:
          
          --input file.txt:file.txt
          
          --input file.txt:/mnt/gevulot/input/file.txt

  -o, --output <PATH>
          Ouput file in VM to store.
          
          If PATH is an absolute path, it must start with prefix /mnt/gevulot/output. If it is relative, it will be treated as relative to /mnt/gevulot/output direcotry.
          
          Examples:
          
          --output file.txt
          
          --output /mnt/gevulot/output/file.txt

      --stdout
          Print stdout of VM during execution

  -F, --format <FORMAT>
          Sets the output format
          
          [env: GEVULOT_FORMAT=]
          [default: yaml]
          [possible values: yaml, json, prettyjson, toml]

      --stderr
          Print stderr of VM during execution

      --store-stdout
          Store stdout of VM into output file

      --store-stderr
          Store stderr of VM into output file

      --output-dir <DIR>
          Directory to store output files if some
          
          [default: output]

  -h, --help
          Print help (see a summary with '-h')

@aleasims aleasims added the enhancement New feature or request label Feb 26, 2025
@aleasims aleasims self-assigned this Feb 26, 2025
This subcommand runs VM built with `gvltctl build` locally.
Only basic features implementation now.
Use `gvltctl local-run` for VM test run.
@aleasims aleasims force-pushed the feature/run-command branch from 0ee7a46 to fdad67d Compare February 27, 2025 23:22
@aleasims aleasims marked this pull request as ready for review February 28, 2025 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant