Skip to content

Commit 25153e0

Browse files
committed
add the initramfs package
The initramfs package contains a map[string][]byte. It includes compressed kernel and initramfs for several kernel and architecture combinations, as well as qemu command line. It is created by go generate. The package uses embed to incorporate those files. They are reasonably small. To see a possible usage, read vm_test.go set up vm_test to direct all output to a pipe Sadly, the original sin of os.Std{in,out,err} requires an os.File, else we could use an in-memory pipe. Use CombinedOutput in vm_test. Signed-off-by: Ronald G Minnich <[email protected]>
1 parent 7c91be2 commit 25153e0

22 files changed

+564
-31
lines changed

go.mod

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,70 @@
11
module github.com/u-root/cpu
22

3-
go 1.23.0
3+
go 1.24
44

55
toolchain go1.24.1
66

77
require (
88
github.com/gliderlabs/ssh v0.3.5
99
github.com/kevinburke/ssh_config v1.2.0
1010
github.com/u-root/u-root v0.11.1-0.20230913033713-004977728a9d
11-
golang.org/x/crypto v0.36.0
12-
golang.org/x/sys v0.31.0
11+
golang.org/x/crypto v0.39.0
12+
golang.org/x/sys v0.33.0
1313
)
1414

1515
require (
16+
github.com/apptainer/container-library-client v1.4.12
1617
github.com/brutella/dnssd v1.2.9
1718
github.com/creack/pty v1.1.18
1819
github.com/go-git/go-billy/v5 v5.5.1-0.20240514075308-8f1b719cb6a2
20+
github.com/google/go-containerregistry v0.20.6
1921
github.com/google/uuid v1.6.0
2022
github.com/hugelgupf/p9 v0.3.0
2123
github.com/mdlayher/vsock v1.2.1
2224
github.com/moby/sys/mountinfo v0.7.1
2325
github.com/shirou/gopsutil v3.21.11+incompatible
2426
github.com/willscott/go-nfs v0.0.0-20240424173852-04b947a7e58a
2527
golang.org/x/exp v0.0.0-20230810033253-352e893a4cad
26-
golang.org/x/term v0.30.0
28+
golang.org/x/term v0.32.0
2729
)
2830

2931
require (
3032
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
33+
github.com/apptainer/sif/v2 v2.21.1 // indirect
34+
github.com/blang/semver/v4 v4.0.0 // indirect
35+
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
3136
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
37+
github.com/docker/cli v28.2.2+incompatible // indirect
38+
github.com/docker/distribution v2.8.3+incompatible // indirect
39+
github.com/docker/docker-credential-helpers v0.9.3 // indirect
3240
github.com/dustin/go-humanize v1.0.1 // indirect
41+
github.com/go-log/log v0.2.0 // indirect
3342
github.com/go-ole/go-ole v1.2.6 // indirect
3443
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
35-
github.com/klauspost/compress v1.16.7 // indirect
44+
github.com/klauspost/compress v1.18.0 // indirect
3645
github.com/klauspost/pgzip v1.2.6 // indirect
3746
github.com/mdlayher/socket v0.4.1 // indirect
3847
github.com/miekg/dns v1.1.55 // indirect
48+
github.com/mitchellh/go-homedir v1.1.0 // indirect
49+
github.com/opencontainers/go-digest v1.0.0 // indirect
50+
github.com/opencontainers/image-spec v1.1.1 // indirect
3951
github.com/pierrec/lz4/v4 v4.1.18 // indirect
52+
github.com/pkg/errors v0.9.1 // indirect
4053
github.com/rasky/go-xdr v0.0.0-20170124162913-1a41d1a06c93 // indirect
54+
github.com/sirupsen/logrus v1.9.3 // indirect
55+
github.com/sylabs/json-resp v0.9.4 // indirect
4156
github.com/tklauser/go-sysconf v0.3.11 // indirect
4257
github.com/tklauser/numcpus v0.6.1 // indirect
4358
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
4459
github.com/ulikunitz/xz v0.5.11 // indirect
60+
github.com/vbatts/tar-split v0.12.1 // indirect
4561
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
4662
github.com/vishvananda/netns v0.0.4 // indirect
4763
github.com/willscott/go-nfs-client v0.0.0-20240104095149-b44639837b00 // indirect
4864
github.com/yusufpapurcu/wmi v1.2.3 // indirect
49-
golang.org/x/mod v0.12.0 // indirect
50-
golang.org/x/net v0.38.0 // indirect
51-
golang.org/x/sync v0.3.0 // indirect
52-
golang.org/x/tools v0.12.0 // indirect
65+
golang.org/x/mod v0.25.0 // indirect
66+
golang.org/x/net v0.41.0 // indirect
67+
golang.org/x/sync v0.15.0 // indirect
68+
golang.org/x/tools v0.34.0 // indirect
5369
google.golang.org/grpc v1.56.3 // indirect
5470
)

go.sum

Lines changed: 66 additions & 22 deletions
Large diffs are not rendered by default.

