Skip to content

Commit

Permalink
Makefile: support for golang debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
schuellerf committed Apr 23, 2024
1 parent 1e5b924 commit 51a1d88
Show file tree
Hide file tree
Showing 163 changed files with 13,327 additions and 3,748 deletions.
32 changes: 28 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,33 @@ WORKER_SRC_DEPS := $(SRC_DEPS)
COMPOSER_SRC_DEPS := $(SRC_DEPS)

GOMODARGS ?= -modfile=go.local.mod
# gcflags "-N -l" for golang to allow debugging
GCFLAGS ?= -gcflags=all=-N -gcflags=all=-l

CONTAINER_DEPS_COMPOSER := ./containers/osbuild-composer/entrypoint.py
CONTAINER_DEPS_WORKER := ./distribution/osbuild-worker-entrypoint.sh

USE_BTRFS ?= yes


# source where the other repos are locally
# has to end with a trailing slash
SRC_DEPS_EXTERNAL_CHECKOUT_DIR ?= ../

COMMON_SRC_DEPS_NAMES := osbuild
COMMON_SRC_DEPS_ORIGIN := $(addprefix $(SRC_DEPS_EXTERNAL_CHECKOUT_DIR),$(COMMON_SRC_DEPS_NAMES))

OSBUILD_CONTAINER_INDICATOR := $(addprefix $(SRC_DEPS_EXTERNAL_CHECKOUT_DIR),container_built.info)

CONTAINER_EXECUTABLE ?= docker
MAKE_SUB_CALL := make CONTAINER_EXECUTABLE="$(CONTAINER_EXECUTABLE)"

$(COMMON_SRC_DEPS_ORIGIN):
@for DIR in $@; do if ! [ -d $$DIR ]; then echo "Please checkout $$DIR so it is available at $$DIR"; exit 1; fi; done

$(OSBUILD_CONTAINER_INDICATOR):
$(MAKE_SUB_CALL) -C $(SRC_DEPS_EXTERNAL_CHECKOUT_DIR)osbuild container

go.local.mod go.local.sum: $(SRC_DEPS_EXTERNAL_DIRS) go.mod $(SRC_DEPS_EXTERNAL) $(WORKER_SRC_DEPS) $(COMPOSER_SRC_DEPS) Makefile
cp go.mod go.local.mod
cp go.sum go.local.sum
Expand All @@ -329,13 +353,13 @@ go.local.mod go.local.sum: $(SRC_DEPS_EXTERNAL_DIRS) go.mod $(SRC_DEPS_EXTERNAL)
env GOPROXY=$(GOPROXY) go mod tidy $(GOMODARGS)
env GOPROXY=$(GOPROXY) go mod vendor $(GOMODARGS)

container_worker_built.info: go.local.mod $(WORKER_SRC_DEPS) $(DOCKERFILE_WORKER)
$(CONTAINER_EXECUTABLE) build -t $(DOCKER_IMAGE_WORKER) -f $(DOCKERFILE_WORKER) --build-arg GOMODARGS=$(GOMODARGS) --build-arg USE_BTRFS=$(USE_BTRFS) .
container_worker_built.info: go.local.mod $(WORKER_SRC_DEPS) $(DOCKERFILE_WORKER) $(CONTAINER_DEPS_WORKER) $(OSBUILD_CONTAINER_INDICATOR)
$(CONTAINER_EXECUTABLE) build -t $(DOCKER_IMAGE_WORKER) -f $(DOCKERFILE_WORKER) --build-arg GOMODARGS="$(GOMODARGS)" --build-arg GCFLAGS="$(GCFLAGS)" --build-arg USE_BTRFS=$(USE_BTRFS) .
echo "Worker last built on" > $@
date >> $@

