[gnome-build-meta/valentindavid/gnome-os-ostree: 23/25] Add OSTree based VM image
- From: Valentin David <valentindavid src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-build-meta/valentindavid/gnome-os-ostree: 23/25] Add OSTree based VM image
- Date: Mon, 6 Jan 2020 15:50:14 +0000 (UTC)
commit 5c0afbe3048f95470ac340068e642cf32fa4fe66
Author: Valentin David <valentin david codethink co uk>
Date: Sun Nov 17 11:48:52 2019 +0100
Add OSTree based VM image
.gitignore | 4 +
elements/vm/deps.bst | 28 +++++++
elements/vm/filesystem.bst | 13 +++
elements/vm/flathub-config.bst | 17 ++++
elements/vm/image.bst | 113 ++++++++++++++++++++++++++
elements/vm/initial-scripts.bst | 7 ++
elements/vm/initramfs.bst | 67 ++++++++++++++++
elements/vm/initramfs/deps.bst | 15 ++++
elements/vm/initramfs/initial-scripts.bst | 7 ++
elements/vm/ostree-config.bst | 50 ++++++++++++
elements/vm/repo-deps.bst | 5 ++
elements/vm/repo.bst | 39 +++++++++
files/vm/flathub-config/add-flathub.preset | 1 +
files/vm/flathub-config/add-flathub.service | 12 +++
files/vm/gnome.gpg | 29 +++++++
files/vm/ostree-config/gnome.conf.in | 4 +
files/vm/ostree-config/ostree.conf | 4 +
plugins/collect_initial_scripts.py | 55 +++++++++++++
plugins/ostree_mirror.py | 120 ++++++++++++++++++++++++++++
project.conf | 20 +++++
utils/build-image.sh | 14 ++++
utils/run-local-repo.sh | 3 +
utils/update-local-repo.sh | 37 +++++++++
utils/update-repo.sh | 108 +++++++++++++++++++++++++
24 files changed, 772 insertions(+)
---
diff --git a/.gitignore b/.gitignore
index add5986a..f78329c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,7 @@ plugins/__pycache__
# Never commit project.refs
project.refs
+
+image/disk.qcow2
+ostree-repo
+ostree-gpg
diff --git a/elements/vm/deps.bst b/elements/vm/deps.bst
new file mode 100644
index 00000000..427a11f1
--- /dev/null
+++ b/elements/vm/deps.bst
@@ -0,0 +1,28 @@
+kind: stack
+
+runtime-depends:
+- freedesktop-sdk.bst:components/util-linux.bst
+- freedesktop-sdk.bst:components/tzdata.bst
+- freedesktop-sdk.bst:components/systemd.bst
+- freedesktop-sdk.bst:components/xorg-server.bst
+- freedesktop-sdk.bst:components/shadow.bst
+- freedesktop-sdk.bst:vm/mesa-default.bst
+
+- core-deps/flatpak.bst
+- vm/initramfs.bst
+- vm/ostree-config.bst
+- core-deps/avahi.bst
+- core-deps/eos-updater.bst
+
+- vm/plymouth-gnome-theme.bst
+- vm/kbd.bst
+
+- freedesktop-sdk.bst:vm/config/pulseaudio.bst
+- freedesktop-sdk.bst:vm/config/sudo.bst
+- freedesktop-sdk.bst:vm/config/journald.bst
+- vm/flathub-config.bst
+
+# And add GNOME core on top !
+- sdk-platform.bst
+- core.bst
+- core/systemd-presets.bst
diff --git a/elements/vm/filesystem.bst b/elements/vm/filesystem.bst
new file mode 100644
index 00000000..da7e9f3f
--- /dev/null
+++ b/elements/vm/filesystem.bst
@@ -0,0 +1,13 @@
+kind: compose
+
+build-depends:
+- vm/deps.bst
+
+# Currently we just take everything and remove the
+# devel stuff (headers and static libraries), and debugging
+# symbols which take a huge amount of space, we could
+# refine this and make it much more selective, though.
+config:
+ exclude:
+ - devel
+ - debug
diff --git a/elements/vm/flathub-config.bst b/elements/vm/flathub-config.bst
new file mode 100644
index 00000000..25d2036b
--- /dev/null
+++ b/elements/vm/flathub-config.bst
@@ -0,0 +1,17 @@
+kind: manual
+
+depends:
+- freedesktop-sdk.bst:bootstrap-import.bst
+
+runtime-depends:
+- core-deps/flatpak.bst
+
+config:
+ install-commands:
+ - |
+ install -Dm644 -t "%{install-root}%{indep-libdir}/systemd/system" add-flathub.service
+ install -Dm644 -t "%{install-root}%{indep-libdir}/systemd/system-preset" add-flathub.preset
+
+sources:
+- kind: local
+ path: files/vm/flathub-config
diff --git a/elements/vm/image.bst b/elements/vm/image.bst
new file mode 100644
index 00000000..6a203d72
--- /dev/null
+++ b/elements/vm/image.bst
@@ -0,0 +1,113 @@
+kind: manual
+
+build-depends:
+- core-deps/ostree.bst
+- vm/qemu-tools.bst
+- freedesktop-sdk.bst:integration/mtab.bst
+- freedesktop-sdk.bst:components/genimage.bst
+
+variables:
+ (?):
+ - arch == "x86_64":
+ linux-root: 4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709
+ - arch == "i686":
+ linux-root: 44479540-F297-41B2-9AF7-D131D5F0458A
+ - arch == "arm":
+ linux-root: 69DAD710-2CE4-4E3C-B16C-21A1D49ABED3
+ - arch == "aarch64":
+ linux-root: B921B045-1DF0-41C3-AF44-4C6F280D3FAE
+
+ sysroot: "%{build-root}/sysroot"
+
+environment:
+ OSTREE_REPO: "%{sysroot}/ostree/repo"
+
+config:
+ build-commands:
+ - mkdir -p "${OSTREE_REPO}"
+ - ostree init --repo="${OSTREE_REPO}" --mode=bare
+
+ - ostree config --group sysroot set bootloader none
+ - ostree pull-local "%{build-root}/source-repo" %{ostree-branch}
+
+ - mkdir -p "%{sysroot}/boot"
+
+ - ostree admin init-fs "%{sysroot}"
+ - ostree admin os-init --sysroot="%{sysroot}" gnome-os
+ - |
+ ostree admin deploy --os="gnome-os" \
+ --sysroot="%{sysroot}" %{ostree-branch} \
+ --karg="rw" --karg="quiet" --karg="splash"
+
+ - |
+ mkdir -p "%{sysroot}/etc/ostree"
+ cp -r "%{sysroot}"/ostree/boot.1/gnome-os/*/*/etc/ostree/remotes.d "%{sysroot}/etc/ostree/remotes.d"
+
+ - |
+ ostree admin set-origin --sysroot="%{sysroot}" \
+ --index=0 \
+ GnomeOS dummy \
+ %{ostree-branch}
+
+ - |
+ cp -r "%{sysroot}"/ostree/boot.1/gnome-os/*/*/boot/EFI/ "%{sysroot}/boot/"
+
+ - |
+ mkdir -p genimage
+
+ - |
+ cat >genimage/genimage.cfg <<EOF
+ image efi.img {
+ vfat {
+ extraargs = "-F32 -n EFI"
+ }
+ mountpoint = "/boot"
+ size = 100M
+ }
+ image root.img {
+ ext4 {
+ label = "root"
+ }
+ size = 16G
+ }
+ image disk.img {
+ hdimage {
+ align = 1M
+ gpt = true
+ }
+ partition efi {
+ image = "efi.img"
+ partition-type-uuid = "U"
+ }
+ partition root {
+ image = "root.img"
+ partition-type-uuid = "%{linux-root}"
+ }
+ }
+ image disk.qcow2 {
+ qemu {
+ }
+ partition image {
+ image = "disk.img"
+ }
+ }
+ EOF
+
+ - |
+ cd genimage
+ genimage --rootpath "%{sysroot}"
+
+ - |
+ install -Dm644 -t "%{install-root}" genimage/images/disk.qcow2
+
+sources:
+- kind: ostree_mirror
+ (?):
+ - repo_mode == 'local':
+ path: ostree-repo
+ gpg: local.gpg
+ - repo_mode == 'nightly':
+ url: https://nightly.gnome.org/
+ gpg: files/vm/gnome.gpg
+ match: 'gnome-os/*'
+ directory: source-repo
diff --git a/elements/vm/initial-scripts.bst b/elements/vm/initial-scripts.bst
new file mode 100644
index 00000000..a811a267
--- /dev/null
+++ b/elements/vm/initial-scripts.bst
@@ -0,0 +1,7 @@
+kind: collect_initial_scripts
+
+build-depends:
+- vm/deps.bst
+
+config:
+ path: /etc/fdsdk/initial_scripts
diff --git a/elements/vm/initramfs.bst b/elements/vm/initramfs.bst
new file mode 100644
index 00000000..8127a743
--- /dev/null
+++ b/elements/vm/initramfs.bst
@@ -0,0 +1,67 @@
+kind: script
+
+build-depends:
+- vm/initramfs/deps.bst
+- vm/initramfs/initial-scripts.bst
+- freedesktop-sdk.bst:vm/prepare-image.bst
+
+variables:
+ uuidnamespace: aea54278-2587-4075-ae67-8688ace4ce3d
+
+config:
+ layout:
+ - element: ''
+ destination: '/tmp'
+ - element: ''
+ destination: '/efi'
+ - element: ''
+ destination: '/var/tmp'
+ - element: vm/initramfs/deps.bst
+ destination: '/'
+ - element: vm/initramfs/initial-scripts.bst
+ destination: '/'
+ - element: vm/prepare-image.bst
+ destination: '/'
+
+ commands:
+ - |
+ prepare-image.sh \
+ --seed "%{uuidnamespace}" \
+ --rootsource /dev/gpt-auto-root \
+ --efisource LABEL=EFI \
+ --efipath /boot \
+ --rootpasswd "root" >/dev/null
+
+ - |
+ mkdir -p "%{install-root}/usr/lib/"
+ cp -r /usr/lib/modules "%{install-root}/usr/lib/"
+
+ - |
+ version="$(ls -1 /lib/modules | head -n1)"
+ mkdir -p "%{install-root}/usr/lib/modules/${version}"
+ dracut -v --fstab \
+ --no-machineid \
+ --kver "${version}" \
+ --add ostree \
+ --add plymouth \
+ --install 'fsck.ext4' \
+ "%{install-root}/usr/lib/modules/${version}/initramfs"
+
+ - |
+ version="$(ls -1 /lib/modules | head -n1)"
+ cp /boot/vmlinuz "%{install-root}/usr/lib/modules/${version}/vmlinuz"
+
+ - dbus-uuidgen >/etc/machine-id
+ - SYSTEMD_RELAX_ESP_CHECKS=1 bootctl --path='/efi' --no-variables install
+ - rm /etc/machine-id
+
+ - |
+ cp -r /efi "%{install-root}/boot"
+
+ - |
+ cat <<EOF >%{install-root}/boot/loader/loader.conf
+ timeout 3
+ editor yes
+ console-mode keep
+ default *
+ EOF
diff --git a/elements/vm/initramfs/deps.bst b/elements/vm/initramfs/deps.bst
new file mode 100644
index 00000000..29872db7
--- /dev/null
+++ b/elements/vm/initramfs/deps.bst
@@ -0,0 +1,15 @@
+kind: stack
+
+runtime-depends:
+- freedesktop-sdk.bst:bootstrap-import.bst
+- freedesktop-sdk.bst:components/util-linux.bst
+- freedesktop-sdk.bst:components/linux.bst
+- freedesktop-sdk.bst:components/systemd.bst
+- freedesktop-sdk.bst:components/dbus.bst
+- freedesktop-sdk.bst:components/dracut.bst
+- freedesktop-sdk.bst:components/os-release.bst
+- freedesktop-sdk.bst:components/shadow.bst
+- freedesktop-sdk.bst:components/tzdata.bst
+- freedesktop-sdk.bst:components/pkg-config.bst
+- core-deps/ostree.bst
+- vm/plymouth-gnome-theme.bst
diff --git a/elements/vm/initramfs/initial-scripts.bst b/elements/vm/initramfs/initial-scripts.bst
new file mode 100644
index 00000000..069d8f3f
--- /dev/null
+++ b/elements/vm/initramfs/initial-scripts.bst
@@ -0,0 +1,7 @@
+kind: collect_initial_scripts
+
+build-depends:
+- vm/initramfs/deps.bst
+
+config:
+ path: /etc/fdsdk/initial_scripts
diff --git a/elements/vm/ostree-config.bst b/elements/vm/ostree-config.bst
new file mode 100644
index 00000000..3cb885c1
--- /dev/null
+++ b/elements/vm/ostree-config.bst
@@ -0,0 +1,50 @@
+kind: manual
+
+build-depends:
+- freedesktop-sdk.bst:bootstrap-import.bst
+- freedesktop-sdk.bst:components/m4.bst
+
+runtime-depends:
+- freedesktop-sdk.bst:components/systemd.bst
+- core-deps/ostree.bst
+
+config:
+ build-commands:
+ - |
+ m4 -DOSTREE_REMOTE_URL="%{ostree-remote-url}" \
+ gnome.conf.in >gnome.conf
+
+ install-commands:
+ - |
+ mkdir %{install-root}/boot
+ mkdir %{install-root}/efi
+ mkdir %{install-root}/etc
+ mkdir %{install-root}/mnt
+ mkdir %{install-root}/run
+ mkdir %{install-root}/opt
+ mkdir %{install-root}/sys
+ mkdir %{install-root}/tmp
+ mkdir %{install-root}/dev
+ mkdir %{install-root}/proc
+
+ - |
+ mkdir -p "%{install-root}/sysroot"
+ ln -s sysroot/ostree "%{install-root}/ostree"
+ ln -s var/home "%{install-root}/home"
+ ln -s var/roothome "%{install-root}/root"
+ ln -s run/media "%{install-root}/media"
+
+ - |
+ install -Dm644 -t "%{install-root}/usr/lib/tmpfiles.d" ostree.conf
+ install -Dm644 *.gpg "%{install-root}/etc/pki/ostree/gnome.gpg"
+ install -Dm644 -t "%{install-root}/etc/ostree/remotes.d" gnome.conf
+
+sources:
+- kind: local
+ path: files/vm/ostree-config
+- kind: local
+ (?):
+ - repo_mode == 'local':
+ path: local.gpg
+ - repo_mode == 'nightly':
+ path: files/vm/gnome.gpg
diff --git a/elements/vm/repo-deps.bst b/elements/vm/repo-deps.bst
new file mode 100644
index 00000000..120ad68c
--- /dev/null
+++ b/elements/vm/repo-deps.bst
@@ -0,0 +1,5 @@
+kind: stack
+
+runtime-depends:
+- core-deps/ostree.bst
+- freedesktop-sdk.bst:vm/prepare-image.bst
diff --git a/elements/vm/repo.bst b/elements/vm/repo.bst
new file mode 100644
index 00000000..90e8bea2
--- /dev/null
+++ b/elements/vm/repo.bst
@@ -0,0 +1,39 @@
+kind: script
+
+build-depends:
+- vm/repo-deps.bst
+- vm/filesystem.bst
+- vm/initial-scripts.bst
+- freedesktop-sdk.bst:vm/prepare-image.bst
+
+variables:
+ uuidnamespace: aea54278-2587-4075-ae67-8688ace4ce3d
+
+environment:
+ OSTREE_REPO: "%{install-root}/ostree/repo"
+
+config:
+ layout:
+ - element: ''
+ destination: /tmp
+ - element: vm/repo-deps.bst
+ destination: /
+ - element: vm/filesystem.bst
+ destination: /sysroot
+ - element: vm/initial-scripts.bst
+ destination: /
+
+ commands:
+ - |
+ prepare-image.sh \
+ --sysroot /sysroot \
+ --seed "%{uuidnamespace}" \
+ --rootsource /dev/gpt-auto-root \
+ --efisource LABEL=EFI \
+ --efipath /boot \
+ --rootpasswd "root" >/dev/null
+
+ - mkdir -p "${OSTREE_REPO}"
+ - ostree init --repo="${OSTREE_REPO}" --mode=archive
+ - mv /sysroot/etc /sysroot/usr/etc
+ - ostree commit --branch=%{ostree-branch} /sysroot
diff --git a/files/vm/flathub-config/add-flathub.preset b/files/vm/flathub-config/add-flathub.preset
new file mode 100644
index 00000000..185c4062
--- /dev/null
+++ b/files/vm/flathub-config/add-flathub.preset
@@ -0,0 +1 @@
+enable add-flathub.service
diff --git a/files/vm/flathub-config/add-flathub.service b/files/vm/flathub-config/add-flathub.service
new file mode 100644
index 00000000..0fa35e0a
--- /dev/null
+++ b/files/vm/flathub-config/add-flathub.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Add flathub
+ConditionFirstBoot=yes
+Wants=network-online.target
+After=network-online.target systemd-resolved.service nss-lookup.target
+
+[Service]
+Type=oneshot
+ExecStart=flatpak remote-add flathub https://flathub.org/repo/flathub.flatpakrepo
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/vm/gnome.gpg b/files/vm/gnome.gpg
new file mode 100644
index 00000000..ecd64cde
--- /dev/null
+++ b/files/vm/gnome.gpg
@@ -0,0 +1,29 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQINBFuhBAsBEADDIU1v3mx7yvJwwbVw11gBm3HYR1kV0EbTI311nDuZ3oSf3zf9
+Rm2gI73C8v5nq6WcTjwkL0tvArf4OxWNFufWKqa6UfODOzwBXeNhkyZEFvvgI0qi
+f6IIbxMSXgntNmH+sD1quXJ7tiGyf2cA1FzQJJVUMRwsb2yGx3XLIZW7JDZgVJvW
+NVDmPg7unuECRXsmEGFusfiejsIwDLyOzXIushFk7APLR5QWyYdI2Ujb077aaMqo
+Ytfv4Iv1Ulgg44dlKqEqdRCbCtlBfirqbi4zi5TNI3dQbyxiPuCBls18Aw9sRq96
+MmpKlyD02Ig8TxzmVcjAJ2nGN/3ptWOva1Osadkh3GGgxWhPV1WEF66Vfnx07wp3
+8081bnpCl0wDLjGumZ0sIAwQ7g5ZdC8Nulx93iOr5uTixYSvcn0djuEbwDC2Qs0U
+yLP2+uT6OcHyT3PjT5zA3nTrMPsgTNPcK/ajrMVe2XUxml/3vZipBdAeJFhtAfAI
+M2mbXw6h63zcjeNBG7ieqlKvbKf4t9uFhzUGC59T/lef5e4GU+OftEDHSirmBeM9
+kext3mSMuzDNdz5G0UgzBoBMfHnWQOgexCvJanYQ9OvJ57O51E6NaTHW0YePS2fl
+p2nRNyGzeZ5352kZxSxaCorKTDuzhrPHtvXGnzp/n9n10gsYZFH7ZSrKrwARAQAB
+tDVHTk9NRSBCdWlsZCBNZXRhIFNpZ25pbmcgS2V5IDxyZWxlYXNlLXRlYW1AZ25v
+bWUub3JnPokCTgQTAQgAOBYhBKE065L4wSlBNu1a1EZc+7lq3wZXBQJboQQLAhsD
+BQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEEZc+7lq3wZX0iQP/i8bw8x7LrKm
++2SxSBh900v+gtM0Ev/I0a6arSnDy+RYrLTOmG3E5sjtUosuOALIWnBQuIY8fgJv
+dw/ezzx71Vg8Ztuhav5OmN3dnV/HYNXHVisGnGQd09duY/WAK1qyyxZlnX8z3C8s
++AZUX15BNPFjJTHGuoQzBxlCtJHZSyw7TlXaHWl7TunB85O30kgAAA52cDjYdEmm
+x9IjPBmdBlpR0WZf7BxW3pnFsRdH1+J7UTbzum5WLgu+QXVnTA2bBY2fTOqlgjLS
+lBQjp/iXRM33H45HJJKAxpNiC4JZTeO68/hmnBIdKF182b/2URfIY4lgBnglffdm
+IH9EoKmThXktwOfjUeivsTO+BTpsHKzQ9HNLFJ5FE8qgAdtN4GhHHGA8wapG774I
+OOPhbGHa88LiMLkCQJmj8JBmag77SHz0jMyRDnEfWj+d3tscfJcU3ePP/Aet+1IK
+cWdcyPrzhgYYbzhZzCsKrTpZRa0XDMfb6hzuRVZdt+fX2xiNWcx5UHvpGa7dHork
+WmRlBUVTO0G6yAUKNRZ5fBk4Jt5Uh/aAXBOf4D4uC5sy3OHLL0oG/oRhT7lPwMTX
+NnblEwZgPFDcqGUYSLUFOKyDHqu04hVrzwKgOE4fUBJv4AKtWiEnmPEvEAANe0kK
+hrMbt8BZCpPMnrfB0HohI+KXIfiQAjLv
+=MJcD
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/files/vm/ostree-config/gnome.conf.in b/files/vm/ostree-config/gnome.conf.in
new file mode 100644
index 00000000..2732f205
--- /dev/null
+++ b/files/vm/ostree-config/gnome.conf.in
@@ -0,0 +1,4 @@
+[remote "GnomeOS"]
+url=OSTREE_REMOTE_URL
+gpg-verify=true
+gpgkeypath=/etc/pki/ostree/gnome.gpg
diff --git a/files/vm/ostree-config/ostree.conf b/files/vm/ostree-config/ostree.conf
new file mode 100644
index 00000000..a8531636
--- /dev/null
+++ b/files/vm/ostree-config/ostree.conf
@@ -0,0 +1,4 @@
+d /var/log/journal 0755 root root -
+L /var/home - - - - ../sysroot/home
+d /var/roothome 0700 root root -
+d /run/media 0755 root root -
diff --git a/plugins/collect_initial_scripts.py b/plugins/collect_initial_scripts.py
new file mode 100644
index 00000000..fe3b346d
--- /dev/null
+++ b/plugins/collect_initial_scripts.py
@@ -0,0 +1,55 @@
+import os
+import re
+from buildstream import Element, ElementError, Scope
+
+class ExtractInitialScriptsElement(Element):
+ def configure(self, node):
+ self.node_validate(node, [
+ 'path',
+ ])
+
+ self.path = self.node_subst_member(node, 'path')
+
+ def preflight(self):
+ runtime_deps = list(self.dependencies(Scope.RUN, recurse=False))
+ if runtime_deps:
+ raise ElementError("{}: Only build type dependencies supported by collect-integration elements"
+ .format(self))
+
+ sources = list(self.sources())
+ if sources:
+ raise ElementError("{}: collect-integration elements may not have sources".format(self))
+
+ def get_unique_key(self):
+ key = {
+ 'path': self.path,
+ }
+ return key
+
+ def configure_sandbox(self, sandbox):
+ pass
+
+ def stage(self, sandbox):
+ pass
+
+ def assemble(self, sandbox):
+ basedir = sandbox.get_directory()
+ path = os.path.join(basedir, self.path.lstrip(os.sep))
+ index = 0
+ for dependency in self.dependencies(Scope.BUILD):
+ public = dependency.get_public_data('initial-script')
+ if public and 'script' in public:
+ script = self.node_subst_member(public, 'script')
+ index += 1
+ depname = re.sub('[^A-Za-z0-9]', '_', dependency.name)
+ basename = '{:03}-{}'.format(index, depname)
+ filename = os.path.join(path, basename)
+ os.makedirs(path, exist_ok=True)
+ with open(filename, 'w') as f:
+ f.write(script)
+ os.chmod(filename, 0o755)
+
+ return os.sep
+
+def setup():
+ return ExtractInitialScriptsElement
diff --git a/plugins/ostree_mirror.py b/plugins/ostree_mirror.py
new file mode 100644
index 00000000..bac84ab3
--- /dev/null
+++ b/plugins/ostree_mirror.py
@@ -0,0 +1,120 @@
+import os
+import shutil
+import gi
+gi.require_version('OSTree', '1.0')
+gi.require_version('Gio', '2.0')
+from gi.repository import OSTree, Gio, GLib
+from buildstream import Source, SourceError, Consistency
+from buildstream import utils
+import collections
+import fnmatch
+
+class OSTreeMirrorSource(Source):
+
+ def configure(self, node):
+ self.node_validate(node, ['match', 'path', 'url', 'ref', 'gpg'] + Source.COMMON_CONFIG_KEYS)
+
+ self.original_url = self.node_get_member(node, str, 'url', None)
+ if self.original_url:
+ self.url = self.translate_url(self.original_url)
+ else:
+ path = self.node_get_project_path(node, 'path')
+ fullpath = os.path.join(self.get_project_directory(), path)
+ self.url = self.original_url = 'file://{}'.format(fullpath)
+ self.ref = self.node_get_member(node, list, 'ref', None)
+ if self.ref is not None:
+ for r in self.ref:
+ self.node_validate(r, ['ref', 'checksum'])
+ self.mirror = os.path.join(self.get_mirror_directory(),
+ utils.url_directory_name(self.original_url))
+
+ gpg = self.node_get_project_path(node, 'gpg')
+ self.gpg = os.path.join(self.get_project_directory(), gpg)
+ self.match = self.node_get_member(node, str, 'match', None)
+
+ self.repo = OSTree.Repo.new(Gio.File.new_for_path(self.mirror))
+ if os.path.isdir(self.mirror):
+ self.repo.open()
+ else:
+ os.makedirs(self.mirror)
+ self.repo.create(OSTree.RepoMode.ARCHIVE)
+ self.repo.remote_add('origin', self.url, None, None)
+
+ gpgfile = Gio.File.new_for_path(self.gpg)
+ self.repo.remote_gpg_import('origin', gpgfile.read(None), None, None)
+
+ def preflight(self):
+ pass
+
+ def get_unique_key(self):
+ return [self.original_url, sorted(self.ref, key=lambda x: x['ref'])]
+
+ def load_ref(self, node):
+ self.ref = self.node_get_member(node, list, 'ref', None)
+ if self.ref is not None:
+ for r in self.ref:
+ self.node_validate(r, ['ref', 'checksum'])
+
+ def get_ref(self):
+ return self.ref
+
+ def set_ref(self, ref, node):
+ node['ref'] = self.ref = ref
+
+ def track(self):
+ self.repo.pull('origin', None,
+ OSTree.RepoPullFlags.MIRROR,
+ None, None)
+
+ found, refs = self.repo.remote_list_refs('origin')
+ kept_refs = []
+ for ref, checksum in sorted(refs.items(), key = lambda x: x[0]):
+ if not self.match or fnmatch.fnmatch(ref, self.match):
+ kept_refs.append({'ref': ref, 'checksum': checksum})
+
+ return kept_refs
+
+ def _refs(self):
+ for r in self.ref:
+ ref = r['ref']
+ checksum = r['checksum']
+ yield ref, checksum
+
+ def fetch(self):
+ to_fetch = []
+ for _, checksum in self._refs():
+ found, _ = self.repo.resolve_rev(checksum, False)
+ if not found:
+ to_fetch.append(checksum)
+
+ if to_fetch:
+ self.repo.pull('origin', [to_fetch],
+ OSTree.RepoPullFlags.MIRROR,
+ None, None)
+
+ def stage(self, directory):
+ local_repo = OSTree.Repo.new(Gio.File.new_for_path(directory))
+ local_repo.create(OSTree.RepoMode.ARCHIVE)
+
+ refs = GLib.Variant("as", [checksum for _, checksum in self._refs()])
+ options = GLib.Variant("a{sv}", {
+ 'refs': refs,
+ })
+
+ local_repo.pull_with_options('file://{}'.format(self.mirror),
+ options, None)
+ for ref, checksum in self._refs():
+ local_repo.set_ref_immediate(None, ref, checksum, None)
+
+ def get_consistency(self):
+ if self.ref is None:
+ return Consistency.INCONSISTENT
+
+ for _, checksum in self._refs():
+ found, _ = self.repo.resolve_rev(checksum, False)
+ if not found:
+ return Consistency.RESOLVED
+ return Consistency.CACHED
+
+def setup():
+ return OSTreeMirrorSource
diff --git a/project.conf b/project.conf
index 54cca149..c20d1695 100644
--- a/project.conf
+++ b/project.conf
@@ -32,6 +32,13 @@ options:
- i686
- x86_64
+ repo_mode:
+ type: enum
+ description: Which remote repository should the bootable image use
+ default: nightly
+ values:
+ - nightly
+ - local
# Source aliases.
#
@@ -205,6 +212,7 @@ shell:
variables:
branch: master
+ ostree-branch: "gnome-os/%{arch}/%{branch}"
gcc_arch: "%{arch}"
abi: "gnu"
gcc_triplet: "%{gcc_arch}-linux-%{abi}"
@@ -228,6 +236,12 @@ variables:
- arch == "arm":
abi: "gnueabihf"
+ - repo_mode == 'local':
+ # This is the default address to the host using QEMU user netdev
+ ostree-remote-url: "http://10.0.2.2:8000/"
+ - repo_mode == 'nightly':
+ ostree-remote-url: "https://nightly.gnome.org/gnomeos/repo"
+
# This should eventually done with buildstream includes
strip-binaries: |
touch source-files
@@ -284,3 +298,9 @@ plugins:
sources:
cargo: 0
git_tag: 1
+- origin: local
+ path: plugins
+ elements:
+ collect_initial_scripts: 0
+ sources:
+ ostree_mirror: 0
diff --git a/utils/build-image.sh b/utils/build-image.sh
new file mode 100755
index 00000000..e18f935e
--- /dev/null
+++ b/utils/build-image.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -eu
+
+: ${REPO_MODE:=local}
+export BST="${BST:-bst} -o repo_mode ${REPO_MODE}"
+
+if [ "${REPO_MODE}" = local ]; then
+ ./utils/update-local-repo.sh
+fi
+
+${BST} track vm/image.bst
+${BST} build vm/image.bst
+${BST} checkout vm/image.bst image
diff --git a/utils/run-local-repo.sh b/utils/run-local-repo.sh
new file mode 100755
index 00000000..7ac3bf85
--- /dev/null
+++ b/utils/run-local-repo.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+exec python3 -m http.server 8000 --directory ostree-repo
diff --git a/utils/update-local-repo.sh b/utils/update-local-repo.sh
new file mode 100755
index 00000000..ce534f08
--- /dev/null
+++ b/utils/update-local-repo.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+set -eu
+
+export BST="${BST:-bst} -o repo_mode local"
+
+ref="$(${BST} show --format "%{vars}" --deps none vm/repo.bst | sed '/ostree-branch: /{;s///;q;};d')"
+
+
+
+if ! [ -d ostree-gpg ]; then
+ rm -rf ostree-gpg.tmp
+ mkdir ostree-gpg.tmp
+ chmod 0700 ostree-gpg.tmp
+ cat >ostree-gpg.tmp/key-config <<EOF
+Key-Type: DSA
+Key-Length: 1024
+Subkey-Type: ELG-E
+Subkey-Length: 1024
+Name-Real: Gnome OS
+Expire-Date: 0
+%no-protection
+%commit
+%echo finished
+EOF
+ gpg --batch --homedir=ostree-gpg.tmp --generate-key ostree-gpg.tmp/key-config
+ gpg --homedir=ostree-gpg.tmp -k --with-colons | sed '/^fpr:/q;d' | cut -d: -f10
ostree-gpg.tmp/default-id
+ gpg --homedir=ostree-gpg.tmp --export --armor >local.gpg
+ mv ostree-gpg.tmp ostree-gpg
+fi
+
+utils/update-repo.sh \
+ --gpg-homedir=ostree-gpg \
+ --gpg-sign="$(cat ostree-gpg/default-id)" \
+ --collection-id=org.gnome.GnomeOS \
+ ostree-repo vm/repo.bst \
+ "${ref}"
diff --git a/utils/update-repo.sh b/utils/update-repo.sh
new file mode 100755
index 00000000..2e5b2b1a
--- /dev/null
+++ b/utils/update-repo.sh
@@ -0,0 +1,108 @@
+#!/bin/bash
+
+set -eu
+
+gpg_opts=()
+main_opts=()
+
+help() {
+ cat <<EOF
+$0 [OPTIONS] REPO ELEMENT REF
+EOF
+}
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --gpg-*=*)
+ gpg_opts+=("$1")
+ ;;
+ --gpg-*)
+ gpg_opts+=("$1", "$2")
+ shift
+ ;;
+ --collection-id=*)
+ collection_id="${1#--collection-id=}"
+ ;;
+ --collection-id)
+ collection_id="${2}"
+ shift
+ ;;
+ --help)
+ help
+ exit 0
+ ;;
+ --)
+ main_opts+=("$@")
+ shift $(($#-1))
+ ;;
+ --*)
+ echo "Unknown option '$1'" 1>&2
+ exit 1
+ ;;
+ -*)
+ for ((i=1;$i < ${#1};++i)); do
+ case "${1:i}" in
+ h)
+ help
+ exit 0
+ ;;
+ *)
+ echo "Unknown option '${1:i}'" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ *)
+ main_opts+=("$1")
+ ;;
+ esac
+ shift
+done
+
+if [ ${#main_opts[*]} -ne 3 ]; then
+ echo "Wrong number of parameters" 1>&2
+ exit 1
+fi
+
+OSTREE_REPO="${main_opts[0]}"
+export OSTREE_REPO
+element="${main_opts[1]}"
+ref="${main_opts[2]}"
+
+checkout="$(mktemp --suffix="-update-repo" -d -p "$(dirname ${OSTREE_REPO})")"
+
+on_exit() {
+ rm -rf "${checkout}"
+}
+trap on_exit EXIT
+
+${BST:-bst} build "${element}"
+${BST:-bst} checkout --hardlinks "${element}" "${checkout}"
+
+if ! [ -d ${OSTREE_REPO} ]; then
+ ostree init --repo=${OSTREE_REPO} --mode=archive
+fi
+
+commit="$(ostree --repo="${checkout}/ostree/repo" rev-parse "${ref}")"
+ostree pull-local "${checkout}/ostree/repo" "${commit}"
+
+prev_commit="$(ostree rev-parse "${ref}" 2>/dev/null || true)"
+
+ostree commit ${gpg_opts[*]} \
+ --branch="${ref}" --tree=ref="${commit}" --skip-if-unchanged
+
+new_commit="$(ostree rev-parse "${ref}")"
+
+if [ "${new_commit}" != "${prev_commit}" ]; then
+ ostree prune --refs-only --keep-younger-than="6 months ago"
+
+ if [ -n "${prev_commit}" ]; then
+ ostree static-delta generate "${ref}"
+ fi
+
+ ostree summary \
+ ${collection_id:+--add-metadata=ostree.deploy-collection-id='"'"${collection_id}"'"'} \
+ ${gpg_opts[*]} \
+ --update
+fi
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]