diff --git a/src/cmd/linuxkit/moby/output.go b/src/cmd/linuxkit/moby/output.go index ec81527b1..d17cf41b6 100644 --- a/src/cmd/linuxkit/moby/output.go +++ b/src/cmd/linuxkit/moby/output.go @@ -16,6 +16,7 @@ import ( var ( outputImages = map[string]string{ + "iso": "linuxkit/mkimage-iso:4c77e9969773bf0ed6b0eb2230a2c94b5fae47ab", "iso-bios": "linuxkit/mkimage-iso-bios:65254243f003cf0ac74c64b0a23b543195ddad8a", "iso-efi": "linuxkit/mkimage-iso-efi:1f5556e56da8e82d52458667ad354b719f314eb2", "raw-bios": "linuxkit/mkimage-raw-bios:2795f6282bdb8582934d5a0c2f1f859d3073336c", @@ -108,6 +109,13 @@ var outFuns = map[string]func(string, io.Reader, int) error{ } return nil }, + "kernel+iso": func(base string, image io.Reader, size int) error { + err := outputKernelISO(outputImages["iso"], base, image) + if err != nil { + return fmt.Errorf("Error writing kernel+iso output: %v", err) + } + return nil + }, "aws": func(base string, image io.Reader, size int) error { filename := base + ".raw" log.Infof(" %s", filename) @@ -498,3 +506,58 @@ func outputKernelSquashFS(image, base string, filesystem io.Reader) error { return dockerRun(buf, output, true, image) } + +func outputKernelISO(image, base string, filesystem io.Reader) error { + log.Debugf("output kernel/iso: %s %s", image, base) + log.Infof(" %s.iso", base) + + tr := tar.NewReader(filesystem) + buf := new(bytes.Buffer) + rootfs := tar.NewWriter(buf) + + for { + var thdr *tar.Header + thdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + return err + } + thdr.Format = tar.FormatPAX + switch { + case thdr.Name == "boot/kernel": + kernel, err := ioutil.ReadAll(tr) + if err != nil { + return err + } + if err := ioutil.WriteFile(base+"-kernel", kernel, os.FileMode(0644)); err != nil { + return err + } + case thdr.Name == "boot/cmdline": + cmdline, err := ioutil.ReadAll(tr) + if err != nil { + return err + } + if err := ioutil.WriteFile(base+"-cmdline", cmdline, os.FileMode(0644)); err != nil { + return err + } + case strings.HasPrefix(thdr.Name, "boot/"): + // skip the rest of boot/ + default: + rootfs.WriteHeader(thdr) + if _, err := io.Copy(rootfs, tr); err != nil { + return err + } + } + } + rootfs.Close() + + output, err := os.Create(base + ".iso") + if err != nil { + return err + } + defer output.Close() + + return dockerRun(buf, output, true, image) +} diff --git a/test/cases/000_build/000_formats/004_aws/test.sh b/test/cases/000_build/000_formats/004_aws/test.sh index d698f3700..aafd9e9a3 100644 --- a/test/cases/000_build/000_formats/004_aws/test.sh +++ b/test/cases/000_build/000_formats/004_aws/test.sh @@ -1,5 +1,5 @@ #!/bin/sh -# SUMMARY: Check that raw output format is generated +# SUMMARY: Check that aws output format is generated # LABELS: amd64 set -e diff --git a/test/cases/000_build/000_formats/008_raw_bios/test.sh b/test/cases/000_build/000_formats/008_raw_bios/test.sh index 264e30cae..3c19dbd51 100644 --- a/test/cases/000_build/000_formats/008_raw_bios/test.sh +++ b/test/cases/000_build/000_formats/008_raw_bios/test.sh @@ -1,5 +1,5 @@ #!/bin/sh -# SUMMARY: Check that raw output format is generated +# SUMMARY: Check that raw-bios output format is generated # LABELS: amd64 set -e diff --git a/test/cases/000_build/000_formats/009_raw_efi/test.sh b/test/cases/000_build/000_formats/009_raw_efi/test.sh index 9eebfbef3..5d35558e2 100644 --- a/test/cases/000_build/000_formats/009_raw_efi/test.sh +++ b/test/cases/000_build/000_formats/009_raw_efi/test.sh @@ -1,5 +1,5 @@ #!/bin/sh -# SUMMARY: Check that raw output format is generated +# SUMMARY: Check that raw-efi output format is generated # LABELS: set -e diff --git a/test/cases/000_build/000_formats/011_kernel+squashfs/test.sh b/test/cases/000_build/000_formats/011_kernel+squashfs/test.sh index 76a2ee210..443e0f0ff 100644 --- a/test/cases/000_build/000_formats/011_kernel+squashfs/test.sh +++ b/test/cases/000_build/000_formats/011_kernel+squashfs/test.sh @@ -1,5 +1,5 @@ #!/bin/sh -# SUMMARY: Check that kernel+initrd output format is generated +# SUMMARY: Check that kernel+squashfs output format is generated # LABELS: set -e diff --git a/test/cases/000_build/000_formats/012_kernel+iso/test.sh b/test/cases/000_build/000_formats/012_kernel+iso/test.sh new file mode 100644 index 000000000..b1008531f --- /dev/null +++ b/test/cases/000_build/000_formats/012_kernel+iso/test.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# SUMMARY: Check that kernel+iso output format is generated +# LABELS: + +set -e + +# Source libraries. Uncomment if needed/defined +#. "${RT_LIB}" +. "${RT_PROJECT_ROOT}/_lib/lib.sh" + +NAME=check + +clean_up() { + rm -f ${NAME}* +} + +trap clean_up EXIT + +linuxkit build -format kernel+iso -name "${NAME}" ../test.yml +[ -f "${NAME}-kernel" ] || exit 1 +[ -f "${NAME}.iso" ] || exit 1 +[ -f "${NAME}-cmdline" ] || exit 1 + +exit 0 diff --git a/tools/mkimage-iso/Dockerfile b/tools/mkimage-iso/Dockerfile new file mode 100644 index 000000000..7241b487e --- /dev/null +++ b/tools/mkimage-iso/Dockerfile @@ -0,0 +1,15 @@ +FROM linuxkit/alpine:daed76b8f1d28cdeeee215a95b9671c682a405dc AS mirror +RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/ +RUN apk add --no-cache --initdb -p /out \ + alpine-baselayout \ + busybox \ + cdrkit \ + libarchive-tools \ + && true +RUN mv /out/etc/apk/repositories.upstream /out/etc/apk/repositories + +FROM scratch +WORKDIR / +COPY --from=mirror /out/ / +COPY . . +ENTRYPOINT [ "/make-iso" ] diff --git a/tools/mkimage-iso/build.yml b/tools/mkimage-iso/build.yml new file mode 100644 index 000000000..0c51e1a94 --- /dev/null +++ b/tools/mkimage-iso/build.yml @@ -0,0 +1,3 @@ +image: mkimage-iso +arches: + - amd64 diff --git a/tools/mkimage-iso/make-iso b/tools/mkimage-iso/make-iso new file mode 100755 index 000000000..875a557d5 --- /dev/null +++ b/tools/mkimage-iso/make-iso @@ -0,0 +1,18 @@ +#!/bin/sh + +set -e + +mkdir -p /tmp/iso +cd /tmp/iso + +# input is a tarball of filesystem on stdin +# output is an iso on stdout + +# extract. BSD tar auto recognises compression, unlike GNU tar +# only if stdin is a tty, if so need files volume mounted... +[ -t 0 ] || bsdtar xzf - + +genisoimage -o ../linuxkit.iso -l -J -R \ + -joliet-long -input-charset utf8 \ + -V LinuxKit . +cat ../linuxkit.iso