container_composer_built.info: go.local.mod $(COMPOSER_SRC_DEPS) $(DOCKERFILE_COMPOSER)
$(CONTAINER_EXECUTABLE) build -t $(DOCKER_IMAGE_COMPOSER) -f $(DOCKERFILE_COMPOSER) --build-arg GOMODARGS=$(GOMODARGS) .
container_composer_built.info: go.local.mod $(COMPOSER_SRC_DEPS) $(DOCKERFILE_COMPOSER) $(CONTAINER_DEPS_COMPOSER) $(OSBUILD_CONTAINER_INDICATOR)
$(CONTAINER_EXECUTABLE) build -t $(DOCKER_IMAGE_COMPOSER) -f $(DOCKERFILE_COMPOSER) --build-arg GOMODARGS="$(GOMODARGS)" --build-arg GCFLAGS="$(GCFLAGS)" .
echo "Composer last built on" > $@
date >> $@

Expand Down
152 changes: 82 additions & 70 deletions containers/osbuild-composer/entrypoint-onprem.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import socket
import subprocess
import sys
import time


class Cli(contextlib.AbstractContextManager):
Expand All @@ -34,6 +35,14 @@ def _parse_args(self):
prog="container/osbuild-composer",
)

self._parser.add_argument(
"--shutdown-wait-period",
type=int,
default=0,
dest="shutdown_wait_period",
help="Wait period in seconds before terminating child processes",
)

# --[no-]composer-api
self._parser.add_argument(
"--composer-api",
Expand All @@ -47,20 +56,46 @@ def _parse_args(self):
dest="composer_api",
help="Disable the composer-API",
)
self._parser.add_argument(
"--prometheus",
action="store_true",
dest="prometheus",
help="Enable prometheus listener",
)
self._parser.add_argument(
"--no-prometheus",
action="store_false",
dest="prometheus",
help="Disable prometheus listener",
)
self._parser.add_argument(
"--composer-api-port",
type=int,
default=8080,
dest="composer_api_port",
help="Port which the composer-API listens on",
)
self._parser.add_argument(
"--prometheus-port",
type=int,
default=8008,
dest="prometheus_port",
help="Port which prometheus listens on",
)
self._parser.add_argument(
"--composer-api-bind-address",
type=str,
default="::",
dest="composer_api_bind_address",
help="Bind the composer API to the specified address",
)
self._parser.add_argument(
"--prometheus-bind-address",
type=str,
default="::",
dest="prometheus_bind_address",
help="Bind the prometheus listener to the specified address",
)

# --[no-]local-worker-api
self._parser.add_argument(
Expand Down Expand Up @@ -118,34 +153,13 @@ def _parse_args(self):
help="Disable the weldr-API",
)

# --[no-]dnf-json
self._parser.add_argument(
"--dnf-json",
action="store_true",
dest="dnf_json",
help="Enable dnf-json",
)
self._parser.add_argument(
"--no-dnf-json",
action="store_false",
dest="dnf_json",
help="Disable dnf-json",
)
self._parser.add_argument(
"--dnf-json-port",
type=int,
default=0,
dest="dnf_json_port",
help="Specify the port dnf-json should listen on",
)

self._parser.set_defaults(
builtin_worker=False,
composer_api=False,
prometheus=False,
local_worker_api=False,
remote_worker_api=False,
weldr_api=False,
dnf_json=False,
)

return self._parser.parse_args(self._argv[1:])
Expand Down Expand Up @@ -212,6 +226,21 @@ def _prepare_sockets(self):
assert(sock.fileno() == index)
index += 1

# osbuild-composer-prometheus.socket
if self.args.prometheus:
print("Create prometheus socket on port {}".format(self.args.prometheus_port), file=sys.stderr)
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
self._exitstack.enter_context(contextlib.closing(sock))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
sock.bind((self.args.prometheus_bind_address, self.args.prometheus_port))
sock.listen()
sockets.append(sock)
names.append("osbuild-composer-prometheus.socket")

assert(sock.fileno() == index)
index += 1

