Skip to content

hlb v0.4.0

Pre-release
Pre-release
Compare
Choose a tag to compare
@hinshun hinshun released this 04 Mar 19:08
1bc8728

Welcome to HLB v0.4! A robust debugger was implemented with breakpoints, forward / reverse execution, and also allowing you to exec into the container at any step. Not only that, its only supported by IDE debuggers via DAP support.

Highlights

Debugger

Access the debugger when running any HLB module by adding --debug to the hlb run command. The debugger halts before program starts, so you can take a look at all the commands supported currently:

❯ hlb run --debug
Type help for a list of commands
(hlb) help
# Running the program
    continue (alias: c) - run until breakpoint or program termination
    next (alias: n) - step over to next source line
    step (alias: s) - single step through program
    stepout - step out of current function
    rev (alias: r) <movement> - reverses execution of program for movement specified
    restart - restart program from the start

# Manipulating breakpoints
    break (alias: b) <symbol | linespec> - sets a breakpoint
    breakpoints (alias: bp) - prints out active breakpoints
    clear <breakpoint-index> - deletes breakpoint
    clearall - deletes all breakpoints

# Viewing program variables and functions
    args - print function arguments
    funcs - print functions in this module

# Viewing the call stack and selecting frames
    backtrace (alias: bt) - prints backtrace at this step

# Filesystem only commands
    pwd - print working directory at this step
    environ - print environment at this step
    network - print network mode at this step
    security - print security mode at this step

# Other commands
    help - prints this help message
    list (alias: ls) - prints source code at this step
    exit (alias: quit) - exits the debugger

Exec at any step of container building

When the debugger is in a filesystem block, the command exec is available allowing you to exec into the container at any step. When a breakpoint is defined in source, continue will halt when it is reached, while supporting all the option::run attached to the statement.

For example, we will debug an alpine image that mounts the openllb/hlb git repo at /in. You can exit the exec back into the debugger repl and continue debugging.

❯ hlb run --debug foo.hlb
Type help for a list of commands
(hlb) continue
#1 resolve image config for docker.io/library/alpine:latest
#1 DONE 0.4s

#2 docker-image://docker.io/library/alpine:latest
#2 CACHED
foo.hlb:3:2:
1 │ fs default() {
2 │ 	image "alpine"
3 │ 	run "echo foo" with option {
  │ 	^^^
4 │ 		breakpoint
5 │ 		mount src "/in"
6 │ 	}
7 │ }
(hlb) exec
Starting process "/bin/sh"
#1 docker-image://docker.io/library/alpine:latest
#1 CACHED

#2 git://github.com/openllb/hlb.git#master
#2 0.452 1bc8728460226ff81fb8562e0b022dc8978ed322	refs/heads/master
#2 0.767 From https://github.com/openllb/hlb
#2 0.767  t [tag update]      master     -> master
#2 0.767  + 6130d0f...1bc8728 master     -> origin/master  (forced update)
#2 DONE 0.8s
/ # cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.15.0
PRETTY_NAME="Alpine Linux v3.15"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://bugs.alpinelinux.org/"
/ # ls /in
LANGSERVER.md  builtin        codegen        examples       hlb.go         mkdocs.hlb     pkg            version.go
LICENSE        checker        diagnostic     go.hlb         language       mkdocs.yml     rpc
README.md      client.go      docs           go.mod         linter         module         scripts
build.hlb      cmd            errdefs        go.sum         local          parser         solver
/ # exit
(hlb) ls
foo.hlb:3:2:
1 │ fs default() {
2 │ 	image "alpine"
3 │ 	run "echo foo" with option {
  │ 	^^^
4 │ 		breakpoint
5 │ 		mount src "/in"
6 │ 	}
7 │ }
(hlb)

DAP

An initial implementation for DAP over stdio has landed. Using vscode-hlb you can debug HLB from Visual Code, or your favorite editor if it supports DAP.

vscode

Module URIs

HLB now supports running modules from URIs, whether it is a local file or from a remote git repository.

❯ hlb run --help
NAME:
   hlb run - compiles and runs a hlb program

USAGE:
   hlb run [command options] <uri>

The following schemes are supported:

  • file:// or empty scheme for local files (same as before)
  • git-https:// git repository over https
  • git+ssh:// git repository over ssh
  • git:// git repository, automatically detecting if ssh is supported based on your SSH agent.

For git based module URIs, an optional branch or commit ref can be provided as a suffix with @<ref> followed by an optional path :/path/to/file.hlb. (e.g. git://github.com/openllb/hlb@master:/build.hlb)

For example, we can run the lint target of this repository remotely like this:

❯ hlb run -t lint git://github.com/openllb/hlb
[+] Building 18.2s (9/9) FINISHED
 => git://github.com/openllb/hlb                                                                                               9.9s
 => resolve image config for docker.io/library/golang:1.17.5-alpine                                                            0.9s
 => docker-image://docker.io/library/golang:1.17.5-alpine                                                                      0.1s
 => => resolve docker.io/library/golang:1.17.5-alpine                                                                          0.1s
 => https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh                                                 0.2s
 => copy / /                                                                                                                   0.0s
 => CACHED /bin/sh -c 'apk add -U git gcc libc-dev'                                                                            0.0s
 => CACHED /bin/sh -c 'sh /golangci/install.sh -b /usr/bin v1.31.0'                                                            0.0s
 => /bin/sh -c 'go get'                                                                                                        2.8s
 => /bin/sh -c '/usr/bin/golangci-lint run'                                                                                    8.4s

Merge, Diff

Thanks to the work of @sipsma, merge and diff are new builtins that allow you to merge and diff filesystems.

Here's an example using both:

fs alpine() {
        image "alpine"
}

fs busybox() {
        image "busybox"
}

fs workspace() {
        busybox
        run "echo this is a test > /root/file1"
        run "dd if=/dev/urandom bs=1024 count=100 of=/var/random"
        run "rm /bin/zcat"
}

fs differences() {
        workspace
        diff busybox
}

fs workspaceRebased() {
        alpine
        merge differences
}

fs default() {
        busybox
        run "ls" with option {
                breakpoint
                mount workspace "/workspace"
                mount differences "/differences"
                mount workspaceRebased "/rebased"
        }
}

Performance

The internals of the HLB compiler is now fully asynchronous, which should improve build performance overall. In particular builds that use a lot of remote sources like docker images, should have their builds speed up significantly.