Skip to content

Commit 5109733

Browse files
authored
Merge pull request #596 from ckyrouac/lldb-deploy
hack: Add remote lldb utilities to hack dir
2 parents 540794d + 7ec44f6 commit 5109733

File tree

7 files changed

+195
-0
lines changed

7 files changed

+195
-0
lines changed

HACKING.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,23 @@ with the target container host) is to just run a webserver on the host, e.g.
6666
run `bootc usroverlay` once, and
6767
`curl -L -o /usr/bin/bootc http://10.0.1.2:8080/target/release/bootc && restorecon /usr/bin/bootc`.
6868

69+
### Debugging via lldb
70+
71+
The `hack/lldb` directory contains an example of how to use lldb to debug bootc code.
72+
`hack/lldb/deploy.sh` can be used to build and deploy a bootc VM in libvirt with an lldb-server
73+
running as a systemd service. Depending on your editor, you can then connect to the lldb server
74+
to use an interactive debugger, and set up the editor to build and push the new binary to the VM.
75+
`hack/lldb/dap-example-vim.lua` is an example for neovim.
76+
77+
The VM can be connected to via `ssh test@bootc-lldb` if you have [nss](https://libvirt.org/nss.html)
78+
enabled.
79+
80+
For some bootc install commands, it's simpler to run the lldb-server in a container, e.g.
81+
82+
```bash
83+
sudo podman run --pid=host --network=host --privileged --security-opt label=type:unconfined_t -v /var/lib/containers:/var/lib/containers -v /dev:/dev -v .:/output localhost/bootc-lldb lldb-server platform --listen "*:1234" --server
84+
```
85+
6986
## Running the tests
7087

7188
First, you can run many unit tests with `cargo test`.

hack/lldb/Containerfile

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM quay.io/centos-bootc/centos-bootc-dev:stream9
2+
3+
COPY ./etc/sysctl.conf /etc/sysctl.conf
4+
COPY ./etc/systemd/system/lldb-server.service /etc/systemd/system/lldb-server.service
5+
COPY ./etc/sudoers.d/wheel-nopasswd /etc/sudoers.d
6+
ARG sshpubkey
7+
8+
RUN dnf -y install lldb firewalld vim && \
9+
firewall-offline-cmd --add-port 1025-65535/tcp && \
10+
systemctl enable lldb-server.service && \
11+
12+
# add test user
13+
if test -z "$sshpubkey"; then echo "must provide sshpubkey"; exit 1; fi; \
14+
useradd -G wheel test && \
15+
mkdir -m 0700 -p /home/test/.ssh && \
16+
echo $sshpubkey > /home/test/.ssh/authorized_keys && \
17+
chmod 0600 /home/test/.ssh/authorized_keys && \
18+
chown -R test: /home/test

hack/lldb/dap-example-vim.lua

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
-- This is an example of how to configure the DAP connection in an editor (neovim in this case)
2+
-- It should be relatively straightforward to adapt to a different editor
3+
4+
local dap = require("dap")
5+
local job = require("plenary.job")
6+
7+
-- This is a coroutine that runs the cargo build command and reports progress
8+
local program = function()
9+
return coroutine.create(function(dap_run_co)
10+
local progress = require("fidget.progress")
11+
12+
local cargo_build_fidget = progress.handle.create({
13+
title = "cargo build",
14+
lsp_client = { name = "Debugger" },
15+
percentage = 0,
16+
})
17+
18+
local cargo_build_job = job:new({
19+
command = "cargo",
20+
args = { "build", "--color=never", "--profile=dev" },
21+
cwd = vim.fn.getcwd(),
22+
enable_handlers = true,
23+
on_stderr = vim.schedule_wrap(function(_, output)
24+
cargo_build_fidget:report({
25+
message = output,
26+
percentage = cargo_build_fidget.percentage + 0.3,
27+
})
28+
end),
29+
on_exit = function(_, return_val)
30+
vim.schedule(function()
31+
if return_val ~= 0 then
32+
cargo_build_fidget:report({
33+
message = "Error during cargo build",
34+
percentage = 100,
35+
})
36+
else
37+
cargo_build_fidget:finish()
38+
coroutine.resume(dap_run_co, vim.fn.getcwd() .. "/target/debug/bootc")
39+
end
40+
end)
41+
end,
42+
})
43+
44+
cargo_build_job:start()
45+
end)
46+
end
47+
48+
dap.adapters = {
49+
lldb = {
50+
executable = {
51+
args = {
52+
"--liblldb",
53+
"~/.local/share/nvim/mason/packages/codelldb/extension/lldb/lib/liblldb.so",
54+
"--port",
55+
"${port}",
56+
},
57+
command = "~/.local/share/nvim/mason/packages/codelldb/extension/adapter/codelldb",
58+
},
59+
host = "127.0.0.1",
60+
port = "${port}",
61+
type = "server",
62+
},
63+
}
64+
65+
-- rust config that runs cargo build before opening dap ui and starting Debugger
66+
-- shows cargo build status as fidget progress
67+
-- the newly built bootc binary is copied to the VM and run in the lldb-server
68+
dap.configurations.rust = {
69+
{
70+
args = { "status" },
71+
cwd = "/",
72+
name = "[remote] status",
73+
program = program,
74+
request = "launch",
75+
console = "integratedTerminal",
76+
stopOnEntry = false,
77+
type = "lldb",
78+
initCommands = {
79+
"platform select remote-linux",
80+
"platform connect connect://bootc-lldb:1234", -- connect to the lldb-server running in the VM
81+
"file target/debug/bootc",
82+
},
83+
},
84+
{
85+
args = { "upgrade" },
86+
cwd = "/",
87+
name = "[remote] upgrade",
88+
program = program,
89+
request = "launch",
90+
console = "integratedTerminal",
91+
stopOnEntry = false,
92+
type = "lldb",
93+
initCommands = {
94+
"platform select remote-linux",
95+
"platform connect connect://bootc-lldb:1234",
96+
"file target/debug/bootc",
97+
},
98+
},
99+
100+
-- The install command can connect to a container instead of a VM.
101+
-- The following command is an example of how to run a container and start a lldb-server:
102+
-- sudo podman run --pid=host --network=host --privileged --security-opt label=type:unconfined_t -v /var/lib/containers:/var/lib/containers -v /dev:/dev -v .:/output localhost/bootc-lldb lldb-server platform --listen "*:1234" --server
103+
{
104+
args = { "install", "to-disk", "--generic-image", "--via-loopback", "--skip-fetch-check", "~/.cache/bootc-dev/disks/test.raw" },
105+
cwd = "/",
106+
env = {
107+
["RUST_LOG"] = "debug",
108+
["BOOTC_DIRECT_IO"] = "on",
109+
},
110+
name = "[remote] install to-disk",
111+
program = program,
112+
request = "launch",
113+
console = "integratedTerminal",
114+
stopOnEntry = false,
115+
type = "lldb",
116+
initCommands = {
117+
"platform select remote-linux",
118+
"platform connect connect://127.0.0.1:1234", -- connect to the lldb-server running in the container
119+
"file target/debug/bootc",
120+
},
121+
},
122+
}

hack/lldb/deploy.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
# connect to the VM using https://libvirt.org/nss.html
4+
5+
set -e
6+
7+
# build the container image
8+
sudo podman build --build-arg "sshpubkey=$(cat ~/.ssh/id_rsa.pub)" -f Containerfile -t localhost/bootc-lldb .
9+
10+
# build the disk image
11+
mkdir -p ~/.cache/bootc-dev/disks
12+
rm -f ~/.cache/bootc-dev/disks/lldb.raw
13+
truncate -s 10G ~/.cache/bootc-dev/disks/lldb.raw
14+
sudo podman run --pid=host --network=host --privileged --security-opt label=type:unconfined_t -v /var/lib/containers:/var/lib/containers -v ~/.cache/bootc-dev/disks:/output -v /dev:/dev localhost/bootc-lldb bootc install to-disk --via-loopback --generic-image --skip-fetch-check /output/lldb.raw
15+
16+
# create a new VM in libvirt
17+
set +e
18+
virsh -c qemu:///system destroy bootc-lldb
19+
virsh -c qemu:///system undefine --nvram bootc-lldb
20+
set -e
21+
sudo virt-install --name bootc-lldb --cpu host --vcpus 8 --memory 8192 --import --disk ~/.cache/bootc-dev/disks/lldb.raw --os-variant rhel9-unknown
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Enable passwordless sudo for the wheel group
2+
%wheel ALL=(ALL) NOPASSWD: ALL

hack/lldb/etc/sysctl.conf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
net.ipv6.conf.all.disable_ipv6 = 1
2+
net.ipv6.conf.default.disable_ipv6 = 1
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[Unit]
2+
Description=LLDB Server
3+
After=network.target
4+
5+
[Service]
6+
Type=simple
7+
User=root
8+
WorkingDirectory=/root
9+
ExecStart=lldb-server platform --listen "*:1234" --server --min-gdbserver-port 31200 --max-gdbserver-port 31202
10+
Restart=on-failure
11+
12+
[Install]
13+
WantedBy=multi-user.target

0 commit comments

Comments
 (0)