# osbuild-local-worker.socket
if self.args.local_worker_api:
print("Create local-worker-api socket", file=sys.stderr)
Expand Down Expand Up @@ -295,51 +324,19 @@ def _spawn_composer(sockets):
preexec_fn=preexec_setenv,
)

def _spawn_dnf_json(self):
cmd = [
"/usr/libexec/osbuild-depsolve-dnf",
]

if self.args.dnf_json_port:
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
self._exitstack.enter_context(contextlib.closing(sock))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
sock.bind(("::", self.args.dnf_json_port))
sock.listen()
else:
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self._exitstack.enter_context(contextlib.closing(sock))
os.makedirs("/run/osbuild-dnf-json/", exist_ok=True)
sock.bind("/run/osbuild-dnf-json/api.sock")
sock.listen()

dnfenv = os.environ.copy()
dnfenv["LISTEN_FDS"] = "1"
dnfenv["LISTEN_FD"] = str(sock.fileno())

return subprocess.Popen(
cmd,
cwd="/usr/libexec/osbuild-composer",
stdin=subprocess.DEVNULL,
stderr=subprocess.STDOUT,
env=dnfenv,
pass_fds=[sock.fileno()]
)

def run(self):
"""Program Runtime"""

proc_composer = None
proc_worker = None
proc_dnf_json = None
res = 0
sockets = self._prepare_sockets()

def handler(signum, frame):
if self.args.shutdown_wait_period:
time.sleep(self.args.shutdown_wait_period)
proc_composer.terminate()
proc_worker.terminate()
proc_dnf_json.terminate()

signal.signal(signal.SIGTERM, handler)

Expand All @@ -348,15 +345,37 @@ def handler(signum, frame):
liveness.touch()

try:
if self.args.builtin_worker:
should_launch_composer = any([self.args.weldr_api, self.args.composer_api, self.args.local_worker_api, self.args.remote_worker_api])
if self.args.builtin_worker or not should_launch_composer:
if not should_launch_composer:
print(f"NOTE: launching worker only - no API for composer enabled")
proc_worker = self._spawn_worker()

if self.args.dnf_json:
proc_dnf_json = self._spawn_dnf_json()

if any([self.args.weldr_api, self.args.composer_api, self.args.local_worker_api, self.args.remote_worker_api]):
if should_launch_composer:
proc_composer = self._spawn_composer(sockets)

debug_port = os.environ.get('GODEBUG_PORT')
debugger = None

if debug_port:
# only debug one - either composer or worker if there is no composer
child_pid = proc_composer.pid if proc_composer else proc_worker.pid
debug_target_name = "image-builder-composer" if proc_composer else "image-builder-worker"

debugger_cmd = [
"/usr/bin/dlv",
"attach",
"--headless=true",
"--api-version", "2",
"--listen", f":{debug_port}",
str(child_pid),
"/usr/libexec/osbuild-composer/osbuild-composer"
]

print(f"NOTE: you HAVE to attach the debugger NOW otherwise { debug_target_name } "
f"will not continue running", file=sys.stderr)
debugger = subprocess.Popen(debugger_cmd)

if proc_composer:
res = proc_composer.wait()

Expand All @@ -365,10 +384,8 @@ def handler(signum, frame):
proc_worker.terminate()
proc_worker.wait()

if proc_dnf_json:
if proc_composer:
proc_dnf_json.terminate()
proc_dnf_json.wait()
if debugger:
debugger.wait()

except KeyboardInterrupt:
if proc_composer:
Expand All @@ -377,14 +394,9 @@ def handler(signum, frame):
if proc_worker:
proc_worker.terminate()
proc_worker.wait()
if proc_dnf_json:
proc_dnf_json.terminate()
proc_dnf_json.wait()
except:
if proc_worker:
proc_worker.kill()
if proc_dnf_json:
proc_dnf_json.kill()
if proc_composer:
proc_composer.kill()
raise
Expand Down
Loading

0 comments on commit 51a1d88

Please sign in to comment.