summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Ashfield <bruce.ashfield@gmail.com>2025-12-08 14:23:46 +0000
committerBruce Ashfield <bruce.ashfield@gmail.com>2025-12-08 20:57:44 -0500
commit2385a741401386d129a0cd4dc4c332d3d54af4b3 (patch)
treeffbc0539e22a0ac230580715480d9759df4fb24e
parent4d63f769924095a8aa85bbe21faeeed904ed36ef (diff)
downloadmeta-virtualization-2385a741401386d129a0cd4dc4c332d3d54af4b3.tar.gz
docs: add QUICKSTART for go-mod-vcs
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
-rw-r--r--scripts/QUICKSTART-oe-go-mod-vcs.md408
1 files changed, 408 insertions, 0 deletions
diff --git a/scripts/QUICKSTART-oe-go-mod-vcs.md b/scripts/QUICKSTART-oe-go-mod-vcs.md
new file mode 100644
index 00000000..40db7885
--- /dev/null
+++ b/scripts/QUICKSTART-oe-go-mod-vcs.md
@@ -0,0 +1,408 @@
1# Quickstart: Go Module VCS Build System for Yocto/BitBake
2
3This guide covers how to create and maintain Go recipes using the `go-mod-vcs` system, which provides reproducible, offline Go builds by fetching dependencies directly from their git repositories.
4
5## Overview
6
7The `go-mod-vcs` system replaces vendor directories with a build-time module cache constructed from git repositories. This provides:
8
9- **Reproducible builds** - Every module comes from a verified git commit
10- **Offline builds** - After `do_fetch`, no network access is required
11- **Auditable dependencies** - Every dependency is traceable to a specific git commit
12- **Smaller recipes** - No need to maintain large vendor directories in source trees
13
14### How It Works
15
16```
17┌─────────────────────────────────────────────────────────────────────┐
18│ Your Recipe │
19│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │
20│ │ myapp_git.bb │ │ go-mod-git.inc │ │ go-mod-cache.inc │ │
21│ │ (your code) │ │ (git fetches) │ │ (module metadata) │ │
22│ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │
23└───────────────────────────────┬─────────────────────────────────────┘
24
25 ┌───────────────────────┼───────────────────────┐
26 │ │ │
27 ▼ ▼ ▼
28 ┌─────────┐ ┌─────────────┐ ┌───────────────┐
29 │do_fetch │ │do_create_ │ │ do_compile │
30 │ │──────────▶│module_cache │────────▶│ │
31 │(git) │ │(build cache)│ │(go build) │
32 └─────────┘ └─────────────┘ └───────────────┘
33```
34
351. **do_fetch** - BitBake fetches all git repositories listed in `go-mod-git.inc`
362. **do_create_module_cache** - The `go-mod-vcs` class builds a Go module cache from git checkouts
373. **do_compile** - Go builds offline using the pre-populated module cache
38
39---
40
41## Converting an Existing Recipe
42
43### Step 1: Add Discovery Configuration
44
45Add these lines to your recipe (before `inherit go`):
46
47```bitbake
48# go-mod-discovery configuration
49GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/..." # Your build target
50GO_MOD_DISCOVERY_GIT_REPO = "https://github.com/org/repo.git"
51GO_MOD_DISCOVERY_GIT_REF = "${SRCREV}"
52
53inherit go-mod-discovery
54```
55
56### Step 2: Include the Generated Files
57
58Add includes after your `SRC_URI`:
59
60```bitbake
61SRC_URI = "git://github.com/org/repo;branch=main;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX}"
62
63include go-mod-git.inc
64include go-mod-cache.inc
65```
66
67### Step 3: Create Placeholder Files
68
69Create empty placeholder files (they'll be generated):
70
71```bash
72cd recipes-containers/myapp/
73touch go-mod-git.inc go-mod-cache.inc
74```
75
76### Step 4: Run Discovery
77
78```bash
79bitbake myapp -c discover_and_generate
80```
81
82This will:
831. Build your project with network access to discover dependencies
842. Extract module metadata from the Go module cache
853. Generate `go-mod-git.inc` and `go-mod-cache.inc` files
86
87### Step 5: Update do_compile()
88
89Ensure your `do_compile()` doesn't set conflicting environment variables. The `go-mod-vcs.bbclass` automatically sets:
90
91- `GOMODCACHE` - Points to the built module cache
92- `GOPROXY=off` - Enforces offline build
93- `GOSUMDB=off` - Disables checksum database
94- `GOTOOLCHAIN=local` - Uses the native Go toolchain
95
96A minimal `do_compile()`:
97
98```bitbake
99do_compile() {
100 cd ${S}/src/import
101
102 export GOPATH="${S}/src/import/.gopath:${STAGING_DIR_TARGET}/${prefix}/local/go"
103 export CGO_ENABLED="1"
104
105 ${GO} build -trimpath ./cmd/...
106}
107```
108
109### Step 6: Build and Test
110
111```bash
112bitbake myapp
113```
114
115---
116
117## Creating a New Recipe
118
119### Minimal Recipe Template
120
121```bitbake
122SUMMARY = "My Go Application"
123HOMEPAGE = "https://github.com/org/myapp"
124
125SRCREV = "abc123def456..."
126SRC_URI = "git://github.com/org/myapp;branch=main;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX}"
127
128include go-mod-git.inc
129include go-mod-cache.inc
130
131LICENSE = "Apache-2.0"
132LIC_FILES_CHKSUM = "file://src/import/LICENSE;md5=..."
133
134GO_IMPORT = "import"
135PV = "v1.0.0+git"
136
137# go-mod-discovery configuration
138GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/..."
139GO_MOD_DISCOVERY_GIT_REPO = "https://github.com/org/myapp.git"
140GO_MOD_DISCOVERY_GIT_REF = "${SRCREV}"
141
142inherit go goarch
143inherit go-mod-discovery
144
145do_compile() {
146 cd ${S}/src/import
147
148 export GOPATH="${S}/src/import/.gopath:${STAGING_DIR_TARGET}/${prefix}/local/go"
149 export CGO_ENABLED="1"
150
151 ${GO} build -trimpath -o ${B}/myapp ./cmd/myapp
152}
153
154do_install() {
155 install -d ${D}${bindir}
156 install -m 755 ${B}/myapp ${D}${bindir}/
157}
158```
159
160### Generate Dependencies
161
162```bash
163# Create placeholder files
164touch go-mod-git.inc go-mod-cache.inc
165
166# Run discovery
167bitbake myapp -c discover_and_generate
168
169# Build
170bitbake myapp
171```
172
173---
174
175## Updating a Recipe to a New Version
176
177### Quick Update (Same Repository)
178
1791. **Update the SRCREV** in your recipe:
180 ```bitbake
181 SRCREV = "new_commit_hash_here"
182 ```
183
1842. **Re-run discovery**:
185 ```bash
186 bitbake myapp -c discover_and_generate
187 ```
188
1893. **Build**:
190 ```bash
191 bitbake myapp
192 ```
193
194### Full Workflow Example
195
196```bash
197# 1. Find the new commit/tag
198git ls-remote https://github.com/org/myapp refs/tags/v2.0.0
199
200# 2. Update SRCREV in recipe
201# SRCREV = "abc123..."
202
203# 3. Clean old discovery cache (optional, recommended for major updates)
204bitbake myapp -c clean_discovery
205
206# 4. Run discovery and generation
207bitbake myapp -c discover_and_generate
208
209# 5. Review generated files
210git diff recipes-containers/myapp/go-mod-*.inc
211
212# 6. Build and test
213bitbake myapp
214
215# 7. Commit changes
216git add recipes-containers/myapp/
217git commit -m "myapp: update to v2.0.0"
218```
219
220---
221
222## Discovery Tasks Reference
223
224| Task | Purpose | Network? |
225|------|---------|----------|
226| `discover_modules` | Build project and download modules from proxy | Yes |
227| `extract_modules` | Extract metadata from cache to JSON | No |
228| `generate_modules` | Generate .inc files from metadata | No |
229| `discover_and_generate` | All three steps in sequence | Yes |
230| `show_upgrade_commands` | Print command lines without running | No |
231| `clean_discovery` | Remove the discovery cache | No |
232
233### Step-by-Step vs All-in-One
234
235**All-in-one** (recommended for most cases):
236```bash
237bitbake myapp -c discover_and_generate
238```
239
240**Step-by-step** (useful for debugging):
241```bash
242bitbake myapp -c discover_modules # Download modules
243bitbake myapp -c extract_modules # Extract to JSON
244bitbake myapp -c generate_modules # Generate .inc files
245```
246
247---
248
249## Configuration Variables
250
251| Variable | Default | Description |
252|----------|---------|-------------|
253| `GO_MOD_DISCOVERY_BUILD_TARGET` | *(required)* | Go build target (e.g., `./cmd/...`) |
254| `GO_MOD_DISCOVERY_GIT_REPO` | *(required for generate)* | Git repository URL |
255| `GO_MOD_DISCOVERY_GIT_REF` | `${SRCREV}` | Git commit/tag |
256| `GO_MOD_DISCOVERY_SRCDIR` | `${S}/src/import` | Directory containing go.mod |
257| `GO_MOD_DISCOVERY_BUILD_TAGS` | `${TAGS}` | Go build tags |
258| `GO_MOD_DISCOVERY_RECIPEDIR` | `${FILE_DIRNAME}` | Output directory for .inc files |
259
260---
261
262## Troubleshooting
263
264### "module lookup disabled by GOPROXY=off"
265
266This error during `do_compile` means a module is missing from the cache.
267
268**Fix:**
269```bash
270# Re-run discovery to find missing modules
271bitbake myapp -c discover_and_generate
272bitbake myapp
273```
274
275### Discovery Cache Location
276
277The discovery cache persists in `${TOPDIR}/go-mod-discovery/${PN}/${PV}/` and survives `bitbake -c cleanall`. To fully reset:
278
279```bash
280bitbake myapp -c clean_discovery
281bitbake myapp -c discover_and_generate
282```
283
284### Viewing Generated Commands
285
286To see what commands would be run without executing them:
287
288```bash
289bitbake myapp -c show_upgrade_commands
290```
291
292### Build Fails After SRCREV Update
293
294If changing SRCREV causes sstate errors:
295
296```bash
297# Clean sstate for the recipe
298bitbake myapp -c cleansstate
299
300# Re-run discovery
301bitbake myapp -c discover_and_generate
302
303# Build
304bitbake myapp
305```
306
307### Multiple Source Repositories
308
309For recipes with multiple git sources, use named SRCREVs:
310
311```bitbake
312SRCREV_myapp = "abc123..."
313SRCREV_plugins = "def456..."
314SRCREV_FORMAT = "myapp_plugins"
315
316SRC_URI = "\
317 git://github.com/org/myapp;name=myapp;branch=main;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX} \
318 git://github.com/org/plugins;name=plugins;branch=main;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX}/plugins \
319"
320
321GO_MOD_DISCOVERY_GIT_REF = "${SRCREV_myapp}"
322```
323
324---
325
326## Example Recipes
327
328### Simple Recipe (rootlesskit)
329
330```bitbake
331SRCREV_rootless = "8059d35092db167ec53cae95fb6aa37fc577060c"
332SRCREV_FORMAT = "rootless"
333
334SRC_URI = "git://github.com/rootless-containers/rootlesskit;name=rootless;branch=master;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX}"
335
336include go-mod-git.inc
337include go-mod-cache.inc
338
339GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/..."
340GO_MOD_DISCOVERY_GIT_REPO = "https://github.com/rootless-containers/rootlesskit.git"
341GO_MOD_DISCOVERY_GIT_REF = "${SRCREV_rootless}"
342
343inherit go goarch go-mod-discovery
344```
345
346### Complex Recipe (k3s with build tags)
347
348```bitbake
349TAGS = "static_build netcgo osusergo providerless"
350
351GO_MOD_DISCOVERY_BUILD_TARGET = "./cmd/server/main.go"
352GO_MOD_DISCOVERY_GIT_REPO = "https://github.com/rancher/k3s.git"
353GO_MOD_DISCOVERY_GIT_REF = "${SRCREV_k3s}"
354
355inherit go goarch go-mod-discovery
356```
357
358---
359
360## Files Generated
361
362### go-mod-git.inc
363
364Contains `SRC_URI` entries for each module's git repository:
365
366```bitbake
367SRC_URI += "git://github.com/spf13/cobra;protocol=https;nobranch=1;rev=e94f6d0...;name=git_41456771_1;destsuffix=vcs_cache/2d91d6bc..."
368```
369
370### go-mod-cache.inc
371
372Contains module metadata and inherits the build class:
373
374```bitbake
375inherit go-mod-vcs
376
377GO_MODULE_CACHE_DATA = '[{"module":"github.com/spf13/cobra","version":"v1.8.1","vcs_hash":"2d91d6bc...","timestamp":"2024-06-01T10:31:11Z","subdir":""},...]'
378```
379
380---
381
382## Advanced: Manual Script Invocation
383
384For cases where BitBake isn't available or you need more control:
385
386```bash
387# Direct generation from git (no BitBake needed)
388python3 ./meta-virtualization/scripts/oe-go-mod-fetcher.py \
389 --git-repo https://github.com/org/myapp.git \
390 --git-ref abc123... \
391 --recipedir ./meta-virtualization/recipes-containers/myapp/
392
393# Using existing discovery cache
394python3 ./meta-virtualization/scripts/oe-go-mod-fetcher.py \
395 --discovered-modules ${TOPDIR}/go-mod-discovery/myapp/v1.0.0/modules.json \
396 --git-repo https://github.com/org/myapp.git \
397 --git-ref abc123... \
398 --recipedir ./meta-virtualization/recipes-containers/myapp/
399```
400
401---
402
403## Getting Help
404
405- **Show available commands**: `bitbake myapp -c show_upgrade_commands`
406- **Architecture details**: See `scripts/ARCHITECTURE.md`
407- **Report issues**: Check the generated files and error messages from discovery
408