initramfs/build.go

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
//go:build generate
2+
3+
package main
4+
5+
import (
6+
"archive/tar"
7+
"bytes"
8+
"compress/gzip"
9+
"fmt"
10+
"log"
11+
"os"
12+
"os/exec"
13+
14+
"github.com/google/go-containerregistry/pkg/crane"
15+
"github.com/google/go-containerregistry/pkg/name"
16+
"github.com/google/go-containerregistry/pkg/v1/mutate"
17+
"github.com/u-root/u-root/pkg/cpio"
18+
"github.com/u-root/u-root/pkg/tarutil"
19+
)
20+
21+
type build struct {
22+
os string
23+
arch string
24+
version string
25+
kernel string
26+
container string
27+
env []string
28+
cmd []string
29+
}
30+
31+
var builds = []build{
32+
{
33+
os: "linux",
34+
arch: "amd64",
35+
version: "v1",
36+
kernel: "bzImage",
37+
container: "ghcr.io/hugelgupf/vmtest/kernel-amd64:main",
38+
env: []string{"GOARCH=amd64", "GOAMD64=v1"},
39+
cmd: []string{},
40+
},
41+
{
42+
os: "linux",
43+
arch: "arm64",
44+
version: "v1",
45+
kernel: "Image",
46+
container: "ghcr.io/hugelgupf/vmtest/kernel-arm64:main",
47+
env: []string{"GOARCH=arm64"},
48+
cmd: []string{},
49+
},
50+
{
51+
os: "linux",
52+
arch: "arm",
53+
kernel: "zImage",
54+
container: "ghcr.io/hugelgupf/vmtest/kernel-arm:main",
55+
env: []string{"GOARCH=arm", "GOARM=5"},
56+
cmd: []string{},
57+
},
58+
{
59+
os: "linux",
60+
arch: "riscv64",
61+
kernel: "Image",
62+
container: "ghcr.io/hugelgupf/vmtest/kernel-riscv64:main",
63+
env: []string{"GOARCH=riscv64"},
64+
cmd: []string{},
65+
},
66+
}
67+
68+
func main() {
69+
env := []string{"CGO_ENABLED=0"}
70+
for _, b := range builds {
71+
log.Printf("Build %v", b)
72+
n := fmt.Sprintf("initramfs_%s_%s.cpio", b.os, b.arch)
73+
cmd := []string{"-initcmd=/bbin/cpud", "-defaultsh=", "-o=" + n,
74+
"../cmds/cpud",
75+
"../../u-root/cmds/core/dhclient",
76+
}
77+
c := exec.Command("u-root", cmd...)
78+
c.Stdout, c.Stderr = os.Stdout, os.Stderr
79+
c.Env = append(os.Environ(), append(env, b.env...)...)
80+
if err := c.Run(); err != nil {
81+
log.Fatal(err)
82+
}
83+
f, err := os.ReadFile(n)
84+
if err != nil {
85+
log.Fatal(err)
86+
}
87+
88+
var newcpio bytes.Buffer
89+
rw := cpio.Newc.Writer(&newcpio)
90+
recs := cpio.Newc.Reader(bytes.NewReader(f))
91+
fixed := 0
92+
cpio.ForEachRecord(recs, func(r cpio.Record) error {
93+
switch r.Name {
94+
case "bbin/bb":
95+
fixed++
96+
r.Name = "bbin/cibb"
97+
case "bbin/init", "bbin/dhclient", "bbin/cpud":
98+
fixed++
99+
r.ReaderAt = bytes.NewReader([]byte("cibb"))
100+
r.Info.FileSize = 4
101+
}
102+
if err := rw.WriteRecord(r); err != nil {
103+
return fmt.Errorf("writing record %q failed: %w", r.Name, err)
104+
}
105+
return nil
106+
})
107+
108+
if fixed < 2 {
109+
log.Fatal("Did not fix any entries in %q", n)
110+
}
111+
112+
// because we modify the cpio, and one of the tests makes sure the cpio matches compressed,
113+
// write back the modified cpio.
114+
if err := os.WriteFile(n, newcpio.Bytes(), 0644); err != nil {
115+
log.Fatalf("writing back changed cpio %s:%v", n, err)
116+
}
117+
118+
var out bytes.Buffer
119+
gz := gzip.NewWriter(&out)
120+
if _, err := gz.Write(newcpio.Bytes()); err != nil {
121+
log.Fatal(err)
122+
}
123+
if err := gz.Close(); err != nil {
124+
log.Fatal(err)
125+
}
126+
if err := os.WriteFile(n+".gz", out.Bytes(), 0644); err != nil {
127+
log.Fatal(err)
128+
}
129+
130+
if len(b.container) == 0 {
131+
continue
132+
}
133+
ref, err := name.ParseReference(b.container)
134+
if err != nil {
135+
log.Fatal(err)
136+
}
137+
138+
img, err := crane.Pull(ref.Name())
139+
if err != nil {
140+
log.Fatal(err)
141+
}
142+
143+
r := mutate.Extract(img)
144+
145+
opts := &tarutil.Opts{}
146+
opts.Filters = []tarutil.Filter{tarutil.SafeFilter, func(h *tar.Header) bool {
147+
return h.Name == b.kernel
148+
},
149+
}
150+
151+
if err := tarutil.ExtractDir(r, ".", opts); err != nil {
152+
log.Fatal(err)
153+
}
154+
155+
// tarutil does not let us extract a file with a name into a []byte.Unfortunate.
156+
kname := fmt.Sprintf("kernel_%s_%s", b.os, b.arch)
157+
if err := os.Rename(b.kernel, kname); err != nil {
158+
log.Fatal(err)
159+
}
160+
if f, err = os.ReadFile(kname); err != nil {
161+
log.Fatal(err)
162+
}
163+
var kout bytes.Buffer
164+
gz = gzip.NewWriter(&kout)
165+
if _, err := gz.Write(f); err != nil {
166+
log.Fatal(err)
167+
}
168+
if err := gz.Close(); err != nil {
169+
log.Fatal(err)
170+
}
171+
if err := os.WriteFile(kname+".gz", kout.Bytes(), 0644); err != nil {
172+
log.Fatal(err)
173+
}
174+
175+
}
176+
}

0 commit comments

Comments
 (0)