Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,69 @@ test-e2e: kernel/$(ARCH)/vmlinuz melange generate # This is invoked by a separat
MELANGE=$(TOP_D)/melange \
./run-tests

#######################
# Script Export Tests
#######################

.PHONY: test-script-export
test-script-export: kernel/$(ARCH)/vmlinuz melange ## Build and test script export functionality
@echo "Building script export test package..."
QEMU_KERNEL_IMAGE=$(TOP_D)/kernel/$(ARCH)/vmlinuz \
QEMU_KERNEL_MODULES=$(TOP_D)/kernel/$(ARCH)/modules/ \
$(TOP_D)/melange build \
--runner=qemu \
--pipeline-dir ./e2e-tests/script-export-pipelines/ \
--out-dir ./e2e-tests/output/ \
--cache-dir /tmp/script-export-cache \
./e2e-tests/script-export-test.yaml
@echo "Running script export validation tests..."
QEMU_KERNEL_IMAGE=$(TOP_D)/kernel/$(ARCH)/vmlinuz \
QEMU_KERNEL_MODULES=$(TOP_D)/kernel/$(ARCH)/modules/ \
$(TOP_D)/melange test \
--runner=qemu \
--repository-append ./e2e-tests/output/ \
--repository-append https://packages.wolfi.dev/os \
--keyring-append https://packages.wolfi.dev/os/wolfi-signing.rsa.pub \
--ignore-signatures \
--pipeline-dirs ./e2e-tests/script-export-pipelines/ \
./e2e-tests/script-export-test.yaml

.PHONY: test-script-export-debug
test-script-export-debug: kernel/$(ARCH)/vmlinuz melange ## Build script export test in debug mode with script saving
@echo "Building script export test package in debug mode..."
QEMU_KERNEL_IMAGE=$(TOP_D)/kernel/$(ARCH)/vmlinuz \
QEMU_KERNEL_MODULES=$(TOP_D)/kernel/$(ARCH)/modules/ \
$(TOP_D)/melange build \
--runner=qemu \
--arch=$(ARCH) \
--debug \
--interactive \
--save-scripts \
--pipeline-dir ./e2e-tests/script-export-pipelines/ \
--out-dir ./e2e-tests/output/ \
--cache-dir /tmp/script-export-cache \
./e2e-tests/script-export-test.yaml
@echo "Running script export validation tests in debug mode..."
QEMU_KERNEL_IMAGE=$(TOP_D)/kernel/$(ARCH)/vmlinuz \
QEMU_KERNEL_MODULES=$(TOP_D)/kernel/$(ARCH)/modules/ \
$(TOP_D)/melange test \
--runner=qemu \
--arch=$(ARCH) \
--debug \
--interactive \
--save-scripts \
--repository-append ./e2e-tests/output/ \
--repository-append https://packages.wolfi.dev/os \
--keyring-append https://packages.wolfi.dev/os/wolfi-signing.rsa.pub \
--ignore-signatures \
--pipeline-dirs ./e2e-tests/script-export-pipelines/ \
./e2e-tests/script-export-test.yaml

.PHONY: clean-script-export-test
clean-script-export-test: ## Clean script export test artifacts
rm -rf ./e2e-tests/output/
rm -rf /tmp/script-export-cache

.PHONY: clean
clean: ## Clean the workspace
rm -rf melange
Expand Down
120 changes: 120 additions & 0 deletions docs/DEBUGGING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Debugging Melange Builds

## Readable Log Output

Melange uses structured logging by default, which can be difficult to read during interactive development. The structured output makes it hard to copy/paste commands for manual execution and can cause ANSI rendering artifacts in terminals.

### Using GCP Logging for Readable Output

A practical workaround is to use the `--gcplog` flag combined with `jq` to extract readable messages:

```bash
# Basic readable output
melange build --gcplog config.yaml 2>&1 | jq -r '.message'

# With Makefiles using MELANGE_EXTRA_ARGS
MELANGE_EXTRA_ARGS="--gcplog" make package/mypackage 2>&1 | jq -r '.message'
MELANGE_EXTRA_ARGS="--gcplog" make debug/mypackage 2>&1 | jq -r '.message'

# Filter for specific message types
melange build --gcplog config.yaml 2>&1 | jq -r 'select(.level == "info") | .message'

# Extract commands being executed
melange build --gcplog config.yaml 2>&1 | jq -r 'select(.msg | contains("running")) | .message'
```

> **Note**: This is a temporary workaround. There are plans to improve interactive logging in the future by circumventing slog for better developer experience.

### Benefits

- **Copy-pasteable commands**: Extract the exact shell commands being executed
- **Cleaner QEMU output**: More readable than structured logging artifacts
- **No ANSI artifacts**: Avoids terminal rendering issues with charmlog
- **Filterable**: Use `jq` to focus on specific log levels or message types
- **Makefile compatible**: Works with existing Makefile workflows via `MELANGE_EXTRA_ARGS`

### Limitations

- **No color output**: ANSI colors from compilation are stripped (expected for GCP logging)
- **Requires jq**: You need `jq` installed for filtering
- **JSON overhead**: More verbose raw output before filtering
- **Temporary solution**: This workaround will be superseded by native plain-text logging

### Example Output

Instead of structured log artifacts, you get clean output like:

```
Writing Makefile for ack
Writing MYMETA.yml and MYMETA.json
+ exit 0
+ '[' -d /home/build ]
+ cd /home/build
+ exit 1
Step failed: task exited with code 1
/bin/sh -c set -ex
[ -d '/home/build' ] || mkdir -p '/home/build'
cd '/home/build'
exit 1
```

### Advanced Filtering

For more complex debugging scenarios:

```bash
# Show timestamps with messages
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r '"\(.time) [\(.level)] \(.message)"'

# Extract only error messages
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r 'select(.level == "error") | .message'

# Show pipeline steps only
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r 'select(.msg | contains("running step")) | .message'

# Extract both message and any command fields
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r '.message + (if .command then "\n" + .command else "" end)'

# Show QEMU-specific output
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r 'select(.message | contains("qemu:")) | .message'
```

### Debugging Failed Steps

When a pipeline step fails, you can extract the failing command for manual execution:

```bash
# Capture the failing command
MELANGE_EXTRA_ARGS="--gcplog" make debug/package 2>&1 | jq -r 'select(.msg == "Step failed") | .message'

# This will show both the error and the exact command that failed, making it easy to:
# 1. Copy the command for manual testing
# 2. Modify the command to debug issues
# 3. Re-run parts of the build manually
```

### Interactive Debugging

For interactive debugging sessions, you can use:

```bash
# Get readable output while building
MELANGE_EXTRA_ARGS="--gcplog --debug-runner --interactive" make debug/package 2>&1 | jq -r '.message'
```

## Future Improvements

The structured logging issues are recognized pain points for interactive development. Future improvements may include:

- Native plain-text logging option to avoid JSON overhead
- Better command formatting for copy-paste workflows
- Preserved ANSI color output for compilation logs
- Enhanced debugging modes with script extraction

This `--gcplog` + `jq` approach provides a practical workaround until these native improvements are available.

## Other Debugging Tips

- Use `--debug` flag to enable verbose pipeline output
- Use `--debug-runner` to keep build environment after failures
- Use `--interactive` to attach to failed builds for manual debugging
Loading
Loading