Commit: a95b833c
This commit is contained in:
commit
a8d8515b75
|
|
@ -0,0 +1,6 @@
|
||||||
|
site/
|
||||||
|
image_output/
|
||||||
|
osbuild_store/
|
||||||
|
|
||||||
|
*~
|
||||||
|
*.swp
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
include:
|
||||||
|
- project: 'redhat/edge/ci-cd/pipe-x/pipelines-as-code'
|
||||||
|
ref: gitlab-ci
|
||||||
|
file:
|
||||||
|
- '/.gitlab/trigger.yml'
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- trigger
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
[allowlist]
|
||||||
|
description = "This repository contains a few passwords for demo accounts, it is fine"
|
||||||
|
paths = [
|
||||||
|
'''ignore\.d''',
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
'''*\.mpp\.json$'''
|
||||||
|
]
|
||||||
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 AutoBase
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Automotive sample images
|
||||||
|
|
||||||
|
This is the git repository for the Automotive SIG sample images. It contains recipes for
|
||||||
|
building some sample automotive images and information on how to download them.
|
||||||
|
|
||||||
|
For more information, visit:
|
||||||
|
|
||||||
|
* [Automotive SIG wiki page] (https://wiki.centos.org/SpecialInterestGroup/Automotive)
|
||||||
|
* [Automotive SIG documentation] (https://sigs.centos.org/automotive)
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
FROM centos:stream9-development
|
||||||
|
|
||||||
|
RUN dnf install -y 'dnf-command(config-manager)' && \
|
||||||
|
dnf config-manager --set-enabled crb && \
|
||||||
|
dnf copr enable -y @osbuild/osbuild
|
||||||
|
|
||||||
|
RUN dnf install -y \
|
||||||
|
"@Development Tools" \
|
||||||
|
# Some convenience packages \
|
||||||
|
bash-completion \
|
||||||
|
dnf \
|
||||||
|
emacs \
|
||||||
|
less \
|
||||||
|
strace \
|
||||||
|
vim \
|
||||||
|
git \
|
||||||
|
wget \
|
||||||
|
# Dependencies for building images \
|
||||||
|
osbuild-ostree \
|
||||||
|
osbuild-tools \
|
||||||
|
# Dependencies to build the kernel's RPM \
|
||||||
|
rpm-build \
|
||||||
|
hostname \
|
||||||
|
openssl-devel \
|
||||||
|
bc \
|
||||||
|
binutils-devel \
|
||||||
|
bpftool \
|
||||||
|
clang \
|
||||||
|
dwarves \
|
||||||
|
gcc-plugin-devel \
|
||||||
|
libcap-devel \
|
||||||
|
libcap-ng-devel \
|
||||||
|
libmnl-devel \
|
||||||
|
llvm \
|
||||||
|
net-tools \
|
||||||
|
numactl-devel \
|
||||||
|
perl-devel \
|
||||||
|
python3-devel \
|
||||||
|
python3-docutils \
|
||||||
|
rsync && \
|
||||||
|
dnf clean all
|
||||||
|
|
||||||
|
CMD ["/usr/bin/bash"]
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
{
|
||||||
|
"product": "Automotive-sig_images",
|
||||||
|
"version": 1,
|
||||||
|
"builds": {
|
||||||
|
"minimal": {
|
||||||
|
"manifest": "minimal",
|
||||||
|
"type": "ostree",
|
||||||
|
"target": "qemu",
|
||||||
|
"format" : "qcow2",
|
||||||
|
"arches": [
|
||||||
|
"x86_64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"automotive-product"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"minimal-rpi": {
|
||||||
|
"manifest": "minimal",
|
||||||
|
"type": "regular",
|
||||||
|
"target": "rpi4",
|
||||||
|
"format" : "img",
|
||||||
|
"arches": [
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"qa": {
|
||||||
|
"manifest": "qa",
|
||||||
|
"type": "ostree",
|
||||||
|
"target": "qemu",
|
||||||
|
"format" : "qcow2",
|
||||||
|
"arches": [
|
||||||
|
"x86_64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"neptune": {
|
||||||
|
"manifest": "neptune",
|
||||||
|
"type": "ostree",
|
||||||
|
"target": "qemu",
|
||||||
|
"format" : "qcow2",
|
||||||
|
"arches": [
|
||||||
|
"x86_64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"neptune-rpi": {
|
||||||
|
"manifest": "neptune",
|
||||||
|
"type": "regular",
|
||||||
|
"target": "rpi4",
|
||||||
|
"format" : "img",
|
||||||
|
"arches": [
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"developer": {
|
||||||
|
"manifest": "developer",
|
||||||
|
"type": "regular",
|
||||||
|
"target": "qemu",
|
||||||
|
"format" : "qcow2",
|
||||||
|
"arches": [
|
||||||
|
"x86_64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"developer-rpi": {
|
||||||
|
"manifest": "developer",
|
||||||
|
"type": "regular",
|
||||||
|
"target": "rpi4",
|
||||||
|
"format" : "img",
|
||||||
|
"arches": [
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"container": {
|
||||||
|
"manifest": "container",
|
||||||
|
"type": "regular",
|
||||||
|
"target": "qemu",
|
||||||
|
"format" : "qcow2",
|
||||||
|
"arches": [
|
||||||
|
"x86_64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"package-sets": [
|
||||||
|
"cs9"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
*.json
|
||||||
|
!*.mpp.json
|
||||||
|
|
@ -0,0 +1,212 @@
|
||||||
|
NULL=
|
||||||
|
EMPTY :=
|
||||||
|
SPACE := $(EMPTY) $(EMPTY)
|
||||||
|
COMMA := ,
|
||||||
|
ESCAPEDSPACE := \$(SPACE)
|
||||||
|
ESCAPEDSPACE_REPLACEMENT := @@SPACE@@
|
||||||
|
|
||||||
|
# This is useful to handle space in forech rules
|
||||||
|
handle-escaped-space = $(subst $(ESCAPEDSPACE),$(ESCAPEDSPACE_REPLACEMENT),$1)
|
||||||
|
apply-escaped-space = $(subst $(ESCAPEDSPACE_REPLACEMENT),$(SPACE),$1)
|
||||||
|
|
||||||
|
HOST_ARCH:=$(shell arch)
|
||||||
|
|
||||||
|
ARCHES := x86_64 aarch64
|
||||||
|
|
||||||
|
|
||||||
|
export VM=0
|
||||||
|
|
||||||
|
OSBUILD_MPP=osbuild-mpp
|
||||||
|
|
||||||
|
DEFINES=
|
||||||
|
DEFINES_ARGS:=$(foreach def,$(call handle-escaped-space,$(DEFINES)),-D '$(call apply-escaped-space,$(def))')
|
||||||
|
MPP_ARGS=
|
||||||
|
export OSBUILD_ARGS=
|
||||||
|
|
||||||
|
BUILDDIR=_build
|
||||||
|
export STOREDIR=$(BUILDDIR)/osbuild_store
|
||||||
|
export OUTPUTDIR=$(BUILDDIR)/image_output
|
||||||
|
|
||||||
|
IMAGEDIR=
|
||||||
|
|
||||||
|
DISTROS := $(basename $(basename $(notdir f,$(wildcard distro/*.ipp.yml))))
|
||||||
|
MANIFESTS := $(wildcard images/*.mpp.yml) $(foreach DIR,$(IMAGEDIR),$(wildcard $(DIR)/*))
|
||||||
|
|
||||||
|
EXTRA_MPP_ARGS= # For internal use
|
||||||
|
ifdef OSTREE_REPO
|
||||||
|
EXTRA_MPP_ARGS +=-D ostree_parent_refs='$(shell tools/ot-refs $(OSTREE_REPO))'
|
||||||
|
endif
|
||||||
|
|
||||||
|
export CHECKPOINTS=build
|
||||||
|
IMAGETYPES := regular ostree direct
|
||||||
|
FORMATS := img qcow2 oci.tar repo rootfs ext4 tar
|
||||||
|
aarch64_TARGETS := rpi4
|
||||||
|
COMMON_TARGETS := qemu aws
|
||||||
|
HOST_TARGETS := $(COMMON_TARGETS) $($(HOST_ARCH)_TARGETS)
|
||||||
|
ALL_TARGETS := $(COMMON_TARGETS) $(foreach a,$(ARCHES), $($(a)_TARGETS))
|
||||||
|
|
||||||
|
manifest-get-name = $(basename $(basename $(notdir $1)))
|
||||||
|
manifest-get-dir = $(notdir $(patsubst %/,%,$(dir $1)))
|
||||||
|
image-name-noarch = $1-$3-$(call manifest-get-name,$2)-$4
|
||||||
|
image-name = $(call image-name-noarch,$1,$2,$3,$4).$5
|
||||||
|
|
||||||
|
# variable name for image type
|
||||||
|
regular_IMAGETYPE := regular
|
||||||
|
ostree_IMAGETYPE := ostree
|
||||||
|
direct_IMAGETYPE := directboot
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo
|
||||||
|
@echo This makefile is a wrapper around osbuild-mpp and osbuild to easily build images
|
||||||
|
@echo
|
||||||
|
@echo To build a raw image, run \"make image.img\", or to build a qcow2 image, run \"make image.qcow2\".
|
||||||
|
@echo This will build any image from a file called \"image.mpp.yml\" in the \"images\" subdirectory. You can
|
||||||
|
@echo pass IMAGEDIR=/some/other/path to make also to pick up manifests from an external directory.
|
||||||
|
@echo
|
||||||
|
@echo For example, to build a minimal qcow2 image with ostree support targeting qemu, run:
|
||||||
|
@echo ' make cs9-qemu-minimal-ostree.$(HOST_ARCH).qcow2'
|
||||||
|
@echo
|
||||||
|
@echo Other extensions are also supported:
|
||||||
|
@echo \ \* .repo: Generate a repo with an ostree commit \(only works for ostree targets\)
|
||||||
|
@echo \ \* .rootfs: Generate a directory with the rootfs content
|
||||||
|
@echo \ \* .tar: Generate a tar file with the rootfs content
|
||||||
|
@echo \ \* .ext4: Generate an ext4 filesystem with the rootfs content \(size from \"image_size\"\)
|
||||||
|
@echo \ \* oci.tar: Generate an oci container image with the rootfs content
|
||||||
|
@echo
|
||||||
|
@echo You can pass variable declarations to osbuild-mpp with the DEFINES make variable.
|
||||||
|
@echo Multiple defines are separated by space, if you need a space inside a value escape it using \"\\ \".
|
||||||
|
@echo For example, to add extra rpms to a minimal regular image, use:
|
||||||
|
@echo " make cs9-qemu-minimal-regular.$(HOST_ARCH).qcow2 DEFINES='extra_rpms=[\"gdb\",\"strace\"]'"
|
||||||
|
@echo
|
||||||
|
@echo To easily run the image with qemu, you can use the included runvm tool, like:
|
||||||
|
@echo \ \ ./runvm cs9-qemu-minimal-regular.$(HOST_ARCH).qcow2
|
||||||
|
@echo
|
||||||
|
@echo There are some additional targets:
|
||||||
|
@echo \ \ manifests: generates resolved json manifests for all images without building them.
|
||||||
|
@echo \ \ clean_caches: Removes intermediate image build artifacts \(that improve rebuild speed\)
|
||||||
|
@echo \ \ clean_downloads: Removes files downloaded during image builds
|
||||||
|
@echo \ \ clean: Run clean_caches and clean_downloads
|
||||||
|
@echo \ \ osbuildvm-images: Build a image that can be used to build images inside a VM
|
||||||
|
@echo
|
||||||
|
@echo There are also some common conversion rules:
|
||||||
|
@echo \ \ foo.ext4.simg will build foo.ext4 and then convert it with img2simg
|
||||||
|
@echo \ \ foo.simg will build foo.img and then convert it with img2simg
|
||||||
|
@echo \ \ foo.tar.gz will build $foo.tar and then gzip it
|
||||||
|
@echo
|
||||||
|
@echo "When building a custom variant of an image (say with an extra package) you can use a"
|
||||||
|
@echo custom @suffix to change the name of the produced file. For example:
|
||||||
|
@echo " make cs9-qemu-minimal-ostree@gdb.$(HOST_ARCH).qcow2 DEFINES='extra_rpms=[\"gdb\"]'"
|
||||||
|
@echo
|
||||||
|
@echo If you pass VM=1, then the images used from \"make osbuildvm-images\" will be used to do the
|
||||||
|
@echo actual building. This means that you don\'t need sudo rights to run osbuild, and it means
|
||||||
|
@echo architectures other than the current ones can be built.
|
||||||
|
@echo
|
||||||
|
@echo Available image targets \(for $(HOST_ARCH)\) are:
|
||||||
|
@echo
|
||||||
|
@$(foreach d, $(DISTROS), $(foreach m, $(MANIFESTS), $(foreach t, $(HOST_TARGETS), $(foreach i,$(IMAGETYPES), echo -e " " $(call image-name,$d,$m,$t,$i,$(HOST_ARCH)).[$(subst $(SPACE),$(COMMA),$(FORMATS))];))))
|
||||||
|
@echo
|
||||||
|
|
||||||
|
# We pre-create all the toplevel dirs, so that they are owned by the user, not root (when created under sudo)
|
||||||
|
.PHONY: $(BUILDDIR)
|
||||||
|
$(BUILDDIR):
|
||||||
|
@mkdir -p $(BUILDDIR)
|
||||||
|
@mkdir -p $(STOREDIR)/{objects,refs,sources/org.osbuild.files,tmp}
|
||||||
|
@mkdir -p $(OUTPUTDIR)
|
||||||
|
|
||||||
|
# Template rule for producing osbuild json manifest from mpp yaml and image type
|
||||||
|
# $1 == distro name
|
||||||
|
# $2 == yaml manifest path
|
||||||
|
# $3 == Target name
|
||||||
|
# $4 == Image type
|
||||||
|
# $5 == Arch
|
||||||
|
define json-rule
|
||||||
|
$(BUILDDIR)/$(call image-name,$1,$2,$3,$4,$5).json: $2 $(BUILDDIR)
|
||||||
|
$(OSBUILD_MPP) -I . -D image_type="\"$($4_IMAGETYPE)\"" -D arch=\"$5\" -D distro_name="\"$1\"" -D target="\"$3\"" $(DEFINES_ARGS) $(EXTRA_MPP_ARGS) $(MPP_ARGS) $$< $$@
|
||||||
|
.PHONY: $(BUILDDIR)/$(call image-name,$1,$2,$3,$4,$5).json
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach d, $(DISTROS), \
|
||||||
|
$(foreach m, $(MANIFESTS), \
|
||||||
|
$(foreach a,$(ARCHES), \
|
||||||
|
$(foreach t,$(COMMON_TARGETS) $($(a)_TARGETS), \
|
||||||
|
$(foreach i,$(IMAGETYPES), \
|
||||||
|
$(eval $(call json-rule,$d,$m,$t,$i,$a)))))))
|
||||||
|
|
||||||
|
# Template rule for producing image from json manifest
|
||||||
|
# $1 == distro name
|
||||||
|
# $2 == Manifest path
|
||||||
|
# $3 == Target
|
||||||
|
# $4 == Image type
|
||||||
|
# $5 == Arch
|
||||||
|
# $6 == Export format (extension)
|
||||||
|
define image-rule
|
||||||
|
$(call image-name,$1,$2,$3,$4,$5).$6: $(BUILDDIR)/$(call image-name,$1,$2,$3,$4,$5).json
|
||||||
|
@tools/runosbuild "$$@" "$$<" "$3" "$4" "$5" "$6"
|
||||||
|
|
||||||
|
$(call image-name-noarch,$1,$2,$3,$4)@%.$5.$6: $(BUILDDIR)/$(call image-name,$1,$2,$3,$4,$5).json
|
||||||
|
@tools/runosbuild "$$@" "$$<" "$3" "$4" "$5" "$6"
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach d, $(DISTROS), \
|
||||||
|
$(foreach m, $(MANIFESTS), \
|
||||||
|
$(foreach a,$(ARCHES), \
|
||||||
|
$(foreach t, $(COMMON_TARGETS) $($(a)_TARGETS), \
|
||||||
|
$(foreach f,$(FORMATS), \
|
||||||
|
$(foreach i,$(IMAGETYPES), \
|
||||||
|
$(eval $(call image-rule,$d,$m,$t,$i,$a,$f))))))))
|
||||||
|
|
||||||
|
# Rule to pre-generate all manifests
|
||||||
|
manifests: $(foreach d, $(DISTROS),$(foreach m, $(MANIFESTS), $(foreach a,$(ARCHES), $(foreach t, $(COMMON_TARGETS) $($(a)_TARGETS), $(foreach i,$(IMAGETYPES), $(BUILDDIR)/$(call image-name,$d,$m,$t,$i,$a).json)))))
|
||||||
|
|
||||||
|
define packages-rule
|
||||||
|
.PHONY: packages-$(call manifest-get-name,$1).json
|
||||||
|
packages-$(call manifest-get-name,$1).json: $1
|
||||||
|
osbuild-mpp $$< -D arch=\"x86_64\" - | jq -f tools/extract-rpms.jq > $$@.x86_64
|
||||||
|
osbuild-mpp $$< -D arch=\"aarch64\" - | jq -f tools/extract-rpms.jq > $$@.aarch64
|
||||||
|
echo 1 | jq --indent 4 -f tools/create-packagelist.jq --slurpfile x86_64 $$@.x86_64 --slurpfile aarch64 $$@.aarch64 > $$@
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach m, $(MANIFESTS), $(eval $(call packages-rule,$m)))
|
||||||
|
|
||||||
|
.PHONY: clean_downloads
|
||||||
|
clean_downloads:
|
||||||
|
sudo rm -rf _build/osbuild_store/sources/org.osbuild.files/*
|
||||||
|
|
||||||
|
.PHONY: clean_caches
|
||||||
|
clean_caches:
|
||||||
|
sudo rm -rf $(STOREDIR)/refs/*
|
||||||
|
sudo rm -rf $(STOREDIR)/refs_tars/*
|
||||||
|
sudo rm -rf $(STOREDIR)/objects/*
|
||||||
|
sudo rm -rf $(STOREDIR)/tmp/*
|
||||||
|
sudo rm -rf $(STOREDIR)/image_output/*
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: clean_downloads clean_caches
|
||||||
|
|
||||||
|
ifeq ($(VM), 1)
|
||||||
|
VM_SUDO=
|
||||||
|
VM_OSBUILD="osbuildvm/osbuildvm --arch=$(HOST_ARCH)"
|
||||||
|
else
|
||||||
|
VM_SUDO=sudo
|
||||||
|
VM_OSBUILD=sudo osbuild
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: osbuildvm-images
|
||||||
|
osbuildvm-images: $(BUILDDIR)
|
||||||
|
osbuild-mpp osbuildvm/osbuildvm.mpp.yml _build/osbuildvm-$(HOST_ARCH).json
|
||||||
|
$(VM_OSBUILD) --store $(STOREDIR) --output-directory $(OUTPUTDIR) --export osbuildvm _build/osbuildvm-$(HOST_ARCH).json
|
||||||
|
cp $(OUTPUTDIR)/osbuildvm/disk.qcow2 _build/osbuildvm-$(HOST_ARCH).img
|
||||||
|
cp $(OUTPUTDIR)/osbuildvm/initramfs _build/osbuildvm-$(HOST_ARCH).initramfs
|
||||||
|
cp $(OUTPUTDIR)/osbuildvm/vmlinuz _build/osbuildvm-$(HOST_ARCH).vmlinuz
|
||||||
|
$(VM_SUDO) rm -rf $(OUTPUTDIR)/osbuildvm
|
||||||
|
|
||||||
|
%.ext4.simg : %.ext4
|
||||||
|
img2simg $< $@
|
||||||
|
rm $<
|
||||||
|
|
||||||
|
%.simg : %.img
|
||||||
|
img2simg $< $@
|
||||||
|
rm $<
|
||||||
|
|
||||||
|
%.tar.gz : %.tar
|
||||||
|
gzip -f $<
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
distro_name: cs9
|
||||||
|
distro_version: 9
|
||||||
|
distro_baseurl: http://mirror.stream.centos.org/9-stream
|
||||||
|
distro_repos:
|
||||||
|
- id: baseos
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
- id: appstream
|
||||||
|
baseurl: $distro_baseurl/AppStream/$arch/os/
|
||||||
|
- id: automotive
|
||||||
|
baseurl: https://buildlogs.centos.org/9-stream/automotive/$arch/packages-main/
|
||||||
|
- id: autosd
|
||||||
|
baseurl: https://buildlogs.centos.org/9-stream/autosd/$arch/packages-main/
|
||||||
|
distro_devel_repos:
|
||||||
|
- id: crb
|
||||||
|
baseurl: $distro_baseurl/CRB/$arch/os/
|
||||||
|
distro_debug_repos:
|
||||||
|
- id: baseos-debug
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/debug/tree/
|
||||||
|
- id: appstream-debug
|
||||||
|
baseurl: $distro_baseurl/AppStream/$arch/debug/tree/
|
||||||
|
- id: crb-debug
|
||||||
|
baseurl: $distro_baseurl/CRB/$arch/debug/tree/
|
||||||
|
- id: autosd-debug
|
||||||
|
baseurl: https://buildlogs.centos.org/9-stream/autosd/$arch/packages-main/debug/
|
||||||
|
distro_module_id: platform:el9
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Demo engine service container
|
||||||
|
Requires=routingmanagerd.socket
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/auto-apps
|
||||||
|
Volume=/run/vsomeip:/run/vsomeip
|
||||||
|
Exec=/usr/bin/engine-service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
## custom.conf
|
||||||
|
|
||||||
|
# GDM configuration storage
|
||||||
|
|
||||||
|
[daemon]
|
||||||
|
# Uncomment the line below to force the login screen to use Xorg
|
||||||
|
# WaylandEnable=false
|
||||||
|
AutomaticLoginEnable=True
|
||||||
|
AutomaticLogin=neptune
|
||||||
|
|
||||||
|
[security]
|
||||||
|
|
||||||
|
[xdmcp]
|
||||||
|
|
||||||
|
[chooser]
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
# Uncomment the line below to turn on debugging
|
||||||
|
#Enable=true
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
## custom.conf
|
||||||
|
|
||||||
|
# GDM configuration storage
|
||||||
|
|
||||||
|
[daemon]
|
||||||
|
# Uncomment the line below to force the login screen to use Xorg
|
||||||
|
WaylandEnable=false
|
||||||
|
AutomaticLoginEnable=True
|
||||||
|
AutomaticLogin=neptune
|
||||||
|
|
||||||
|
[security]
|
||||||
|
|
||||||
|
[xdmcp]
|
||||||
|
|
||||||
|
[chooser]
|
||||||
|
|
||||||
|
[debug]
|
||||||
|
# Uncomment the line below to turn on debugging
|
||||||
|
#Enable=true
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Init neptune gdm session conf
|
||||||
|
ConditionPathExists=!/var/lib/AccountsService/users/neptune
|
||||||
|
Before=gdm.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=service
|
||||||
|
ExecStart=/bin/sh -c ' \
|
||||||
|
echo -e "[User]\nSession=neptune-%i\nXSession=neptune-xorg\nPasswordHint=\nIcon=/var/lib/AccountsService/icons/guest\nSystemAccount=false\n" \
|
||||||
|
> /var/lib/AccountsService/users/neptune'
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Demo radio service container
|
||||||
|
Requires=routingmanagerd.socket
|
||||||
|
Wants=engine.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
Image=localhost/auto-apps
|
||||||
|
Volume=/run/vsomeip:/run/vsomeip
|
||||||
|
Exec=/usr/bin/radio-service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
[storage]
|
||||||
|
|
||||||
|
driver = "overlay"
|
||||||
|
runroot = "/run/containers/storage"
|
||||||
|
graphroot = "/var/lib/containers/storage"
|
||||||
|
|
||||||
|
[storage.options]
|
||||||
|
# We add a custom "/usr/share/containers/storage" here to allow readonly in-image containers
|
||||||
|
additionalimagestores = [
|
||||||
|
"/usr/share/containers/storage"
|
||||||
|
]
|
||||||
|
|
||||||
|
[storage.options.overlay]
|
||||||
|
# Nodev for security (default in cs9)
|
||||||
|
# We use metacopy to allow better pagecache sharing of base-layers (default in cs9)
|
||||||
|
mountopt = "nodev,metacopy=on"
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
formatVersion: 1
|
||||||
|
formatType: am-configuration
|
||||||
|
---
|
||||||
|
# basic AM functionality - the builtin apps are in 'apps'.
|
||||||
|
# installations will go into the standard QStandardPath AppLocalDataLocation
|
||||||
|
# (e.g. ~/.local/share/Luxoft Sweden AB/Neptune UI) /am hierarchy
|
||||||
|
|
||||||
|
applications:
|
||||||
|
builtinAppsManifestDir: "${CONFIG_PWD}/apps"
|
||||||
|
installedAppsManifestDir: "${stdpath:AppLocalDataLocation}/neptune3-ui/manifests"
|
||||||
|
installationDir: "${stdpath:AppLocalDataLocation}/neptune3-ui/apps"
|
||||||
|
documentDir: "${stdpath:AppLocalDataLocation}/neptune3-ui/docs"
|
||||||
|
|
||||||
|
# QML apps will be able to import from modules...
|
||||||
|
|
||||||
|
runtimes:
|
||||||
|
qml:
|
||||||
|
importPaths: [ "${CONFIG_PWD}/imports_shared" ]
|
||||||
|
environmentVariables:
|
||||||
|
QT_PLUGIN_PATH: "${CONFIG_PWD}"
|
||||||
|
SERVER_CONF_PATH: "${CONFIG_PWD}/server.conf"
|
||||||
|
native:
|
||||||
|
importPaths: [ "${CONFIG_PWD}/imports_shared" ]
|
||||||
|
environmentVariables:
|
||||||
|
QT_PLUGIN_PATH: "${CONFIG_PWD}"
|
||||||
|
SERVER_CONF_PATH: "${CONFIG_PWD}/server.conf"
|
||||||
|
|
||||||
|
# ... as well as the SystemUI
|
||||||
|
|
||||||
|
ui:
|
||||||
|
fullscreen: yes
|
||||||
|
style: "${CONFIG_PWD}/styles/neptune"
|
||||||
|
iconThemeName: "neptune"
|
||||||
|
iconThemeSearchPaths: [ "${CONFIG_PWD}/imports_shared/assets/icons" ]
|
||||||
|
mainQml: "${CONFIG_PWD}/Main.qml"
|
||||||
|
importPaths: [ "${CONFIG_PWD}/imports_shared", "${CONFIG_PWD}/imports_system", "${CONFIG_PWD}/sysui" ]
|
||||||
|
windowIcon: "${CONFIG_PWD}/imports_shared/assets/icons/neptune/sysui/ic-menu-home.png"
|
||||||
|
enableTouchEmulation: yes
|
||||||
|
|
||||||
|
systemProperties:
|
||||||
|
public:
|
||||||
|
showCluster: no
|
||||||
|
showHUD: no
|
||||||
|
devMode: yes
|
||||||
|
enableCursorManagement: no
|
||||||
|
hardwareVariant: 'high'
|
||||||
|
#Qt Safe Renderer settings
|
||||||
|
qsrEnabled: no
|
||||||
|
qsrServerAddress: '127.0.0.1'
|
||||||
|
qsrServerPort: '1111'
|
||||||
|
showSystemAppsInLauncher: no
|
||||||
|
private:
|
||||||
|
appStoreServerUrl: 'http://demoappsdeploy.qt.io:8514'
|
||||||
|
userName: 't'
|
||||||
|
userPassword: 't'
|
||||||
|
imei: '112163001487801'
|
||||||
|
orientation: 'Landscape'
|
||||||
|
adjustSizesForScreen: yes
|
||||||
|
|
||||||
|
# development setup: no security
|
||||||
|
|
||||||
|
flags:
|
||||||
|
noSecurity: yes
|
||||||
|
noUiWatchdog: yes
|
||||||
|
|
||||||
|
# default logging
|
||||||
|
|
||||||
|
logging:
|
||||||
|
rules:
|
||||||
|
- "*=false"
|
||||||
|
- "qt.*=false"
|
||||||
|
- "qt.gamepad*=true"
|
||||||
|
- "am.*=false"
|
||||||
|
- "qml*=true"
|
||||||
|
- "cursor.navigation=false"
|
||||||
|
- "qt3ds.*=false"
|
||||||
|
- "shared.com.pelagicore.map.info=false"
|
||||||
|
- "*.warning=false"
|
||||||
|
- "*.critical=true"
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=neptune3-ui
|
||||||
|
StartupNotify=false
|
||||||
|
Terminal=false
|
||||||
|
Name[en_US]=neptune3-ui
|
||||||
|
Comment[en_US]=Launches neptune3-ui on logging in
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=Application
|
||||||
|
Exec=env QT_QPA_PLATFORM=wayland QT_IM_MODULE=qtvirtualkeyboard neptune3-ui
|
||||||
|
StartupNotify=false
|
||||||
|
Terminal=false
|
||||||
|
Name[en_US]=neptune3-ui
|
||||||
|
Comment[en_US]=Launches neptune3-ui on logging in
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
[GNOME Session]
|
||||||
|
Name=Neptune XOrg
|
||||||
|
RequiredComponents=mutter;neptune3-ui-xorg;
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
[GNOME Session]
|
||||||
|
Name=Neptune
|
||||||
|
RequiredComponents=mutter;neptune3-ui;
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Neptune (Wayland)
|
||||||
|
Comment=This session logs you into Neptune
|
||||||
|
Exec=gnome-session --session=neptune
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=GNOME
|
||||||
|
X-GDM-SessionRegisters=true
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=Neptune (XOrg)
|
||||||
|
Comment=This session logs you into Neptune
|
||||||
|
Exec=gnome-session --session=neptune-xorg
|
||||||
|
Type=Application
|
||||||
|
DesktopNames=GNOME
|
||||||
|
X-GDM-SessionRegisters=true
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: container
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
- - id: copr-quadlet
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/alexl/quadlet/centos-stream-9-$arch/
|
||||||
|
- - id: copr-sample-apps
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/alexl/cs9-sample-images/centos-stream-9-$arch/
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- - podman
|
||||||
|
- quadlet
|
||||||
|
- curl
|
||||||
|
- vsomeip3-routingmanager
|
||||||
|
- auto-apps
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: storage.conf
|
||||||
|
path: ../files/storage.conf
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['storage.conf']}
|
||||||
|
to: tree:///etc/containers/storage.conf
|
||||||
|
- type: org.osbuild.skopeo
|
||||||
|
inputs:
|
||||||
|
images:
|
||||||
|
type: org.osbuild.containers
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-resolve-images:
|
||||||
|
images:
|
||||||
|
- source: registry.gitlab.com/centos/automotive/sample-images/demo/auto-apps
|
||||||
|
tag: latest
|
||||||
|
name: localhost/auto-apps
|
||||||
|
options:
|
||||||
|
destination:
|
||||||
|
type: containers-storage
|
||||||
|
storage-path: /usr/share/containers/storage
|
||||||
|
- type: org.osbuild.mkdir
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- path: /etc/containers/systemd
|
||||||
|
parents: true
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: radio.container
|
||||||
|
path: ../files/radio.container
|
||||||
|
inlinefile2:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: engine.container
|
||||||
|
path: ../files/engine.container
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['radio.container']}
|
||||||
|
to: tree:///etc/containers/systemd/radio.container
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile2/{embedded['engine.container']}
|
||||||
|
to: tree:///etc/containers/systemd/engine.container
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
guest:
|
||||||
|
password:
|
||||||
|
mpp-eval: guest_password
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- rngd.service
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: developer
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: distro_devel_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
- - id: osbuild
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/@osbuild/osbuild/centos-stream-9-$arch
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- - "@Development Tools"
|
||||||
|
# Some convenience packages
|
||||||
|
- bash-completion
|
||||||
|
- dnf
|
||||||
|
- emacs-nox
|
||||||
|
- less
|
||||||
|
- strace
|
||||||
|
- sudo
|
||||||
|
- vim
|
||||||
|
- git
|
||||||
|
- wget
|
||||||
|
- make
|
||||||
|
# Dependencies to build RPMs and images
|
||||||
|
- rpm-build
|
||||||
|
- hostname
|
||||||
|
- openssl-devel
|
||||||
|
- bc
|
||||||
|
- binutils-devel
|
||||||
|
- bpftool
|
||||||
|
- clang
|
||||||
|
- dwarves
|
||||||
|
- gcc-plugin-devel
|
||||||
|
- libcap-devel
|
||||||
|
- libcap-ng-devel
|
||||||
|
- libmnl-devel
|
||||||
|
- llvm
|
||||||
|
- net-tools
|
||||||
|
- numactl-devel
|
||||||
|
- osbuild-ostree
|
||||||
|
- osbuild-tools
|
||||||
|
- openssh-clients
|
||||||
|
- openssh-server
|
||||||
|
- perl-devel
|
||||||
|
- python3-devel
|
||||||
|
- python3-docutils
|
||||||
|
- rsync
|
||||||
|
- iputils
|
||||||
|
- iproute
|
||||||
|
- qemu-kvm
|
||||||
|
- fuse-devel
|
||||||
|
- kernel-rpm-macros
|
||||||
|
# Container tools
|
||||||
|
- podman
|
||||||
|
- buildah
|
||||||
|
- skopeo
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
guest:
|
||||||
|
password:
|
||||||
|
mpp-eval: guest_password
|
||||||
|
- type: org.osbuild.sshd.config
|
||||||
|
options:
|
||||||
|
config:
|
||||||
|
PermitRootLogin:
|
||||||
|
mpp-eval: ssh_permit_root_login
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- rngd.service
|
||||||
|
- sshd.service
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
Binary file not shown.
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
# This image demontrates how to use an encrypted rootfs
|
||||||
|
# Due to the use of luks_auto_unlock, the passphrase is copied to the initrd and
|
||||||
|
# the rootfs uses this to automatically unlock the system on the first boot.
|
||||||
|
# However, the autosig-sample-tpm-enroll service is also installed, and this
|
||||||
|
# will replace the passphrase with a TPM based token, meaning that later
|
||||||
|
# boots are tied to this machine only.
|
||||||
|
# Remember to pass --tpm2 to runvm when testing this.
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: encrypted
|
||||||
|
use_luks: true
|
||||||
|
luks_auto_unlock: true
|
||||||
|
extra_boot_rpms:
|
||||||
|
- clevis-dracut
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
# Install the tools and service files
|
||||||
|
- - autosig-sample-tpm-enroll
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- rngd.service
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: gadget
|
||||||
|
image_size: '3221225472'
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: distro_devel_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
- - id: osbuild
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/@osbuild/osbuild/centos-stream-9-$arch
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- - "@Development Tools"
|
||||||
|
- firewalld
|
||||||
|
# Some convenience packages
|
||||||
|
- bash-completion
|
||||||
|
- dnf
|
||||||
|
- emacs-nox
|
||||||
|
- less
|
||||||
|
- strace
|
||||||
|
- sudo
|
||||||
|
- vim
|
||||||
|
- git
|
||||||
|
- wget
|
||||||
|
- make
|
||||||
|
# Dependencies to build RPMs and images
|
||||||
|
- rpm-build
|
||||||
|
- hostname
|
||||||
|
- openssl-devel
|
||||||
|
- bc
|
||||||
|
- binutils-devel
|
||||||
|
- bpftool
|
||||||
|
- clang
|
||||||
|
- dwarves
|
||||||
|
- gcc-plugin-devel
|
||||||
|
- libcap-devel
|
||||||
|
- libcap-ng-devel
|
||||||
|
- libmnl-devel
|
||||||
|
- llvm
|
||||||
|
- net-tools
|
||||||
|
- numactl-devel
|
||||||
|
- osbuild-ostree
|
||||||
|
- osbuild-tools
|
||||||
|
- openssh-clients
|
||||||
|
- openssh-server
|
||||||
|
- perl-devel
|
||||||
|
- python3-devel
|
||||||
|
- python3-docutils
|
||||||
|
- rsync
|
||||||
|
- iputils
|
||||||
|
- iproute
|
||||||
|
- qemu-kvm
|
||||||
|
- fuse-devel
|
||||||
|
- kernel-rpm-macros
|
||||||
|
# Container tools
|
||||||
|
- podman
|
||||||
|
- buildah
|
||||||
|
- skopeo
|
||||||
|
# Gadget
|
||||||
|
- pi_gadget
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
guest:
|
||||||
|
password:
|
||||||
|
mpp-eval: guest_password
|
||||||
|
- type: org.osbuild.firewall
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- cockpit
|
||||||
|
- ssh
|
||||||
|
- type: org.osbuild.sshd.config
|
||||||
|
options:
|
||||||
|
config:
|
||||||
|
PermitRootLogin:
|
||||||
|
mpp-eval: ssh_permit_root_login
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- firewalld.service
|
||||||
|
- rngd.service
|
||||||
|
- sshd.service
|
||||||
|
- cockpit.socket
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: minimal
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
- []
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- []
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
guest:
|
||||||
|
password:
|
||||||
|
mpp-eval: guest_password
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- rngd.service
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,206 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: neptune
|
||||||
|
display_server: wayland
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
- - id: copr-neptune
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/pingou/qtappmanager-fedora/centos-stream-9-$arch/
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- - dnf
|
||||||
|
- firewalld
|
||||||
|
- gdm
|
||||||
|
- gnome-control-center
|
||||||
|
- gnome-session-xsession
|
||||||
|
- gnome-shell
|
||||||
|
- gnome-terminal
|
||||||
|
- langpacks-en
|
||||||
|
- neptune3-ui
|
||||||
|
- openssh-clients
|
||||||
|
- openssh-server
|
||||||
|
- plymouth
|
||||||
|
- polkit
|
||||||
|
- sudo
|
||||||
|
- xorg-x11-drv-fbdev
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- gnome-tour
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
guest:
|
||||||
|
password:
|
||||||
|
mpp-eval: guest_password
|
||||||
|
neptune:
|
||||||
|
password: ''
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: custom.conf
|
||||||
|
path: ../files/etc/gdm/custom-$display_server.conf
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['custom.conf']}
|
||||||
|
to: tree:///etc/gdm/custom.conf
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: init-neptune-session@.service
|
||||||
|
path: ../files/etc/systemd/system/init-neptune-session@.service
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['init-neptune-session@.service']}
|
||||||
|
to: tree:///etc/systemd/system/init-neptune-session@.service
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune-wayland.desktop
|
||||||
|
path: ../files/usr/share/wayland-sessions/neptune-wayland.desktop
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune-wayland.desktop']}
|
||||||
|
to: tree:///usr/share/wayland-sessions/neptune-wayland.desktop
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune-xorg.desktop
|
||||||
|
path: ../files/usr/share/xsessions/neptune-xorg.desktop
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune-xorg.desktop']}
|
||||||
|
to: tree:///usr/share/xsessions/neptune-xorg.desktop
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune.session
|
||||||
|
path: ../files/usr/share/gnome-session/sessions/neptune.session
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune.session']}
|
||||||
|
to: tree:///usr/share/gnome-session/sessions/neptune.session
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune-xorg.session
|
||||||
|
path: ../files/usr/share/gnome-session/sessions/neptune-xorg.session
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune-xorg.session']}
|
||||||
|
to: tree:///usr/share/gnome-session/sessions/neptune-xorg.session
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: am-config-neptune.yaml
|
||||||
|
path: ../files/usr/lib64/neptune3/am-config-neptune.yaml
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['am-config-neptune.yaml']}
|
||||||
|
to: tree:///usr/lib64/neptune3/am-config-neptune.yaml
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune3-ui.desktop
|
||||||
|
path: ../files/usr/share/applications/neptune3-ui.desktop
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune3-ui.desktop']}
|
||||||
|
to: tree:///usr/share/applications/neptune3-ui.desktop
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: neptune3-ui-xorg.desktop
|
||||||
|
path: ../files/usr/share/applications/neptune3-ui-xorg.desktop
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['neptune3-ui-xorg.desktop']}
|
||||||
|
to: tree:///usr/share/applications/neptune3-ui-xorg.desktop
|
||||||
|
- type: org.osbuild.sshd.config
|
||||||
|
options:
|
||||||
|
config:
|
||||||
|
PermitRootLogin:
|
||||||
|
mpp-eval: ssh_permit_root_login
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- firewalld.service
|
||||||
|
- rngd.service
|
||||||
|
- sshd.service
|
||||||
|
- mpp-eval: "'init-neptune-session@wayland.service' if display_server == 'wayland' else 'init-neptune-session@xorg.service'"
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: soafee
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
- - podman
|
||||||
|
- curl
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
name: upgrade-demo
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/build.ipp.yml
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
ignore-weak-deps: true
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- mpp-eval: target_repos
|
||||||
|
- mpp-eval: extra_repos
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: image_rpms
|
||||||
|
- mpp-eval: extra_rpms
|
||||||
|
# Install the watchdog tools and service files
|
||||||
|
- - autosig-sample-watchdog
|
||||||
|
- autosig-sample-staticdelta
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
# Make sure we only try a failed boot once before rollback (default is 3)
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: greenboot.conf
|
||||||
|
text: "GREENBOOT_MAX_BOOT_ATTEMPTS=1\n"
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['greenboot.conf']}
|
||||||
|
to: tree:///etc/greenboot/greenboot.conf
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- NetworkManager.service
|
||||||
|
- rngd.service
|
||||||
|
# Enable the watchdog ostree/greenboot integration
|
||||||
|
- watchdog-ostree-start.service
|
||||||
|
- watchdog-ostree-stop.service
|
||||||
|
# Work around bug for now (https://github.com/coreos/rpm-ostree/issues/3554)
|
||||||
|
- type: org.osbuild.mkdir
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- path: /var/lib/containers
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: include/image.ipp.yml
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
efiarch: aa64
|
||||||
|
boot_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: boot_rpms
|
||||||
|
- - grub2-efi-aa64
|
||||||
|
base_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- []
|
||||||
|
pipelines:
|
||||||
|
- name: build
|
||||||
|
runner: org.osbuild.centos9
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-eval: distro_repos
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: build_rpms
|
||||||
|
- mpp-eval: extra_build_rpms
|
||||||
|
- - grub2-efi-aa64
|
||||||
|
- grub2-efi-aa64-cdboot
|
||||||
|
- shim-aa64
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
labels:
|
||||||
|
/usr/bin/cp: system_u:object_r:install_exec_t:s0
|
||||||
|
/usr/bin/tar: system_u:object_r:install_exec_t:s0
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
efiarch: x64
|
||||||
|
boot_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: boot_rpms
|
||||||
|
- - grub2-efi-x64
|
||||||
|
base_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- - microcode_ctl
|
||||||
|
pipelines:
|
||||||
|
- name: build
|
||||||
|
runner: org.osbuild.centos9
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-eval: distro_repos
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: build_rpms
|
||||||
|
- mpp-eval: extra_build_rpms
|
||||||
|
- - grub2-efi-x64
|
||||||
|
- grub2-efi-x64-cdboot
|
||||||
|
- grub2-tools-efi
|
||||||
|
- shim-x64
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
labels:
|
||||||
|
/usr/bin/cp: system_u:object_r:install_exec_t:s0
|
||||||
|
/usr/bin/tar: system_u:object_r:install_exec_t:s0
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
version: '2'
|
||||||
|
|
||||||
|
mpp-vars:
|
||||||
|
distro_name: cs9 # The default
|
||||||
|
|
||||||
|
mpp-define-image:
|
||||||
|
size: $image_size
|
||||||
|
table:
|
||||||
|
uuid: $parttab_uuid
|
||||||
|
label: $partition_label
|
||||||
|
partitions:
|
||||||
|
- id: efi
|
||||||
|
start:
|
||||||
|
mpp-eval: "0 if partition_label == 'gpt' else 2048"
|
||||||
|
size: $efipart_size
|
||||||
|
type:
|
||||||
|
mpp-eval: "'C12A7328-F81F-11D2-BA4B-00A0C93EC93B' if partition_label == 'gpt' else 'ef'"
|
||||||
|
uuid: $efipart_uuid
|
||||||
|
- id: boot
|
||||||
|
size: $bootpart_size
|
||||||
|
type:
|
||||||
|
mpp-eval: "'0FC63DAF-8483-4772-8E79-3D69D8477DE4' if partition_label == 'gpt' else '83'"
|
||||||
|
uuid: $bootpart_uuid
|
||||||
|
- id: root
|
||||||
|
type:
|
||||||
|
mpp-eval: "'0FC63DAF-8483-4772-8E79-3D69D8477DE4' if partition_label == 'gpt' else '83'"
|
||||||
|
uuid: $rootpart_uuid
|
||||||
|
pipelines:
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: distro/$distro_name.ipp.yml
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: defaults.ipp.yml
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: target-$target.ipp.yml
|
||||||
|
- mpp-import-pipeline:
|
||||||
|
path: build-$arch.ipp.yml
|
||||||
|
id: build
|
||||||
|
runner: org.osbuild.centos9
|
||||||
|
|
@ -0,0 +1,315 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
default_target: qemu
|
||||||
|
default_image_type: ostree
|
||||||
|
default_ostree_ref: $distro_name/$arch/$target-$name
|
||||||
|
default_ostree_os_version: $distro_version
|
||||||
|
default_osname: centos
|
||||||
|
default_uefi_vendor: centos
|
||||||
|
default_kernel_rpm: kernel-automotive
|
||||||
|
default_linux_firmware_rpm: linux-firmware-automotive
|
||||||
|
default_partition_label: gpt
|
||||||
|
default_extra_rpms: []
|
||||||
|
default_extra_build_rpms: []
|
||||||
|
default_extra_repos: []
|
||||||
|
default_target_repos: []
|
||||||
|
default_root_password: $6$xoLqEUz0cGGJRx01$H3H/bFm0myJPULNMtbSsOFd/2BnHqHkMD92Sfxd.EKM9hXTWSmELG8cf205l6dktomuTcgKGGtGDgtvHVXSWU.
|
||||||
|
default_guest_password: $6$xoLqEUz0cGGJRx01$H3H/bFm0myJPULNMtbSsOFd/2BnHqHkMD92Sfxd.EKM9hXTWSmELG8cf205l6dktomuTcgKGGtGDgtvHVXSWU.
|
||||||
|
default_root_ssh_key: ""
|
||||||
|
default_ssh_permit_root_login: false
|
||||||
|
default_image_size: '8589934592'
|
||||||
|
default_efipart_size: 204800
|
||||||
|
default_bootpart_size: 614400
|
||||||
|
default_kernel_loglevel: 4
|
||||||
|
static_uuids:
|
||||||
|
mpp-eval: locals().get('static_uuids', True)
|
||||||
|
default_rootfs_uuid:
|
||||||
|
mpp-eval: ('76a22bf4-f153-4541-b6c7-0332c0dfaeac' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_bootfs_uuid:
|
||||||
|
mpp-eval: ('156f0420-627b-4151-ae6f-fda298097515' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_parttab_uuid:
|
||||||
|
mpp-eval: ('d209c89e-ea5e-4fbd-b161-b461cce297e0' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_efipart_uuid:
|
||||||
|
mpp-eval: ('68b2905b-df3e-4fb3-80fa-49d1e773aa33' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_bootpart_uuid:
|
||||||
|
mpp-eval: ('61b2905b-df3e-4fb3-80fa-49d1e773aa32' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_rootpart_uuid:
|
||||||
|
mpp-eval: ('6264d520-3fb9-423f-8ab8-7a0a8e3d3562' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_luks_uuid:
|
||||||
|
mpp-eval: ('aedd1eef-f24e-425e-a9f3-bb5a1c996a95' if static_uuids else str(__import__('uuid').uuid4()))
|
||||||
|
default_use_luks: false
|
||||||
|
use_luks:
|
||||||
|
mpp-eval: locals().get('use_luks', default_use_luks)
|
||||||
|
default_luks_use_integrity: false
|
||||||
|
default_luks_auto_unlock: false
|
||||||
|
luks_auto_unlock:
|
||||||
|
mpp-eval: locals().get('luks_auto_unlock', default_luks_auto_unlock)
|
||||||
|
default_use_efi_runtime: true
|
||||||
|
default_kernel_opts:
|
||||||
|
- console=tty0
|
||||||
|
- console=ttyS0
|
||||||
|
- systemd.log_target=console
|
||||||
|
- systemd.journald.forward_to_console=1
|
||||||
|
default_dracut_add_modules:
|
||||||
|
- base
|
||||||
|
- bash
|
||||||
|
- dracut-systemd
|
||||||
|
- fs-lib
|
||||||
|
- i18n
|
||||||
|
- kernel-modules
|
||||||
|
- kernel-modules-extra
|
||||||
|
- rootfs-block
|
||||||
|
- shutdown
|
||||||
|
- systemd
|
||||||
|
- systemd-initrd
|
||||||
|
- terminfo
|
||||||
|
- udev-rules
|
||||||
|
- usrmount
|
||||||
|
default_dracut_omit_modules:
|
||||||
|
- mpp-if: not use_luks
|
||||||
|
then: dm
|
||||||
|
- lunmask
|
||||||
|
- mdraid
|
||||||
|
- memstrack
|
||||||
|
- nss-softokn
|
||||||
|
- nvdimm
|
||||||
|
- resume
|
||||||
|
- terminfo
|
||||||
|
default_dracut_filesystems:
|
||||||
|
- vfat
|
||||||
|
- ext4
|
||||||
|
default_dracut_add_drivers: []
|
||||||
|
default_dracut_install: []
|
||||||
|
default_ostree_repo_url: http://10.0.2.100/
|
||||||
|
default_ostree_remote_name: auto-sig
|
||||||
|
default_luks_passphrase: password
|
||||||
|
target:
|
||||||
|
mpp-eval: locals().get('target', default_target)
|
||||||
|
image_type:
|
||||||
|
mpp-eval: locals().get('image_type', default_image_type)
|
||||||
|
kernel_rpm:
|
||||||
|
mpp-eval: locals().get('kernel_rpm', default_kernel_rpm)
|
||||||
|
linux_firmware_rpm:
|
||||||
|
mpp-eval: locals().get('linux_firmware_rpm', default_linux_firmware_rpm)
|
||||||
|
ostree_ref:
|
||||||
|
mpp-eval: locals().get('ostree_ref', default_ostree_ref)
|
||||||
|
ostree_os_version:
|
||||||
|
mpp-eval: locals().get('ostree_os_version', default_ostree_os_version)
|
||||||
|
osname:
|
||||||
|
mpp-eval: locals().get('osname', default_osname)
|
||||||
|
uefi_vendor:
|
||||||
|
mpp-eval: locals().get('uefi_vendor', default_uefi_vendor)
|
||||||
|
partition_label:
|
||||||
|
mpp-eval: locals().get('partition_label', default_partition_label)
|
||||||
|
extra_rpms:
|
||||||
|
mpp-eval: locals().get('extra_rpms', default_extra_rpms)
|
||||||
|
extra_build_rpms:
|
||||||
|
mpp-eval: locals().get('extra_build_rpms', default_extra_build_rpms)
|
||||||
|
extra_repos:
|
||||||
|
mpp-eval: locals().get('extra_repos', default_extra_repos)
|
||||||
|
target_repos:
|
||||||
|
mpp-eval: locals().get('target_repos', default_target_repos)
|
||||||
|
image_size:
|
||||||
|
mpp-eval: locals().get('image_size', default_image_size)
|
||||||
|
rootfs_uuid:
|
||||||
|
mpp-eval: locals().get('rootfs_uuid', default_rootfs_uuid)
|
||||||
|
bootfs_uuid:
|
||||||
|
mpp-eval: locals().get('bootfs_uuid', default_bootfs_uuid)
|
||||||
|
parttab_uuid:
|
||||||
|
mpp-eval: locals().get('parttab_uuid', default_parttab_uuid)
|
||||||
|
rootpart_uuid:
|
||||||
|
mpp-eval: locals().get('rootpart_uuid', default_rootpart_uuid)
|
||||||
|
bootpart_uuid:
|
||||||
|
mpp-eval: locals().get('bootpart_uuid', default_bootpart_uuid)
|
||||||
|
efipart_uuid:
|
||||||
|
mpp-eval: locals().get('efipart_uuid', default_efipart_uuid)
|
||||||
|
luks_uuid:
|
||||||
|
mpp-eval: locals().get('luks_uuid', default_luks_uuid)
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: locals().get('kernel_opts', default_kernel_opts)
|
||||||
|
efipart_size:
|
||||||
|
mpp-eval: locals().get('efipart_size', default_efipart_size)
|
||||||
|
bootpart_size:
|
||||||
|
mpp-eval: locals().get('bootpart_size', default_bootpart_size)
|
||||||
|
dracut_add_modules:
|
||||||
|
mpp-eval: locals().get('dracut_add_modules', default_dracut_add_modules)
|
||||||
|
dracut_omit_modules:
|
||||||
|
mpp-eval: locals().get('dracut_omit_modules', default_dracut_omit_modules)
|
||||||
|
dracut_filesystems:
|
||||||
|
mpp-eval: locals().get('dracut_filesystems', default_dracut_filesystems)
|
||||||
|
dracut_add_drivers:
|
||||||
|
mpp-eval: locals().get('dracut_add_drivers', default_dracut_add_drivers)
|
||||||
|
dracut_install:
|
||||||
|
mpp-eval: locals().get('dracut_install', default_dracut_install)
|
||||||
|
root_password:
|
||||||
|
mpp-eval: locals().get('root_password', default_root_password)
|
||||||
|
root_ssh_key:
|
||||||
|
mpp-eval: locals().get('root_ssh_key', default_root_ssh_key)
|
||||||
|
ssh_permit_root_login:
|
||||||
|
mpp-eval: locals().get('ssh_permit_root_login', default_ssh_permit_root_login)
|
||||||
|
guest_password:
|
||||||
|
mpp-eval: locals().get('guest_password', default_guest_password)
|
||||||
|
ostree_repo_url:
|
||||||
|
mpp-eval: locals().get('ostree_repo_url', default_ostree_repo_url)
|
||||||
|
ostree_remote_name:
|
||||||
|
mpp-eval: locals().get('ostree_remote_name', default_ostree_remote_name)
|
||||||
|
luks_passphrase:
|
||||||
|
mpp-eval: locals().get('luks_passphrase', default_luks_passphrase)
|
||||||
|
luks_use_integrity:
|
||||||
|
mpp-eval: locals().get('luks_use_integrity', default_luks_use_integrity)
|
||||||
|
use_efi_runtime:
|
||||||
|
mpp-eval: locals().get('use_efi_runtime', default_use_efi_runtime)
|
||||||
|
kernel_loglevel:
|
||||||
|
mpp-eval: locals().get('kernel_loglevel', default_kernel_loglevel)
|
||||||
|
default_target_stages: []
|
||||||
|
target_stages:
|
||||||
|
mpp-eval: locals().get('target_stages', default_target_stages)
|
||||||
|
centos_gpg_key: |
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||||
|
|
||||||
|
mQINBFzMWxkBEADHrskpBgN9OphmhRkc7P/YrsAGSvvl7kfu+e9KAaU6f5MeAVyn
|
||||||
|
rIoM43syyGkgFyWgjZM8/rur7EMPY2yt+2q/1ZfLVCRn9856JqTIq0XRpDUe4nKQ
|
||||||
|
8BlA7wDVZoSDxUZkSuTIyExbDf0cpw89Tcf62Mxmi8jh74vRlPy1PgjWL5494b3X
|
||||||
|
5fxDidH4bqPZyxTBqPrUFuo+EfUVEqiGF94Ppq6ZUvrBGOVo1V1+Ifm9CGEK597c
|
||||||
|
aevcGc1RFlgxIgN84UpuDjPR9/zSndwJ7XsXYvZ6HXcKGagRKsfYDWGPkA5cOL/e
|
||||||
|
f+yObOnC43yPUvpggQ4KaNJ6+SMTZOKikM8yciyBwLqwrjo8FlJgkv8Vfag/2UR7
|
||||||
|
JINbyqHHoLUhQ2m6HXSwK4YjtwidF9EUkaBZWrrskYR3IRZLXlWqeOi/+ezYOW0m
|
||||||
|
vufrkcvsh+TKlVVnuwmEPjJ8mwUSpsLdfPJo1DHsd8FS03SCKPaXFdD7ePfEjiYk
|
||||||
|
nHpQaKE01aWVSLUiygn7F7rYemGqV9Vt7tBw5pz0vqSC72a5E3zFzIIuHx6aANry
|
||||||
|
Gat3aqU3qtBXOrA/dPkX9cWE+UR5wo/A2UdKJZLlGhM2WRJ3ltmGT48V9CeS6N9Y
|
||||||
|
m4CKdzvg7EWjlTlFrd/8WJ2KoqOE9leDPeXRPncubJfJ6LLIHyG09h9kKQARAQAB
|
||||||
|
tDpDZW50T1MgKENlbnRPUyBPZmZpY2lhbCBTaWduaW5nIEtleSkgPHNlY3VyaXR5
|
||||||
|
QGNlbnRvcy5vcmc+iQI3BBMBAgAhBQJczFsZAhsDBgsJCAcDAgYVCAIJCgsDFgIB
|
||||||
|
Ah4BAheAAAoJEAW1VbOEg8ZdjOsP/2ygSxH9jqffOU9SKyJDlraL2gIutqZ3B8pl
|
||||||
|
Gy/Qnb9QD1EJVb4ZxOEhcY2W9VJfIpnf3yBuAto7zvKe/G1nxH4Bt6WTJQCkUjcs
|
||||||
|
N3qPWsx1VslsAEz7bXGiHym6Ay4xF28bQ9XYIokIQXd0T2rD3/lNGxNtORZ2bKjD
|
||||||
|
vOzYzvh2idUIY1DgGWJ11gtHFIA9CvHcW+SMPEhkcKZJAO51ayFBqTSSpiorVwTq
|
||||||
|
a0cB+cgmCQOI4/MY+kIvzoexfG7xhkUqe0wxmph9RQQxlTbNQDCdaxSgwbF2T+gw
|
||||||
|
byaDvkS4xtR6Soj7BKjKAmcnf5fn4C5Or0KLUqMzBtDMbfQQihn62iZJN6ZZ/4dg
|
||||||
|
q4HTqyVpyuzMXsFpJ9L/FqH2DJ4exGGpBv00ba/Zauy7GsqOc5PnNBsYaHCply0X
|
||||||
|
407DRx51t9YwYI/ttValuehq9+gRJpOTTKp6AjZn/a5Yt3h6jDgpNfM/EyLFIY9z
|
||||||
|
V6CXqQQ/8JRvaik/JsGCf+eeLZOw4koIjZGEAg04iuyNTjhx0e/QHEVcYAqNLhXG
|
||||||
|
rCTTbCn3NSUO9qxEXC+K/1m1kaXoCGA0UWlVGZ1JSifbbMx0yxq/brpEZPUYm+32
|
||||||
|
o8XfbocBWljFUJ+6aljTvZ3LQLKTSPW7TFO+GXycAOmCGhlXh2tlc6iTc41PACqy
|
||||||
|
yy+mHmSv
|
||||||
|
=kkH7
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
redhat_gpg_key: |
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQINBErgSTsBEACh2A4b0O9t+vzC9VrVtL1AKvUWi9OPCjkvR7Xd8DtJxeeMZ5eF
|
||||||
|
0HtzIG58qDRybwUe89FZprB1ffuUKzdE+HcL3FbNWSSOXVjZIersdXyH3NvnLLLF
|
||||||
|
0DNRB2ix3bXG9Rh/RXpFsNxDp2CEMdUvbYCzE79K1EnUTVh1L0Of023FtPSZXX0c
|
||||||
|
u7Pb5DI5lX5YeoXO6RoodrIGYJsVBQWnrWw4xNTconUfNPk0EGZtEnzvH2zyPoJh
|
||||||
|
XGF+Ncu9XwbalnYde10OCvSWAZ5zTCpoLMTvQjWpbCdWXJzCm6G+/hx9upke546H
|
||||||
|
5IjtYm4dTIVTnc3wvDiODgBKRzOl9rEOCIgOuGtDxRxcQkjrC+xvg5Vkqn7vBUyW
|
||||||
|
9pHedOU+PoF3DGOM+dqv+eNKBvh9YF9ugFAQBkcG7viZgvGEMGGUpzNgN7XnS1gj
|
||||||
|
/DPo9mZESOYnKceve2tIC87p2hqjrxOHuI7fkZYeNIcAoa83rBltFXaBDYhWAKS1
|
||||||
|
PcXS1/7JzP0ky7d0L6Xbu/If5kqWQpKwUInXtySRkuraVfuK3Bpa+X1XecWi24JY
|
||||||
|
HVtlNX025xx1ewVzGNCTlWn1skQN2OOoQTV4C8/qFpTW6DTWYurd4+fE0OJFJZQF
|
||||||
|
buhfXYwmRlVOgN5i77NTIJZJQfYFj38c/Iv5vZBPokO6mffrOTv3MHWVgQARAQAB
|
||||||
|
tDNSZWQgSGF0LCBJbmMuIChyZWxlYXNlIGtleSAyKSA8c2VjdXJpdHlAcmVkaGF0
|
||||||
|
LmNvbT6JAjYEEwECACAFAkrgSTsCGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAK
|
||||||
|
CRAZni+R/UMdUWzpD/9s5SFR/ZF3yjY5VLUFLMXIKUztNN3oc45fyLdTI3+UClKC
|
||||||
|
2tEruzYjqNHhqAEXa2sN1fMrsuKec61Ll2NfvJjkLKDvgVIh7kM7aslNYVOP6BTf
|
||||||
|
C/JJ7/ufz3UZmyViH/WDl+AYdgk3JqCIO5w5ryrC9IyBzYv2m0HqYbWfphY3uHw5
|
||||||
|
un3ndLJcu8+BGP5F+ONQEGl+DRH58Il9Jp3HwbRa7dvkPgEhfFR+1hI+Btta2C7E
|
||||||
|
0/2NKzCxZw7Lx3PBRcU92YKyaEihfy/aQKZCAuyfKiMvsmzs+4poIX7I9NQCJpyE
|
||||||
|
IGfINoZ7VxqHwRn/d5mw2MZTJjbzSf+Um9YJyA0iEEyD6qjriWQRbuxpQXmlAJbh
|
||||||
|
8okZ4gbVFv1F8MzK+4R8VvWJ0XxgtikSo72fHjwha7MAjqFnOq6eo6fEC/75g3NL
|
||||||
|
Ght5VdpGuHk0vbdENHMC8wS99e5qXGNDued3hlTavDMlEAHl34q2H9nakTGRF5Ki
|
||||||
|
JUfNh3DVRGhg8cMIti21njiRh7gyFI2OccATY7bBSr79JhuNwelHuxLrCFpY7V25
|
||||||
|
OFktl15jZJaMxuQBqYdBgSay2G0U6D1+7VsWufpzd/Abx1/c3oi9ZaJvW22kAggq
|
||||||
|
dzdA27UUYjWvx42w9menJwh/0jeQcTecIUd0d0rFcw/c1pvgMMl/Q73yzKgKYw==
|
||||||
|
=zbHE
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
mQINBFsy23UBEACUKSphFEIEvNpy68VeW4Dt6qv+mU6am9a2AAl10JANLj1oqWX+
|
||||||
|
oYk3en1S6cVe2qehSL5DGVa3HMUZkP3dtbD4SgzXzxPodebPcr4+0QNWigkUisri
|
||||||
|
XGL5SCEcOP30zDhZvg+4mpO2jMi7Kc1DLPzBBkgppcX91wa0L1pQzBcvYMPyV/Dh
|
||||||
|
KbQHR75WdkP6OA2JXdfC94nxYq+2e0iPqC1hCP3Elh+YnSkOkrawDPmoB1g4+ft/
|
||||||
|
xsiVGVy/W0ekXmgvYEHt6si6Y8NwXgnTMqxeSXQ9YUgVIbTpsxHQKGy76T5lMlWX
|
||||||
|
4LCOmEVomBJg1SqF6yi9Vu8TeNThaDqT4/DddYInd0OO69s0kGIXalVgGYiW2HOD
|
||||||
|
x2q5R1VGCoJxXomz+EbOXY+HpKPOHAjU0DB9MxbU3S248LQ69nIB5uxysy0PSco1
|
||||||
|
sdZ8sxRNQ9Dw6on0Nowx5m6Thefzs5iK3dnPGBqHTT43DHbnWc2scjQFG+eZhe98
|
||||||
|
Ell/kb6vpBoY4bG9/wCG9qu7jj9Z+BceCNKeHllbezVLCU/Hswivr7h2dnaEFvPD
|
||||||
|
O4GqiWiwOF06XaBMVgxA8p2HRw0KtXqOpZk+o+sUvdPjsBw42BB96A1yFX4jgFNA
|
||||||
|
PyZYnEUdP6OOv9HSjnl7k/iEkvHq/jGYMMojixlvXpGXhnt5jNyc4GSUJQARAQAB
|
||||||
|
tDNSZWQgSGF0LCBJbmMuIChhdXhpbGlhcnkga2V5KSA8c2VjdXJpdHlAcmVkaGF0
|
||||||
|
LmNvbT6JAjkEEwECACMFAlsy23UCGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIX
|
||||||
|
gAAKCRD3b2bD1AgnknqOD/9fB2ASuG2aJIiap4kK58R+RmOVM4qgclAnaG57+vjI
|
||||||
|
nKvyfV3NH/keplGNRxwqHekfPCqvkpABwhdGEXIE8ILqnPewIMr6PZNZWNJynZ9i
|
||||||
|
eSMzVuCG7jDoGyQ5/6B0f6xeBtTeBDiRl7+Alehet1twuGL1BJUYG0QuLgcEzkaE
|
||||||
|
/gkuumeVcazLzz7L12D22nMk66GxmgXfqS5zcbqOAuZwaA6VgSEgFdV2X2JU79zS
|
||||||
|
BQJXv7NKc+nDXFG7M7EHjY3Rma3HXkDbkT8bzh9tJV7Z7TlpT829pStWQyoxKCVq
|
||||||
|
sEX8WsSapTKA3P9YkYCwLShgZu4HKRFvHMaIasSIZWzLu+RZH/4yyHOhj0QB7XMY
|
||||||
|
eHQ6fGSbtJ+K6SrpHOOsKQNAJ0hVbSrnA1cr5+2SDfel1RfYt0W9FA6DoH/S5gAR
|
||||||
|
dzT1u44QVwwp3U+eFpHphFy//uzxNMtCjjdkpzhYYhOCLNkDrlRPb+bcoL/6ePSr
|
||||||
|
016PA7eEnuC305YU1Ml2WcCn7wQV8x90o33klJmEkWtXh3X39vYtI4nCPIvZn1eP
|
||||||
|
Vy+F+wWt4vN2b8oOdlzc2paOembbCo2B+Wapv5Y9peBvlbsDSgqtJABfK8KQq/jK
|
||||||
|
Yl3h5elIa1I3uNfczeHOnf1enLOUOlq630yeM/yHizz99G1g+z/guMh5+x/OHraW
|
||||||
|
iA==
|
||||||
|
=+Gxh
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
fstab:
|
||||||
|
- uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
vfs_type: ext4
|
||||||
|
path: /
|
||||||
|
freq: 1
|
||||||
|
passno: 1
|
||||||
|
- label: ESP
|
||||||
|
vfs_type: vfat
|
||||||
|
path: /boot/efi
|
||||||
|
freq: 1
|
||||||
|
passno: 1
|
||||||
|
- uuid:
|
||||||
|
mpp-eval: bootfs_uuid
|
||||||
|
vfs_type: ext4
|
||||||
|
path: /boot
|
||||||
|
freq: 1
|
||||||
|
passno: 1
|
||||||
|
build_rpms:
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then: cryptsetup
|
||||||
|
- dnf
|
||||||
|
- dosfstools
|
||||||
|
- e2fsprogs
|
||||||
|
- efibootmgr
|
||||||
|
- grub2-tools
|
||||||
|
- grub2-tools-minimal
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then: lvm2
|
||||||
|
- policycoreutils
|
||||||
|
- python3-iniparse
|
||||||
|
- python3
|
||||||
|
- qemu-img
|
||||||
|
- rpm-ostree
|
||||||
|
- selinux-policy-targeted
|
||||||
|
- skopeo
|
||||||
|
- systemd
|
||||||
|
- tar
|
||||||
|
- xz
|
||||||
|
boot_rpms:
|
||||||
|
- dracut-config-generic
|
||||||
|
- grub2-tools-minimal
|
||||||
|
- $kernel_rpm
|
||||||
|
base_rpms:
|
||||||
|
- $linux_firmware_rpm
|
||||||
|
- NetworkManager
|
||||||
|
- audit
|
||||||
|
- chrony
|
||||||
|
- e2fsprogs
|
||||||
|
- efibootmgr
|
||||||
|
- glibc-langpack-en
|
||||||
|
- hostname
|
||||||
|
- passwd
|
||||||
|
- rng-tools
|
||||||
|
- rootfiles
|
||||||
|
- selinux-policy-targeted
|
||||||
|
- systemd-udev
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then: lvm2
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
image_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: locals().get('extra_image_rpms', [])
|
||||||
|
- []
|
||||||
|
pipelines:
|
||||||
|
- name: kernel-tree
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.kernel-cmdline
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
- mpp-eval: redhat_gpg_key
|
||||||
|
disable_dracut: true
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
module-platform-id: $distro_module_id
|
||||||
|
baseurl: $distro_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: distro_repos
|
||||||
|
- - id: cs9-shim
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/alexl/cs9-shim/fedora-35-$arch/
|
||||||
|
packages:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: base_rpms
|
||||||
|
- mpp-eval: boot_rpms
|
||||||
|
- mpp-eval: locals().get('extra_boot_rpms', [])
|
||||||
|
- - shim-unsigned-$efiarch
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.mkdir
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- path: /boot/efi/EFI/Linux
|
||||||
|
parents: true
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
bootcsv:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: directboot.csv
|
||||||
|
path: directboot.csv
|
||||||
|
extra-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:extra-tree-content
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from:
|
||||||
|
mpp-format-string: input://bootcsv/{embedded['directboot.csv']}
|
||||||
|
to: tree:///boot/efi/EFI/Linux/boot.csv
|
||||||
|
- mpp-eval: extra_tree_content
|
||||||
|
- type: org.osbuild.dracut
|
||||||
|
options:
|
||||||
|
kernel:
|
||||||
|
- mpp-eval: rpms['kernel-tree'][kernel_rpm + '-core'].evra
|
||||||
|
add_modules:
|
||||||
|
mpp-eval: dracut_add_modules
|
||||||
|
omit_modules:
|
||||||
|
mpp-eval: dracut_omit_modules
|
||||||
|
add_drivers:
|
||||||
|
mpp-eval: dracut_add_drivers
|
||||||
|
filesystems:
|
||||||
|
mpp-eval: dracut_filesystems
|
||||||
|
install:
|
||||||
|
mpp-eval: dracut_install
|
||||||
|
extra:
|
||||||
|
- /boot/efi/EFI/Linux/initramfs.img
|
||||||
|
- --kernel-cmdline
|
||||||
|
- mpp-format-string: root=UUID={rootfs_uuid} {' ' .join(kernel_opts)}
|
||||||
|
- name: image-tree
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
mpp-join:
|
||||||
|
- - type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
extra-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:extra-tree-content
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from: input://tree/
|
||||||
|
to: tree:///
|
||||||
|
- mpp-eval: extra_tree_content
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
kernel:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:kernel-tree
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from: input://kernel/lib/modules
|
||||||
|
to: tree:///lib/
|
||||||
|
- from: input://kernel/boot/efi/EFI/BOOT
|
||||||
|
to: tree:////boot/efi/EFI/
|
||||||
|
- from: input://kernel/boot/efi/EFI/Linux
|
||||||
|
to: tree:////boot/efi/EFI/
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
kernel:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:kernel-tree
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from: input://kernel/lib/modules
|
||||||
|
to: tree:///lib/
|
||||||
|
- from: input://kernel/boot/efi/EFI/BOOT
|
||||||
|
to: tree:////boot/efi/EFI/
|
||||||
|
- from: input://kernel/boot/efi/EFI/Linux
|
||||||
|
to: tree:////boot/efi/EFI/
|
||||||
|
- mpp-if: arch == 'aarch64'
|
||||||
|
then:
|
||||||
|
type: org.osbuild.gunzip
|
||||||
|
inputs:
|
||||||
|
file:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
name:kernel-tree:
|
||||||
|
file:
|
||||||
|
mpp-format-string: boot/vmlinuz-{rpms['kernel-tree'][kernel_rpm + '-core'].evra}
|
||||||
|
options:
|
||||||
|
path: /boot/efi/EFI/Linux/linux.efi
|
||||||
|
else:
|
||||||
|
type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
kernel:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:kernel-tree
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://kernel/boot/vmlinuz-{rpms['kernel-tree'][kernel_rpm + '-core'].evra}
|
||||||
|
to: tree:///boot/efi/EFI/Linux/linux.efi
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
root:
|
||||||
|
password:
|
||||||
|
mpp-eval: root_password
|
||||||
|
key:
|
||||||
|
mpp-eval: root_ssh_key
|
||||||
|
- mpp-eval: target_stages
|
||||||
|
- - type: org.osbuild.fstab
|
||||||
|
options:
|
||||||
|
filesystems:
|
||||||
|
mpp-eval: fstab
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
image_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: locals().get('extra_image_rpms', [])
|
||||||
|
- mpp-eval: boot_rpms
|
||||||
|
- mpp-eval: locals().get('extra_boot_rpms', [])
|
||||||
|
- - nss-altfiles
|
||||||
|
- greenboot
|
||||||
|
- greenboot-grub2
|
||||||
|
- greenboot-reboot
|
||||||
|
- greenboot-status
|
||||||
|
- greenboot-rpm-ostree-grub2
|
||||||
|
- polkit # Needed by rpm-ostree upgrade (until fix for https://github.com/coreos/rpm-ostree/issues/3554 is in)
|
||||||
|
pipelines:
|
||||||
|
- name: ostree-tree
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
mpp-join:
|
||||||
|
- - type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
extra-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:extra-tree-content
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from: input://tree/
|
||||||
|
to: tree:///
|
||||||
|
- mpp-eval: extra_tree_content
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- greenboot-grub2-set-counter.service
|
||||||
|
- greenboot-grub2-set-success.service
|
||||||
|
- greenboot-healthcheck.service
|
||||||
|
- greenboot-rpm-ostree-grub2-check-fallback.service
|
||||||
|
- greenboot-status.service
|
||||||
|
- greenboot-task-runner.service
|
||||||
|
- mpp-eval: target_stages
|
||||||
|
- - type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
- type: org.osbuild.ostree.preptree
|
||||||
|
options:
|
||||||
|
etc_group_members:
|
||||||
|
- wheel
|
||||||
|
- docker
|
||||||
|
initramfs-args:
|
||||||
|
- mpp-if: dracut_add_modules
|
||||||
|
then: "--add"
|
||||||
|
- mpp-if: dracut_add_modules
|
||||||
|
then:
|
||||||
|
mpp-eval: "' '.join(dracut_add_modules)"
|
||||||
|
- mpp-if: dracut_omit_modules
|
||||||
|
then: "--omit"
|
||||||
|
- mpp-if: dracut_omit_modules
|
||||||
|
then:
|
||||||
|
mpp-eval: "' '.join(dracut_omit_modules)"
|
||||||
|
- mpp-if: dracut_filesystems
|
||||||
|
then: "--filesystems"
|
||||||
|
- mpp-if: dracut_filesystems
|
||||||
|
then:
|
||||||
|
mpp-eval: "' '.join(dracut_filesystems)"
|
||||||
|
- mpp-if: dracut_add_drivers
|
||||||
|
then: "--add-drivers"
|
||||||
|
- mpp-if: dracut_add_drivers
|
||||||
|
then:
|
||||||
|
mpp-eval: "' '.join(dracut_add_drivers)"
|
||||||
|
- mpp-if: dracut_install
|
||||||
|
then: "--install"
|
||||||
|
- mpp-if: dracut_install
|
||||||
|
then:
|
||||||
|
mpp-eval: "' '.join(dracut_install)"
|
||||||
|
- name: ostree-commit
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.ostree.init
|
||||||
|
options:
|
||||||
|
path: /repo
|
||||||
|
- type: org.osbuild.ostree.commit
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:ostree-tree
|
||||||
|
options:
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
os_version:
|
||||||
|
mpp-eval: ostree_os_version
|
||||||
|
parent:
|
||||||
|
mpp-if: ostree_ref in locals().get("ostree_parent_refs", {})
|
||||||
|
then:
|
||||||
|
mpp-eval: ostree_parent_refs[ostree_ref]
|
||||||
|
- name: image-tree
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.ostree.init-fs
|
||||||
|
- type: org.osbuild.ostree.pull
|
||||||
|
options:
|
||||||
|
repo: /ostree/repo
|
||||||
|
remote:
|
||||||
|
mpp-eval: ostree_remote_name
|
||||||
|
inputs:
|
||||||
|
commits:
|
||||||
|
type: org.osbuild.ostree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
name:ostree-commit:
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
- type: org.osbuild.ostree.os-init
|
||||||
|
options:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
- type: org.osbuild.ostree.config
|
||||||
|
options:
|
||||||
|
repo: /ostree/repo
|
||||||
|
config:
|
||||||
|
sysroot:
|
||||||
|
readonly: true
|
||||||
|
bootloader: none
|
||||||
|
- type: org.osbuild.ostree.remotes
|
||||||
|
options:
|
||||||
|
repo: /ostree/repo
|
||||||
|
remotes:
|
||||||
|
- name:
|
||||||
|
mpp-eval: ostree_remote_name
|
||||||
|
url:
|
||||||
|
mpp-eval: ostree_repo_url
|
||||||
|
- type: org.osbuild.mkdir
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- path: /boot/efi
|
||||||
|
mode: 448
|
||||||
|
- type: org.osbuild.ostree.deploy
|
||||||
|
options:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
remote:
|
||||||
|
mpp-eval: ostree_remote_name
|
||||||
|
mounts:
|
||||||
|
- /boot
|
||||||
|
- /boot/efi
|
||||||
|
rootfs:
|
||||||
|
label: root
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: kernel_opts
|
||||||
|
- type: org.osbuild.ostree.fillvar
|
||||||
|
options:
|
||||||
|
deployment:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
- type: org.osbuild.users
|
||||||
|
mounts:
|
||||||
|
- type: org.osbuild.ostree.deployment
|
||||||
|
name: ostree.deployment
|
||||||
|
options:
|
||||||
|
deployment:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
root:
|
||||||
|
password:
|
||||||
|
mpp-eval: root_password
|
||||||
|
key:
|
||||||
|
mpp-eval: root_ssh_key
|
||||||
|
- type: org.osbuild.fstab
|
||||||
|
options:
|
||||||
|
ostree:
|
||||||
|
deployment:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
filesystems:
|
||||||
|
mpp-eval: fstab
|
||||||
|
- type: org.osbuild.ostree.selinux
|
||||||
|
options:
|
||||||
|
deployment:
|
||||||
|
osname:
|
||||||
|
mpp-eval: osname
|
||||||
|
ref:
|
||||||
|
mpp-eval: ostree_ref
|
||||||
|
- type: org.osbuild.grub2
|
||||||
|
options:
|
||||||
|
rootfs:
|
||||||
|
label: root
|
||||||
|
bootfs:
|
||||||
|
label: boot
|
||||||
|
uefi:
|
||||||
|
vendor:
|
||||||
|
mpp-eval: uefi_vendor
|
||||||
|
unified: true
|
||||||
|
install: true
|
||||||
|
legacy: false
|
||||||
|
write_defaults: false
|
||||||
|
greenboot: true
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
image_rpms:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: locals().get('extra_image_rpms', [])
|
||||||
|
- mpp-eval: boot_rpms
|
||||||
|
- mpp-eval: locals().get('extra_boot_rpms', [])
|
||||||
|
- - shim
|
||||||
|
pipelines:
|
||||||
|
- name: image-tree
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
mpp-join:
|
||||||
|
- - type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
extra-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:extra-tree-content
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from: input://tree/
|
||||||
|
to: tree:///
|
||||||
|
- mpp-eval: extra_tree_content
|
||||||
|
- type: org.osbuild.users
|
||||||
|
options:
|
||||||
|
users:
|
||||||
|
root:
|
||||||
|
password:
|
||||||
|
mpp-eval: root_password
|
||||||
|
key:
|
||||||
|
mpp-eval: root_ssh_key
|
||||||
|
- mpp-eval: target_stages
|
||||||
|
- - type: org.osbuild.dracut
|
||||||
|
options:
|
||||||
|
kernel:
|
||||||
|
- mpp-eval: rpms['rootfs'][kernel_rpm + '-core'].evra
|
||||||
|
add_modules:
|
||||||
|
mpp-eval: dracut_add_modules
|
||||||
|
omit_modules:
|
||||||
|
mpp-eval: dracut_omit_modules
|
||||||
|
add_drivers:
|
||||||
|
mpp-eval: dracut_add_drivers
|
||||||
|
filesystems:
|
||||||
|
mpp-eval: dracut_filesystems
|
||||||
|
install:
|
||||||
|
mpp-eval: dracut_install
|
||||||
|
- type: org.osbuild.fstab
|
||||||
|
options:
|
||||||
|
filesystems:
|
||||||
|
mpp-eval: fstab
|
||||||
|
- type: org.osbuild.grub2
|
||||||
|
options:
|
||||||
|
root_fs_uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
boot_fs_uuid:
|
||||||
|
mpp-eval: bootfs_uuid
|
||||||
|
kernel_opts:
|
||||||
|
mpp-eval: ''' '' .join(kernel_opts)'
|
||||||
|
uefi:
|
||||||
|
vendor:
|
||||||
|
mpp-eval: uefi_vendor
|
||||||
|
unified: true
|
||||||
|
legacy: false
|
||||||
|
write_defaults: false
|
||||||
|
greenboot: true
|
||||||
|
- type: org.osbuild.fix-bls
|
||||||
|
options:
|
||||||
|
prefix: /
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
|
@ -0,0 +1,413 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
extra_tree_content:
|
||||||
|
- mpp-if: use_luks and luks_auto_unlock
|
||||||
|
then:
|
||||||
|
from: input://extra-tree/luks-key
|
||||||
|
to: tree:///usr/.auto-unlock-key
|
||||||
|
dracut_install:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: dracut_install
|
||||||
|
- mpp-if: use_luks and luks_auto_unlock
|
||||||
|
then:
|
||||||
|
- /usr/.auto-unlock-key
|
||||||
|
kernel_opts:
|
||||||
|
mpp-join:
|
||||||
|
- - ro
|
||||||
|
- loglevel=$kernel_loglevel
|
||||||
|
- mpp-if: use_efi_runtime
|
||||||
|
then: efi=runtime
|
||||||
|
- mpp-eval: kernel_opts
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
- rd.luks.uuid=$luks_uuid
|
||||||
|
- rd.luks.options=discard
|
||||||
|
- mpp-if: luks_auto_unlock
|
||||||
|
then: rd.luks.key=$luks_uuid=/usr/.auto-unlock-key
|
||||||
|
pipelines:
|
||||||
|
# Some variables need to be written to files, do that here
|
||||||
|
- name: extra-tree-content
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: luks-key
|
||||||
|
text: $luks_passphrase
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['luks-key']}
|
||||||
|
to: tree:///luks-key
|
||||||
|
- mpp-import-pipelines:
|
||||||
|
path: image-$image_type.ipp.yml
|
||||||
|
- name: image
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.truncate
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
size:
|
||||||
|
mpp-eval: image.size
|
||||||
|
- type: org.osbuild.sfdisk
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
options:
|
||||||
|
mpp-format-json: '{image.layout}'
|
||||||
|
- type: org.osbuild.mkfs.fat
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['efi'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['efi'].size
|
||||||
|
options:
|
||||||
|
label: ESP
|
||||||
|
volid: 7B7795E7
|
||||||
|
- type: org.osbuild.mkfs.ext4
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['boot'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['boot'].size
|
||||||
|
options:
|
||||||
|
uuid:
|
||||||
|
mpp-eval: bootfs_uuid
|
||||||
|
label: boot
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.luks2.format
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
lock: true
|
||||||
|
options:
|
||||||
|
passphrase:
|
||||||
|
mpp-eval: luks_passphrase
|
||||||
|
uuid:
|
||||||
|
mpp-eval: luks_uuid
|
||||||
|
label: luks-rootfs
|
||||||
|
pbkdf:
|
||||||
|
method: argon2i
|
||||||
|
memory: 32
|
||||||
|
parallelism: 1
|
||||||
|
iterations: 4
|
||||||
|
integrity:
|
||||||
|
mpp-if: luks_use_integrity
|
||||||
|
then: hmac-sha256
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.lvm2.create
|
||||||
|
devices:
|
||||||
|
luks:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
device:
|
||||||
|
type: org.osbuild.luks2
|
||||||
|
parent: luks
|
||||||
|
options:
|
||||||
|
passphrase:
|
||||||
|
mpp-eval: luks_passphrase
|
||||||
|
options:
|
||||||
|
volumes:
|
||||||
|
- name: root
|
||||||
|
extents: 100%FREE
|
||||||
|
- type: org.osbuild.mkfs.ext4
|
||||||
|
devices:
|
||||||
|
luks:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
lvm:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.luks2
|
||||||
|
parent: luks
|
||||||
|
options:
|
||||||
|
passphrase:
|
||||||
|
mpp-eval: luks_passphrase
|
||||||
|
device:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.lvm2.lv
|
||||||
|
parent: lvm
|
||||||
|
options:
|
||||||
|
volume: root
|
||||||
|
else:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
options:
|
||||||
|
uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
label: root
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:image-tree
|
||||||
|
build-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:build
|
||||||
|
extra-tree:
|
||||||
|
mpp-if: "'extra_image_source_' + image_type in locals()"
|
||||||
|
then:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- mpp-format-string: "name:{locals().get('extra_image_source_' + image_type)}"
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from: input://tree/
|
||||||
|
to: mount://root/
|
||||||
|
- mpp-eval: locals().get('extra_image_copy_' + image_type, [])
|
||||||
|
devices:
|
||||||
|
efi:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['efi'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['efi'].size
|
||||||
|
boot:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['boot'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['boot'].size
|
||||||
|
root:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.lvm2.lv
|
||||||
|
parent: root-luks
|
||||||
|
options:
|
||||||
|
volume: root
|
||||||
|
else:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
root-raw:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
root-luks:
|
||||||
|
mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.luks2
|
||||||
|
parent: root-raw
|
||||||
|
options:
|
||||||
|
passphrase:
|
||||||
|
mpp-eval: luks_passphrase
|
||||||
|
mounts:
|
||||||
|
- name: root
|
||||||
|
type: org.osbuild.ext4
|
||||||
|
source: root
|
||||||
|
target: /
|
||||||
|
- name: boot
|
||||||
|
type: org.osbuild.ext4
|
||||||
|
source: boot
|
||||||
|
target: /boot
|
||||||
|
- name: efi
|
||||||
|
type: org.osbuild.fat
|
||||||
|
source: efi
|
||||||
|
target: /boot/efi
|
||||||
|
- mpp-if: use_luks
|
||||||
|
then:
|
||||||
|
type: org.osbuild.lvm2.metadata
|
||||||
|
devices:
|
||||||
|
luks:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start:
|
||||||
|
mpp-eval: image.layout['root'].start
|
||||||
|
size:
|
||||||
|
mpp-eval: image.layout['root'].size
|
||||||
|
device:
|
||||||
|
type: org.osbuild.luks2
|
||||||
|
parent: luks
|
||||||
|
options:
|
||||||
|
passphrase:
|
||||||
|
mpp-eval: luks_passphrase
|
||||||
|
options:
|
||||||
|
vg_name: osbuild
|
||||||
|
creation_host: osbuild
|
||||||
|
description: "Built with osbuild"
|
||||||
|
- name: qcow2
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.qemu
|
||||||
|
inputs:
|
||||||
|
image:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
name:image:
|
||||||
|
file: disk.img
|
||||||
|
options:
|
||||||
|
filename: disk.qcow2
|
||||||
|
format:
|
||||||
|
type: qcow2
|
||||||
|
compat: '1.1'
|
||||||
|
|
||||||
|
- name: container
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.oci-archive
|
||||||
|
inputs:
|
||||||
|
base:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
options:
|
||||||
|
filename: container.tar
|
||||||
|
architecture: $arch
|
||||||
|
config:
|
||||||
|
Cmd:
|
||||||
|
- "/usr/bin/bash"
|
||||||
|
|
||||||
|
# We need a smaller fstab for the non-partitioned case
|
||||||
|
- name: ext4-fstab
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
# We copy /etc to get the right selinux context on the new file
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
image-tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:image-tree
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from: input://image-tree/etc
|
||||||
|
to: tree:///etc
|
||||||
|
- type: org.osbuild.fstab
|
||||||
|
options:
|
||||||
|
filesystems:
|
||||||
|
- uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
vfs_type: ext4
|
||||||
|
path: /
|
||||||
|
|
||||||
|
- name: ext4
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.truncate
|
||||||
|
options:
|
||||||
|
filename: rootfs.ext4
|
||||||
|
size:
|
||||||
|
mpp-eval: image.size
|
||||||
|
- type: org.osbuild.mkfs.ext4
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: rootfs.ext4
|
||||||
|
start: 0
|
||||||
|
size:
|
||||||
|
mpp-format-int: "{int(image.size) // 512}"
|
||||||
|
options:
|
||||||
|
uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
label: root
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:image-tree
|
||||||
|
fstab:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:ext4-fstab
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
mpp-join:
|
||||||
|
- - from: input://tree/
|
||||||
|
to: mount://root/
|
||||||
|
- from: input://fstab/etc/fstab
|
||||||
|
to: mount://root/etc/fstab
|
||||||
|
- mpp-eval: locals().get('extra_image_copy_' + image_type, [])
|
||||||
|
devices:
|
||||||
|
root:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: rootfs.ext4
|
||||||
|
start: 0
|
||||||
|
size:
|
||||||
|
mpp-format-int: "{int(image.size) // 512}"
|
||||||
|
mounts:
|
||||||
|
- name: root
|
||||||
|
type: org.osbuild.ext4
|
||||||
|
source: root
|
||||||
|
target: /
|
||||||
|
|
||||||
|
- name: tar
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.tar
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
options:
|
||||||
|
filename: rootfs.tar
|
||||||
|
root-node: omit
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
extra_image_rpms:
|
||||||
|
- openssh-server
|
||||||
|
- sudo
|
||||||
|
- tuned
|
||||||
|
- cloud-init
|
||||||
|
- cloud-utils-growpart
|
||||||
|
- gdisk
|
||||||
|
- NetworkManager-cloud-setup
|
||||||
|
- rsync
|
||||||
|
- qemu-guest-agent
|
||||||
|
extra_build_rpms:
|
||||||
|
- python3-pyyaml
|
||||||
|
target_stages:
|
||||||
|
- type: org.osbuild.sshd.config
|
||||||
|
options:
|
||||||
|
config:
|
||||||
|
PermitRootLogin:
|
||||||
|
mpp-eval: ssh_permit_root_login
|
||||||
|
- type: org.osbuild.systemd
|
||||||
|
options:
|
||||||
|
enabled_services:
|
||||||
|
- sshd
|
||||||
|
- NetworkManager
|
||||||
|
- nm-cloud-setup.service
|
||||||
|
- nm-cloud-setup.timer
|
||||||
|
- cloud-init
|
||||||
|
- cloud-init-local
|
||||||
|
- cloud-config
|
||||||
|
- cloud-final
|
||||||
|
- reboot.target
|
||||||
|
- tuned
|
||||||
|
default_target: multi-user.target
|
||||||
|
- type: org.osbuild.systemd-logind
|
||||||
|
options:
|
||||||
|
filename: 00-getty-fixes.conf
|
||||||
|
config:
|
||||||
|
Login:
|
||||||
|
NAutoVTs: 0
|
||||||
|
- type: org.osbuild.cloud-init
|
||||||
|
options:
|
||||||
|
filename: 00-cs-default-user.cfg
|
||||||
|
config:
|
||||||
|
system_info:
|
||||||
|
default_user:
|
||||||
|
name: ec2-user
|
||||||
|
- type: org.osbuild.systemd.unit
|
||||||
|
options:
|
||||||
|
unit: nm-cloud-setup.service
|
||||||
|
dropin: 10-enable-for-ec2.conf
|
||||||
|
config:
|
||||||
|
Service:
|
||||||
|
Environment: NM_CLOUD_SETUP_EC2=yes
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.timezone
|
||||||
|
options:
|
||||||
|
zone: UTC
|
||||||
|
- type: org.osbuild.chrony
|
||||||
|
options:
|
||||||
|
servers:
|
||||||
|
- hostname: 169.254.169.123
|
||||||
|
prefer: true
|
||||||
|
iburst: true
|
||||||
|
minpoll: 4
|
||||||
|
maxpoll: 4
|
||||||
|
leapsectz: ""
|
||||||
|
- type: org.osbuild.keymap
|
||||||
|
options:
|
||||||
|
keymap: us
|
||||||
|
x11-keymap:
|
||||||
|
layouts:
|
||||||
|
- us
|
||||||
|
pipelines: []
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
version: '2'
|
||||||
|
pipelines: []
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
extra_image_source_ostree: ostree-tree
|
||||||
|
extra_image_copy_ostree:
|
||||||
|
- from: input://extra-tree/lib/ostree-boot/efi/
|
||||||
|
to: mount://root/boot/efi/
|
||||||
|
rpi4_use_uefi: false
|
||||||
|
extra_image_source_directboot: rpi-direct-files
|
||||||
|
extra_image_copy_directboot:
|
||||||
|
mpp-if: not rpi4_use_uefi
|
||||||
|
then:
|
||||||
|
- from: input://extra-tree/
|
||||||
|
to: mount://root/boot/efi/
|
||||||
|
else: []
|
||||||
|
extra_image_rpms:
|
||||||
|
- pi4-firmware-blob
|
||||||
|
- pi_resize
|
||||||
|
dracut_add_drivers:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: dracut_add_drivers
|
||||||
|
- - bcm2835
|
||||||
|
- bcm2835-mailbox
|
||||||
|
- sdhci
|
||||||
|
partition_label: dos
|
||||||
|
target_repos:
|
||||||
|
- id: cs9-rpi4-fw
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/alexl/cs9-rpi4-fw/centos-stream-9-aarch64/
|
||||||
|
rpi4_direct_cmdline_txt: console=serial0,115200 console=tty1 modprobe.blacklist=vc4
|
||||||
|
rpi4_direct_config_txt: |
|
||||||
|
kernel=EFI/Linux/linux.efi
|
||||||
|
initramfs EFI/Linux/initramfs.img followkernel
|
||||||
|
arm_64bit=1
|
||||||
|
enable_uart=1
|
||||||
|
uart_2ndstage=1
|
||||||
|
dtoverlay=miniuart-bt
|
||||||
|
display_auto_detect=1
|
||||||
|
dtoverlay=vc4-kms-v3d-pi4
|
||||||
|
max_framebuffers=2
|
||||||
|
disable_overscan=1
|
||||||
|
pipelines:
|
||||||
|
- name: rpi-direct-files
|
||||||
|
runner: org.osbuild.centos9
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: config.txt
|
||||||
|
text: $rpi4_direct_config_txt
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['config.txt']}
|
||||||
|
to: tree:///config.txt
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: cmdline.txt
|
||||||
|
text: $rpi4_direct_cmdline_txt
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['cmdline.txt']}
|
||||||
|
to: tree:///cmdline.txt
|
||||||
|
|
@ -0,0 +1,394 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import select
|
||||||
|
import shlex
|
||||||
|
import socket
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
import signal
|
||||||
|
import shutil
|
||||||
|
import json
|
||||||
|
|
||||||
|
BLOCK_SIZE = 64*1024
|
||||||
|
|
||||||
|
def read_manifest(path):
|
||||||
|
if path == "-":
|
||||||
|
manifest = sys.stdin.read()
|
||||||
|
else:
|
||||||
|
with open(path) as f:
|
||||||
|
manifest = f.read()
|
||||||
|
|
||||||
|
return manifest
|
||||||
|
|
||||||
|
def parse_arguments(sys_argv):
|
||||||
|
parser = argparse.ArgumentParser(description="Build operating system images")
|
||||||
|
|
||||||
|
parser.add_argument("manifest_path", metavar="MANIFEST",
|
||||||
|
help="json file containing the manifest that should be built, or a '-' to read from stdin")
|
||||||
|
parser.add_argument("--store", metavar="DIRECTORY", type=os.path.abspath,
|
||||||
|
default=".osbuild",
|
||||||
|
help="directory where intermediary os trees are stored")
|
||||||
|
parser.add_argument("--checkpoint", metavar="ID", action="append", type=str, default=None,
|
||||||
|
help="stage to commit to the object store during build (can be passed multiple times)")
|
||||||
|
parser.add_argument("--export", metavar="ID", action="append", type=str, default=None,
|
||||||
|
help="object to export, can be passed multiple times")
|
||||||
|
parser.add_argument("--output-directory", metavar="DIRECTORY", type=os.path.abspath,
|
||||||
|
help="directory where result objects are stored")
|
||||||
|
parser.add_argument("--arch", metavar="ARCH", type=str, default=platform.machine(),
|
||||||
|
help="Arch to build for")
|
||||||
|
|
||||||
|
return parser.parse_args(sys_argv[1:])
|
||||||
|
|
||||||
|
def local_osbuild(manifest, opts):
|
||||||
|
cmd = ['osbuild'] + opts + ['-']
|
||||||
|
try:
|
||||||
|
p = subprocess.run(cmd, check=True, input=manifest.encode("utf8"), capture_output=True )
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(e.output)
|
||||||
|
sys.exit(e.returncode)
|
||||||
|
lines = p.stdout.decode("utf8").splitlines()
|
||||||
|
checkpoints = {}
|
||||||
|
for l in lines:
|
||||||
|
p = l.split()
|
||||||
|
checkpoint = p[0][:-1]
|
||||||
|
checkpoints[checkpoint] = p[1]
|
||||||
|
return checkpoints
|
||||||
|
|
||||||
|
def extract_dependencies(manifest):
|
||||||
|
j = json.loads(manifest)
|
||||||
|
version = j.get("version", None);
|
||||||
|
if version != '2':
|
||||||
|
print(f"Unsupported manifest version {version}, only version 2 supported")
|
||||||
|
sys.exit(1)
|
||||||
|
sources = j.get("sources", {});
|
||||||
|
curl = sources.get("org.osbuild.curl", {});
|
||||||
|
curl_items = curl.get("items", {});
|
||||||
|
shas = curl_items.keys()
|
||||||
|
return list(shas)
|
||||||
|
|
||||||
|
def find_images(arch):
|
||||||
|
base_image=f"osbuildvm-{arch}.img"
|
||||||
|
base_kernel=f"osbuildvm-{arch}.vmlinuz"
|
||||||
|
base_initrd=f"osbuildvm-{arch}.initramfs"
|
||||||
|
|
||||||
|
image_dir=None
|
||||||
|
image_dirs = [os.getcwd(), os.path.join(os.getcwd(), "_build"), "/usr/share/osbuildvm"]
|
||||||
|
for i in image_dirs:
|
||||||
|
if os.path.exists(os.path.join(i, base_image)):
|
||||||
|
image_dir = i
|
||||||
|
break
|
||||||
|
if not image_dir:
|
||||||
|
print(f"Unable to find {base_image}, tried: {image_dirs}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
image = os.path.join(image_dir, base_image)
|
||||||
|
kernel = os.path.join(image_dir, base_kernel)
|
||||||
|
initrd = os.path.join(image_dir, base_initrd)
|
||||||
|
return (image, kernel, initrd)
|
||||||
|
|
||||||
|
def qemu_img(*args):
|
||||||
|
res = subprocess.run(["qemu-img"] + [*args],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
check=True)
|
||||||
|
|
||||||
|
class QEmu(object):
|
||||||
|
def __init__(self, image1, image2, kernel, initrd, arch):
|
||||||
|
# This is where we store the sockets and the pidfile
|
||||||
|
self.tmpdir = tempfile.TemporaryDirectory(prefix="tmp-qemu-")
|
||||||
|
self.args = []
|
||||||
|
self.pid = 0
|
||||||
|
self.host_arch = platform.machine()
|
||||||
|
self.arch = arch
|
||||||
|
|
||||||
|
debug_serial = False
|
||||||
|
|
||||||
|
qemu_kvm_path = self.find_qemu()
|
||||||
|
|
||||||
|
self.args.append(qemu_kvm_path)
|
||||||
|
|
||||||
|
# Virtio serial ports
|
||||||
|
|
||||||
|
self.args.extend(["-device", "virtio-serial"])
|
||||||
|
out_socket_path = self.add_socket("output")
|
||||||
|
sync_socket_path = self.add_socket("sync")
|
||||||
|
stdout_socket_path = self.add_socket("stdout")
|
||||||
|
|
||||||
|
debug_cmdline="quiet loglevel=1"
|
||||||
|
if debug_serial:
|
||||||
|
self.args.extend(["-serial", "file:/dev/stdout"])
|
||||||
|
debug_cmdline=""
|
||||||
|
|
||||||
|
# Machine details
|
||||||
|
self.args.extend(["-m", "size=2G",
|
||||||
|
"-nodefaults",
|
||||||
|
"-vga", "none", "-vnc", "none"])
|
||||||
|
|
||||||
|
if self.kvm_supported():
|
||||||
|
self.args.extend(["-enable-kvm"])
|
||||||
|
|
||||||
|
if self.arch=="x86_64":
|
||||||
|
machine = "q35"
|
||||||
|
cpu = "qemu64"
|
||||||
|
if self.arch=="aarch64":
|
||||||
|
machine = "virt"
|
||||||
|
cpu = "cortex-a57"
|
||||||
|
|
||||||
|
if self.arch == self.host_arch:
|
||||||
|
cpu = "host"
|
||||||
|
|
||||||
|
self.args.extend(["-machine", machine,
|
||||||
|
"-cpu", cpu])
|
||||||
|
|
||||||
|
if self.arch=="aarch64":
|
||||||
|
self.args.extend(["-bios", "/usr/share/edk2/aarch64/QEMU_EFI.fd",
|
||||||
|
"-boot", "efi"])
|
||||||
|
|
||||||
|
pid_file = os.path.join(self.tmpdir.name, "qemu.pid")
|
||||||
|
self.args.extend(["-daemonize", "-pidfile" , pid_file,
|
||||||
|
"-kernel", kernel,
|
||||||
|
"-initrd", initrd,
|
||||||
|
"-append", f'root=/dev/vda console=ttyS0 init=/usr/bin/start.sh {debug_cmdline} ro',
|
||||||
|
"-drive", f"file={image1},index=0,media=disk,format=qcow2,snapshot=on,if=virtio",
|
||||||
|
"-drive", f"file={image2},index=1,media=disk,format=raw,if=virtio"])
|
||||||
|
|
||||||
|
p = subprocess.run(self.args, check=True)
|
||||||
|
|
||||||
|
with open(pid_file, "r") as f:
|
||||||
|
self.pid = int(f.read())
|
||||||
|
|
||||||
|
self.sock_out = self.connect_socket(out_socket_path)
|
||||||
|
self.sock_sync = self.connect_socket(sync_socket_path)
|
||||||
|
self.sock_stdout = self.connect_socket(stdout_socket_path)
|
||||||
|
|
||||||
|
def connect_socket(self, path):
|
||||||
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
sock.connect(path)
|
||||||
|
return sock
|
||||||
|
|
||||||
|
def add_socket(self, id):
|
||||||
|
socket_path = os.path.join(self.tmpdir.name, id + ".sock")
|
||||||
|
self.args.extend(["-chardev", f"socket,path={socket_path},server=on,wait=off,id={id}",
|
||||||
|
"-device", f"virtserialport,chardev={id},name={id}"])
|
||||||
|
return socket_path
|
||||||
|
|
||||||
|
def find_qemu(self):
|
||||||
|
if self.arch == self.host_arch:
|
||||||
|
binary_name = "qemu-kvm"
|
||||||
|
else:
|
||||||
|
binary_name = f"qemu-system-{self.arch}"
|
||||||
|
|
||||||
|
|
||||||
|
for d in ["/usr/bin", "/usr/libexec"]:
|
||||||
|
p = os.path.join(d, binary_name)
|
||||||
|
if os.path.isfile(p):
|
||||||
|
return p
|
||||||
|
|
||||||
|
print(f"Can't find {binary_name}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def kvm_supported(self):
|
||||||
|
return self.arch == self.host_arch and os.path.exists("/dev/kvm")
|
||||||
|
|
||||||
|
def copy_out(self, destination):
|
||||||
|
while True:
|
||||||
|
readable, writable, exceptional = select.select([self.sock_out, self.sock_sync, self.sock_stdout], [], [])
|
||||||
|
|
||||||
|
read_something = False
|
||||||
|
|
||||||
|
if self.sock_stdout in readable:
|
||||||
|
data = self.sock_stdout.recv(BLOCK_SIZE)
|
||||||
|
while len(data) > 0:
|
||||||
|
res = sys.stdout.buffer.write(data)
|
||||||
|
data = data[res:]
|
||||||
|
sys.stdout.flush()
|
||||||
|
read_something = True
|
||||||
|
|
||||||
|
if self.sock_out in readable:
|
||||||
|
data = self.sock_out.recv(BLOCK_SIZE)
|
||||||
|
while len(data) > 0:
|
||||||
|
res = destination.write(data)
|
||||||
|
data = data[res:]
|
||||||
|
read_something = True
|
||||||
|
|
||||||
|
if read_something:
|
||||||
|
continue # Don't exit until there is no more to read from sock or sock_stdout
|
||||||
|
|
||||||
|
# If we had no buffered data in sock and sync_sock is readable that means we copied everything and can exit
|
||||||
|
if self.sock_sync in readable:
|
||||||
|
data = self.sock_sync.recv(BLOCK_SIZE)
|
||||||
|
break
|
||||||
|
|
||||||
|
def kill(self):
|
||||||
|
if self.pid != 0:
|
||||||
|
os.kill(self.pid, signal.SIGTERM)
|
||||||
|
self.pid = 0
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
self.kill()
|
||||||
|
self.tmpdir.cleanup()
|
||||||
|
|
||||||
|
def create_ext4_image(path, size, root_dir):
|
||||||
|
with open(path, "w") as f:
|
||||||
|
f.truncate(size)
|
||||||
|
|
||||||
|
cmd = ["mkfs.ext4", "-d", root_dir, "-E", "no_copy_xattrs,root_owner=0:0", "-O", "^has_journal", path]
|
||||||
|
try:
|
||||||
|
p = subprocess.run(cmd, check=True,capture_output=True)
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
print(f"Unable to create ext4 work fs: {e}", file=sys.stderr)
|
||||||
|
sys.exit(e.returncode)
|
||||||
|
|
||||||
|
def link_or_copy_file(source_path, dest_path):
|
||||||
|
try:
|
||||||
|
os.link(source_path, dest_path)
|
||||||
|
except Exception as e:
|
||||||
|
shutil.copyfile(source_path, dest_path, follow_symlinks=False)
|
||||||
|
|
||||||
|
def make_work_rootfs(args, tmpdirname, manifest, digests, main_sh, checkpoint_ids):
|
||||||
|
rootdir = os.path.join(tmpdirname, "root")
|
||||||
|
os.makedirs(rootdir, exist_ok=True)
|
||||||
|
|
||||||
|
with open (os.open(os.path.join(rootdir, "main.sh"), os.O_CREAT | os.O_WRONLY, 0o775), "w") as mainsh:
|
||||||
|
mainsh.write(main_sh)
|
||||||
|
|
||||||
|
with open (os.path.join(rootdir, "image.json"), "w") as image_json:
|
||||||
|
image_json.write(manifest)
|
||||||
|
|
||||||
|
orig_sources_dir = os.path.join(args.store, "sources/org.osbuild.files")
|
||||||
|
root_sources_dir = os.path.join(rootdir, "osbuild_store/sources/org.osbuild.files")
|
||||||
|
os.makedirs(root_sources_dir, mode=0o777, exist_ok=True)
|
||||||
|
root_input_dir = os.path.join(rootdir, "input")
|
||||||
|
os.makedirs(root_input_dir, mode=0o777, exist_ok=True)
|
||||||
|
|
||||||
|
for digest in digests:
|
||||||
|
link_or_copy_file(os.path.join(orig_sources_dir, digest),
|
||||||
|
os.path.join(root_sources_dir, digest))
|
||||||
|
|
||||||
|
for cp, cp_id in checkpoint_ids.items():
|
||||||
|
source_path = os.path.join(args.store, "refs_tars/" + cp_id + ".tar.gz")
|
||||||
|
if os.path.isfile(source_path):
|
||||||
|
link_or_copy_file(source_path,
|
||||||
|
os.path.join(root_input_dir, cp_id + ".tar.gz"))
|
||||||
|
|
||||||
|
return rootdir
|
||||||
|
|
||||||
|
# Moves any files recursively in root_src_dir to root_dst_dir, replacing if needed
|
||||||
|
# Keeps old files and directories in root_dst_dir
|
||||||
|
def move_merged(root_src_dir, root_dst_dir):
|
||||||
|
root_src_dir = os.path.abspath(root_src_dir)
|
||||||
|
root_dst_dir = os.path.abspath(root_dst_dir)
|
||||||
|
for src_dir, dirs, files in os.walk(root_src_dir):
|
||||||
|
dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
|
||||||
|
if not os.path.exists(dst_dir):
|
||||||
|
os.makedirs(dst_dir)
|
||||||
|
for file_ in files:
|
||||||
|
src_file = os.path.join(src_dir, file_)
|
||||||
|
dst_file = os.path.join(dst_dir, file_)
|
||||||
|
if os.path.exists(dst_file):
|
||||||
|
os.remove(dst_file)
|
||||||
|
shutil.move(src_file, dst_dir)
|
||||||
|
|
||||||
|
def run_in_vm(args, manifest, digests, tmpdirname, shell_to_run, checkpoint_ids):
|
||||||
|
image,kernel,initrd = find_images(args.arch)
|
||||||
|
|
||||||
|
rootdir = make_work_rootfs(args, tmpdirname, manifest, digests, shell_to_run, checkpoint_ids)
|
||||||
|
work_image = os.path.join(tmpdirname, "work.img")
|
||||||
|
create_ext4_image(work_image, 100*1024*1024*1024, rootdir)
|
||||||
|
shutil.rmtree(rootdir)
|
||||||
|
|
||||||
|
output_path = args.output_directory
|
||||||
|
os.makedirs(output_path, exist_ok=True)
|
||||||
|
|
||||||
|
exit_status = 1
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(prefix="download-", dir=output_path) as output_tmpdir:
|
||||||
|
with QEmu(image, work_image, kernel, initrd, args.arch) as qemu:
|
||||||
|
with subprocess.Popen(["tar", "x", "-C", output_tmpdir], stdin=subprocess.PIPE) as proc:
|
||||||
|
qemu.copy_out(proc.stdin)
|
||||||
|
exit_status_path = os.path.join(output_tmpdir, "exit_status")
|
||||||
|
if os.path.isfile(exit_status_path):
|
||||||
|
with open(exit_status_path, "r") as f:
|
||||||
|
exit_status = int(f.read())
|
||||||
|
|
||||||
|
# Move osbuild outout to the real output dir
|
||||||
|
osbuild_output = os.path.join(output_tmpdir, "osbuild")
|
||||||
|
if os.path.isdir(osbuild_output):
|
||||||
|
move_merged(osbuild_output, output_path)
|
||||||
|
|
||||||
|
checkpoints_output = os.path.join(output_tmpdir, "checkpoints")
|
||||||
|
checkpoints_dest = os.path.join(args.store, "refs_tars")
|
||||||
|
if os.path.isdir(checkpoints_output):
|
||||||
|
os.makedirs(checkpoints_dest, exist_ok=True)
|
||||||
|
for tar in os.listdir(checkpoints_output):
|
||||||
|
if not os.path.isfile(os.path.join(checkpoints_dest, tar)):
|
||||||
|
shutil.move(os.path.join(checkpoints_output, tar),
|
||||||
|
checkpoints_dest)
|
||||||
|
|
||||||
|
sys.exit(exit_status)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_arguments(sys.argv)
|
||||||
|
manifest = read_manifest(args.manifest_path)
|
||||||
|
|
||||||
|
print("Running osbuild on host to download files")
|
||||||
|
checkpoint_ids = local_osbuild(manifest, ['--store', args.store])
|
||||||
|
|
||||||
|
digests = extract_dependencies(manifest)
|
||||||
|
|
||||||
|
mainsh_data = f'''\
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
mkdir -p /work/osbuild_store
|
||||||
|
(
|
||||||
|
echo === Extracting checkpoints in vm ===
|
||||||
|
for tar in $(find /work/input/ -mindepth 1 -print ); do
|
||||||
|
echo extracting $(basename $tar)
|
||||||
|
tar xf $tar --acls --selinux --xattrs -C /work/osbuild_store
|
||||||
|
done
|
||||||
|
echo === Running osbuild in vm ===
|
||||||
|
osbuild --store /work/osbuild_store --output-directory /work/output/osbuild {' '.join(map(lambda e: "--export " + e, args.export))} {' '.join(map(lambda cp: "--checkpoint " + cp, args.checkpoint))} /work/image.json
|
||||||
|
RES=$?
|
||||||
|
echo $RES > /work/output/exit_status
|
||||||
|
|
||||||
|
echo === Osbuild exit status $RES ===
|
||||||
|
|
||||||
|
echo === Saving checkpoints ===
|
||||||
|
mkdir -p /work/output/checkpoints
|
||||||
|
for cp in $(find /work/osbuild_store/refs/ -mindepth 1 -printf "%f "); do
|
||||||
|
if test -f /work/input/$cp.tar.gz; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
obj=$(basename $(readlink /work/osbuild_store/refs/$cp))
|
||||||
|
tar cSf /work/output/checkpoints/$cp.tar.gz --acls --selinux --xattrs -C /work/osbuild_store/ refs/$cp objects/$obj
|
||||||
|
echo Saved $cp
|
||||||
|
done
|
||||||
|
) > /dev/virtio-ports/stdout 2>&1
|
||||||
|
|
||||||
|
tar cSf /dev/virtio-ports/output -C /work/output ./
|
||||||
|
|
||||||
|
# Signal output ended
|
||||||
|
sleep 3
|
||||||
|
echo DONE > /dev/virtio-ports/sync
|
||||||
|
|
||||||
|
# Block for it to be fully read
|
||||||
|
cat /dev/virtio-ports/sync
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
tmpdir = os.path.join(args.store, "tmp")
|
||||||
|
os.makedirs(tmpdir, exist_ok=True)
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory(prefix="osbuild-qemu-", dir=tmpdir) as tmpdirname:
|
||||||
|
run_in_vm(args, manifest, digests, tmpdirname, mainsh_data, checkpoint_ids)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,229 @@
|
||||||
|
version: '2'
|
||||||
|
mpp-vars:
|
||||||
|
rootfs_uuid: 86a22bf4-f153-4541-b6c7-0332c0dfaead
|
||||||
|
rootfs_size: 2147483648
|
||||||
|
cs9_baseurl: http://mirror.stream.centos.org/9-stream
|
||||||
|
cs9_repos:
|
||||||
|
- id: baseos
|
||||||
|
baseurl: $cs9_baseurl/BaseOS/$arch/os/
|
||||||
|
- id: appstream
|
||||||
|
baseurl: $cs9_baseurl/AppStream/$arch/os/
|
||||||
|
centos_gpg_key: |
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
Version: GnuPG v2.0.22 (GNU/Linux)
|
||||||
|
|
||||||
|
mQINBFzMWxkBEADHrskpBgN9OphmhRkc7P/YrsAGSvvl7kfu+e9KAaU6f5MeAVyn
|
||||||
|
rIoM43syyGkgFyWgjZM8/rur7EMPY2yt+2q/1ZfLVCRn9856JqTIq0XRpDUe4nKQ
|
||||||
|
8BlA7wDVZoSDxUZkSuTIyExbDf0cpw89Tcf62Mxmi8jh74vRlPy1PgjWL5494b3X
|
||||||
|
5fxDidH4bqPZyxTBqPrUFuo+EfUVEqiGF94Ppq6ZUvrBGOVo1V1+Ifm9CGEK597c
|
||||||
|
aevcGc1RFlgxIgN84UpuDjPR9/zSndwJ7XsXYvZ6HXcKGagRKsfYDWGPkA5cOL/e
|
||||||
|
f+yObOnC43yPUvpggQ4KaNJ6+SMTZOKikM8yciyBwLqwrjo8FlJgkv8Vfag/2UR7
|
||||||
|
JINbyqHHoLUhQ2m6HXSwK4YjtwidF9EUkaBZWrrskYR3IRZLXlWqeOi/+ezYOW0m
|
||||||
|
vufrkcvsh+TKlVVnuwmEPjJ8mwUSpsLdfPJo1DHsd8FS03SCKPaXFdD7ePfEjiYk
|
||||||
|
nHpQaKE01aWVSLUiygn7F7rYemGqV9Vt7tBw5pz0vqSC72a5E3zFzIIuHx6aANry
|
||||||
|
Gat3aqU3qtBXOrA/dPkX9cWE+UR5wo/A2UdKJZLlGhM2WRJ3ltmGT48V9CeS6N9Y
|
||||||
|
m4CKdzvg7EWjlTlFrd/8WJ2KoqOE9leDPeXRPncubJfJ6LLIHyG09h9kKQARAQAB
|
||||||
|
tDpDZW50T1MgKENlbnRPUyBPZmZpY2lhbCBTaWduaW5nIEtleSkgPHNlY3VyaXR5
|
||||||
|
QGNlbnRvcy5vcmc+iQI3BBMBAgAhBQJczFsZAhsDBgsJCAcDAgYVCAIJCgsDFgIB
|
||||||
|
Ah4BAheAAAoJEAW1VbOEg8ZdjOsP/2ygSxH9jqffOU9SKyJDlraL2gIutqZ3B8pl
|
||||||
|
Gy/Qnb9QD1EJVb4ZxOEhcY2W9VJfIpnf3yBuAto7zvKe/G1nxH4Bt6WTJQCkUjcs
|
||||||
|
N3qPWsx1VslsAEz7bXGiHym6Ay4xF28bQ9XYIokIQXd0T2rD3/lNGxNtORZ2bKjD
|
||||||
|
vOzYzvh2idUIY1DgGWJ11gtHFIA9CvHcW+SMPEhkcKZJAO51ayFBqTSSpiorVwTq
|
||||||
|
a0cB+cgmCQOI4/MY+kIvzoexfG7xhkUqe0wxmph9RQQxlTbNQDCdaxSgwbF2T+gw
|
||||||
|
byaDvkS4xtR6Soj7BKjKAmcnf5fn4C5Or0KLUqMzBtDMbfQQihn62iZJN6ZZ/4dg
|
||||||
|
q4HTqyVpyuzMXsFpJ9L/FqH2DJ4exGGpBv00ba/Zauy7GsqOc5PnNBsYaHCply0X
|
||||||
|
407DRx51t9YwYI/ttValuehq9+gRJpOTTKp6AjZn/a5Yt3h6jDgpNfM/EyLFIY9z
|
||||||
|
V6CXqQQ/8JRvaik/JsGCf+eeLZOw4koIjZGEAg04iuyNTjhx0e/QHEVcYAqNLhXG
|
||||||
|
rCTTbCn3NSUO9qxEXC+K/1m1kaXoCGA0UWlVGZ1JSifbbMx0yxq/brpEZPUYm+32
|
||||||
|
o8XfbocBWljFUJ+6aljTvZ3LQLKTSPW7TFO+GXycAOmCGhlXh2tlc6iTc41PACqy
|
||||||
|
yy+mHmSv
|
||||||
|
=kkH7
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
pipelines:
|
||||||
|
- runner: org.osbuild.centos9
|
||||||
|
name: build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
module-platform-id: platform:el9
|
||||||
|
baseurl: $cs9_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-eval: cs9_repos
|
||||||
|
packages:
|
||||||
|
- dnf
|
||||||
|
- e2fsprogs
|
||||||
|
- policycoreutils
|
||||||
|
- python3-iniparse
|
||||||
|
- python39
|
||||||
|
- qemu-img
|
||||||
|
- selinux-policy-targeted
|
||||||
|
- tar
|
||||||
|
- xz
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
exclude:
|
||||||
|
docs: true
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
labels:
|
||||||
|
/usr/bin/cp: system_u:object_r:install_exec_t:s0
|
||||||
|
/usr/bin/tar: system_u:object_r:install_exec_t:s0
|
||||||
|
- name: rootfs
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.rpm
|
||||||
|
options:
|
||||||
|
gpgkeys:
|
||||||
|
- mpp-eval: centos_gpg_key
|
||||||
|
inputs:
|
||||||
|
packages:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-depsolve:
|
||||||
|
architecture: $arch
|
||||||
|
module-platform-id: platform:el9
|
||||||
|
baseurl: $cs9_baseurl/BaseOS/$arch/os/
|
||||||
|
repos:
|
||||||
|
mpp-join:
|
||||||
|
- mpp-eval: cs9_repos
|
||||||
|
- - id: osbuild
|
||||||
|
baseurl: https://download.copr.fedorainfracloud.org/results/@osbuild/osbuild/centos-stream-9-$arch
|
||||||
|
packages:
|
||||||
|
- bash
|
||||||
|
- dracut-config-generic
|
||||||
|
- kernel
|
||||||
|
- langpacks-en
|
||||||
|
- selinux-policy-targeted
|
||||||
|
- net-tools
|
||||||
|
- osbuild
|
||||||
|
- osbuild-tools
|
||||||
|
- osbuild-ostree
|
||||||
|
excludes:
|
||||||
|
- dracut-config-rescue
|
||||||
|
- type: org.osbuild.locale
|
||||||
|
options:
|
||||||
|
language: en_US.UTF-8
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
inlinefile:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.source
|
||||||
|
mpp-embed:
|
||||||
|
id: osbuilder.sh
|
||||||
|
text: |
|
||||||
|
#!/usr/bin/bash
|
||||||
|
function clean_up {
|
||||||
|
systemctl poweroff -f -f
|
||||||
|
}
|
||||||
|
trap clean_up EXIT
|
||||||
|
if grep -q "osbuilder_bash=1" /proc/cmdline; then bash; exit; fi
|
||||||
|
mount /dev/vdb /work
|
||||||
|
/work/main.sh
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://inlinefile/{embedded['osbuilder.sh']}
|
||||||
|
to: tree:///usr/bin/start.sh
|
||||||
|
- type: org.osbuild.chmod
|
||||||
|
options:
|
||||||
|
items:
|
||||||
|
/usr/bin/start.sh:
|
||||||
|
mode: a+x
|
||||||
|
- type: org.osbuild.mkdir
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- path: /work
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
- type: org.osbuild.selinux
|
||||||
|
options:
|
||||||
|
file_contexts: etc/selinux/targeted/contexts/files/file_contexts
|
||||||
|
- name: image
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.truncate
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
size:
|
||||||
|
mpp-format-string: '{rootfs_size}'
|
||||||
|
- type: org.osbuild.mkfs.ext4
|
||||||
|
devices:
|
||||||
|
device:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start: 0
|
||||||
|
size:
|
||||||
|
mpp-eval: rootfs_size
|
||||||
|
options:
|
||||||
|
uuid:
|
||||||
|
mpp-eval: rootfs_uuid
|
||||||
|
label: root
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
tree:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from: input://tree/
|
||||||
|
to: mount://root/
|
||||||
|
devices:
|
||||||
|
root:
|
||||||
|
type: org.osbuild.loopback
|
||||||
|
options:
|
||||||
|
filename: disk.img
|
||||||
|
start: 0
|
||||||
|
size:
|
||||||
|
mpp-eval: rootfs_size
|
||||||
|
mounts:
|
||||||
|
- name: root
|
||||||
|
type: org.osbuild.ext4
|
||||||
|
source: root
|
||||||
|
target: /
|
||||||
|
- name: osbuildvm
|
||||||
|
build: name:build
|
||||||
|
stages:
|
||||||
|
- type: org.osbuild.qemu
|
||||||
|
inputs:
|
||||||
|
image:
|
||||||
|
type: org.osbuild.files
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
name:image:
|
||||||
|
file: disk.img
|
||||||
|
options:
|
||||||
|
filename: disk.qcow2
|
||||||
|
format:
|
||||||
|
type: qcow2
|
||||||
|
compat: '1.1'
|
||||||
|
- type: org.osbuild.copy
|
||||||
|
inputs:
|
||||||
|
rootfs:
|
||||||
|
type: org.osbuild.tree
|
||||||
|
origin: org.osbuild.pipeline
|
||||||
|
references:
|
||||||
|
- name:rootfs
|
||||||
|
options:
|
||||||
|
paths:
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://rootfs/usr/lib/modules/{rpms['rootfs']['kernel-core'].evra}/vmlinuz
|
||||||
|
to: tree:///vmlinuz
|
||||||
|
- from:
|
||||||
|
mpp-format-string: input://rootfs/boot/initramfs-{rpms['rootfs']['kernel-core'].evra}.img
|
||||||
|
to: tree:///initramfs
|
||||||
|
- type: org.osbuild.chmod
|
||||||
|
options:
|
||||||
|
items:
|
||||||
|
/initramfs:
|
||||||
|
mode: a+r
|
||||||
|
|
@ -0,0 +1,449 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import atexit
|
||||||
|
import binascii
|
||||||
|
import http.server
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import select
|
||||||
|
import shutil
|
||||||
|
import signal
|
||||||
|
import socket
|
||||||
|
import socketserver
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import time
|
||||||
|
|
||||||
|
is_verbose = False
|
||||||
|
def print_verbose(s):
|
||||||
|
if is_verbose:
|
||||||
|
print(s)
|
||||||
|
|
||||||
|
def print_error(s):
|
||||||
|
print(s, file=sys.stderr)
|
||||||
|
|
||||||
|
def exit_error(s):
|
||||||
|
print_error(s)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def bool_arg(val):
|
||||||
|
return "on" if val else "off"
|
||||||
|
|
||||||
|
def find_qemu(arch):
|
||||||
|
binary_names = [ f"qemu-system-{arch}" ]
|
||||||
|
if arch == platform.machine():
|
||||||
|
binary_names.append("qemu-kvm")
|
||||||
|
|
||||||
|
for binary_name in binary_names:
|
||||||
|
if "QEMU_BUILD_DIR" in os.environ:
|
||||||
|
p = os.path.join(os.environ["QEMU_BUILD_DIR"], binary_name)
|
||||||
|
if os.path.isfile(p):
|
||||||
|
return p
|
||||||
|
else:
|
||||||
|
exit_error(f"Can't find {binary_name}")
|
||||||
|
|
||||||
|
qemu_bin_dirs = ["/usr/bin", "/usr/libexec"]
|
||||||
|
if "PATH" in os.environ:
|
||||||
|
qemu_bin_dirs += os.environ["PATH"].split(":")
|
||||||
|
|
||||||
|
for d in qemu_bin_dirs:
|
||||||
|
p = os.path.join(d, binary_name)
|
||||||
|
if os.path.isfile(p):
|
||||||
|
return p
|
||||||
|
|
||||||
|
exit_error(f"Can't find {binary_name}")
|
||||||
|
|
||||||
|
def qemu_available_accels(qemu):
|
||||||
|
cmd = qemu + ' -accel help'
|
||||||
|
info = subprocess.check_output(cmd.split(" ")).decode('utf-8')
|
||||||
|
accel_list = []
|
||||||
|
for accel in ('kvm', 'xen', 'hvf', 'hax', 'tcg'):
|
||||||
|
if info.find(accel) > 0:
|
||||||
|
accel_list.append(accel)
|
||||||
|
return accel_list
|
||||||
|
|
||||||
|
def random_id():
|
||||||
|
return binascii.b2a_hex(os.urandom(8)).decode('utf8')
|
||||||
|
|
||||||
|
def machine_id():
|
||||||
|
try:
|
||||||
|
with open("/etc/machine-id", "r") as f:
|
||||||
|
mid = f.read().strip()
|
||||||
|
except FileNotFoundError:
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
# for macOS
|
||||||
|
import plistlib
|
||||||
|
cmd = "ioreg -rd1 -c IOPlatformExpertDevice -a"
|
||||||
|
plist_data = subprocess.check_output(cmd.split(" "))
|
||||||
|
mid = plistlib.loads(plist_data)[0]["IOPlatformUUID"].replace("-","")
|
||||||
|
else:
|
||||||
|
# fallback for the other distros
|
||||||
|
hostname = socket.gethostname()
|
||||||
|
mid = ''.join(hex(ord(x))[2:] for x in (hostname*16)[:16])
|
||||||
|
|
||||||
|
return mid
|
||||||
|
|
||||||
|
def generate_mac_address():
|
||||||
|
# create a new mac address based on our machine id
|
||||||
|
data = machine_id()
|
||||||
|
|
||||||
|
maclst = ["FE"] + [data[x:x+2] for x in range(-12, -2, 2)]
|
||||||
|
return ":".join(maclst)
|
||||||
|
|
||||||
|
def run_http_server(path):
|
||||||
|
writer, reader = socket.socketpair(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
child_pid = os.fork()
|
||||||
|
if child_pid == 0:
|
||||||
|
reader.close()
|
||||||
|
|
||||||
|
# Child
|
||||||
|
os.chdir(path)
|
||||||
|
|
||||||
|
class HTTPHandler(http.server.SimpleHTTPRequestHandler):
|
||||||
|
def log_message(self, format, *args):
|
||||||
|
pass # Silence logs
|
||||||
|
|
||||||
|
httpd = socketserver.TCPServer(("127.0.0.1", 0), HTTPHandler)
|
||||||
|
writer.send(str(httpd.server_address[1]).encode("utf8"))
|
||||||
|
writer.close()
|
||||||
|
|
||||||
|
httpd.serve_forever()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Parent
|
||||||
|
writer.close()
|
||||||
|
atexit.register(os.kill, child_pid,signal.SIGTERM)
|
||||||
|
|
||||||
|
http_port = int(reader.recv(128).decode("utf8"))
|
||||||
|
reader.close()
|
||||||
|
|
||||||
|
return http_port
|
||||||
|
|
||||||
|
def find_ovmf(args):
|
||||||
|
dirs = [
|
||||||
|
"~/.local/share/ovmf",
|
||||||
|
"/usr/share/OVMF",
|
||||||
|
"/usr/share/edk2/ovmf/"
|
||||||
|
]
|
||||||
|
if args.ovmf_dir:
|
||||||
|
dirs.append(args.ovmf_dir)
|
||||||
|
|
||||||
|
for d in dirs:
|
||||||
|
path = os.path.expanduser(d)
|
||||||
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
|
|
||||||
|
raise RuntimeError("Could not find OMVF")
|
||||||
|
|
||||||
|
# location can differ depending on how qemu is installed
|
||||||
|
def find_edk2():
|
||||||
|
dirs = [
|
||||||
|
"/usr/local/share/qemu",
|
||||||
|
"/opt/homebrew/share/qemu"
|
||||||
|
]
|
||||||
|
|
||||||
|
for d in dirs:
|
||||||
|
path = os.path.expanduser(d)
|
||||||
|
if os.path.exists(path):
|
||||||
|
return path
|
||||||
|
|
||||||
|
raise RuntimeError("Could not find edk2 directory")
|
||||||
|
|
||||||
|
def qemu_run_command(qmp_socket_path, command):
|
||||||
|
sock2 = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
sock2.connect(qmp_socket_path)
|
||||||
|
r = sock2.recv(1024)
|
||||||
|
sock2.send('{"execute":"qmp_capabilities"}\n'.encode("utf8"))
|
||||||
|
r = sock2.recv(1024)
|
||||||
|
sock2.send(f'{command}\n'.encode("utf8"))
|
||||||
|
r = sock2.recv(1024)
|
||||||
|
sock2.close()
|
||||||
|
|
||||||
|
def virtio_serial_connect(virtio_socket_path):
|
||||||
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
while True:
|
||||||
|
time.sleep(0.1)
|
||||||
|
try:
|
||||||
|
sock.connect(virtio_socket_path)
|
||||||
|
return sock
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def available_tcp_port(port_range_from = 1024):
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
port = port_range_from
|
||||||
|
port_range_to = port_range_from + 32 # limit for retry
|
||||||
|
while port < port_range_to:
|
||||||
|
try:
|
||||||
|
s.bind(('', port))
|
||||||
|
except OSError:
|
||||||
|
port += 1
|
||||||
|
continue
|
||||||
|
break
|
||||||
|
s.close()
|
||||||
|
return port
|
||||||
|
|
||||||
|
class WatchdogCommand:
|
||||||
|
START = 1
|
||||||
|
STOP = 2
|
||||||
|
|
||||||
|
def __init__(self, op, arg = None):
|
||||||
|
self.op = op
|
||||||
|
self.arg = arg
|
||||||
|
|
||||||
|
def parse_watchdog_commands(sock):
|
||||||
|
commands = []
|
||||||
|
data = sock.recv(16).decode("utf8")
|
||||||
|
for l in data.splitlines():
|
||||||
|
if l.startswith("START"):
|
||||||
|
try:
|
||||||
|
arg = int(l[5:])
|
||||||
|
except ValueError:
|
||||||
|
arg = 30 # Default if not specified
|
||||||
|
commands.append( WatchdogCommand(WatchdogCommand.START, arg) )
|
||||||
|
elif l.startswith("STOP"):
|
||||||
|
commands.append( WatchdogCommand(WatchdogCommand.STOP) )
|
||||||
|
else:
|
||||||
|
print_verbose(f"Unsupported watchdog command {l}")
|
||||||
|
return commands
|
||||||
|
|
||||||
|
def run_watchdog(watch_socket_path, qmp_socket_path):
|
||||||
|
sock = virtio_serial_connect(watch_socket_path)
|
||||||
|
|
||||||
|
p = select.poll()
|
||||||
|
p.register(sock, select.POLLIN)
|
||||||
|
|
||||||
|
watchdog_timeout = None
|
||||||
|
watchdog_delay = 30
|
||||||
|
|
||||||
|
while True:
|
||||||
|
timeout = None
|
||||||
|
if watchdog_timeout != None:
|
||||||
|
timeout = max(watchdog_timeout - time.time(), 0) * 1000
|
||||||
|
|
||||||
|
poll_res = p.poll(timeout)
|
||||||
|
|
||||||
|
if len(poll_res) > 0:
|
||||||
|
v = poll_res[0][1]
|
||||||
|
if v & select.POLLHUP:
|
||||||
|
sys.exit(0)
|
||||||
|
commands = parse_watchdog_commands(sock)
|
||||||
|
for cmd in commands:
|
||||||
|
if cmd.op == WatchdogCommand.START:
|
||||||
|
print_verbose(f"Starting watchdog for {cmd.arg} sec")
|
||||||
|
watchdog_timeout = time.time() + cmd.arg
|
||||||
|
if cmd.op == WatchdogCommand.STOP:
|
||||||
|
print_verbose(f"Stopped watchdog")
|
||||||
|
watchdog_timeout = None
|
||||||
|
|
||||||
|
if watchdog_timeout != None and time.time() >= watchdog_timeout:
|
||||||
|
print_verbose(f"Triggering watchdog")
|
||||||
|
qemu_run_command(qmp_socket_path, '{"execute": "system_reset"}')
|
||||||
|
|
||||||
|
# Queue a new timeout in case the next boot fails, until disabled
|
||||||
|
watchdog_timeout = time.time() + watchdog_delay
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(description="Boot virtual machine images")
|
||||||
|
parser.add_argument("--verbose", default=False, action="store_true")
|
||||||
|
parser.add_argument("--arch", default=platform.machine(), action="store",
|
||||||
|
help=f"Arch to run for (default {platform.machine()})")
|
||||||
|
parser.add_argument("--publish-dir", action="store",
|
||||||
|
help=f"Publish the specified directory over http in the vm")
|
||||||
|
parser.add_argument("--memory", default="2G",
|
||||||
|
help=f"Memory size (default 2G)")
|
||||||
|
parser.add_argument("--nographics", default=False, action="store_true",
|
||||||
|
help=f"Run without graphics")
|
||||||
|
parser.add_argument("--watchdog", default=False, action="store_true",
|
||||||
|
help=f"Enable watchdog")
|
||||||
|
parser.add_argument("--tpm2", default=False, action="store_true",
|
||||||
|
help=f"Enable TPM2")
|
||||||
|
parser.add_argument("--snapshot", default=False, action="store_true",
|
||||||
|
help=f"Work on a snapshot of the image")
|
||||||
|
parser.add_argument("--ovmf-dir", action="store",
|
||||||
|
help="Specify directory for OVMF files (Open Virtual Machine Firmware)")
|
||||||
|
parser.add_argument("--secureboot", dest="secureboot", action="store_true", default=False,
|
||||||
|
help="Enable SecureBoot")
|
||||||
|
parser.add_argument("--ssh-port", type=int, default=2222,
|
||||||
|
help="SSH port forwarding to SSH_PORT (default 2222)")
|
||||||
|
parser.add_argument("--cdrom", action="store",
|
||||||
|
help="Specify .iso to load")
|
||||||
|
parser.add_argument("image", type=str, help="The image to boot")
|
||||||
|
parser.add_argument('extra_args', nargs=argparse.REMAINDER, metavar="...", help="extra qemu arguments")
|
||||||
|
|
||||||
|
args = parser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
global is_verbose
|
||||||
|
is_verbose = args.verbose
|
||||||
|
|
||||||
|
# arm64 is an alias for aarch64 on macOS
|
||||||
|
if args.arch == "arm64":
|
||||||
|
args.arch = "aarch64"
|
||||||
|
|
||||||
|
qemu = find_qemu(args.arch)
|
||||||
|
accel_list = qemu_available_accels(qemu)
|
||||||
|
qemu_args = [qemu]
|
||||||
|
|
||||||
|
if args.arch == "x86_64":
|
||||||
|
machine = "q35"
|
||||||
|
default_cpu = "qemu64,+ssse3,+sse4.1,+sse4.2,+popcnt"
|
||||||
|
|
||||||
|
ovmf = find_ovmf(args)
|
||||||
|
if args.secureboot:
|
||||||
|
qemu_args += [
|
||||||
|
"-drive", f"file={ovmf}/OVMF_CODE.secboot.fd,if=pflash,format=raw,unit=0,readonly=on",
|
||||||
|
"-drive", f"file={ovmf}/OVMF_VARS.secboot.fd,if=pflash,format=raw,unit=1,snapshot=on,readonly=off",
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
qemu_args += [
|
||||||
|
"-drive", f"file={ovmf}/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on",
|
||||||
|
"-drive", f"file={ovmf}/OVMF_VARS.fd,if=pflash,format=raw,unit=1,snapshot=on,readonly=off",
|
||||||
|
]
|
||||||
|
elif args.arch == "aarch64":
|
||||||
|
machine = "virt"
|
||||||
|
default_cpu = "cortex-a57"
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
edk2 = find_edk2()
|
||||||
|
qemu_args += [
|
||||||
|
"-device", "virtio-gpu-pci", # for display
|
||||||
|
"-display", "default,show-cursor=on", # for display
|
||||||
|
"-device", "qemu-xhci", # for keyboard
|
||||||
|
"-device", "usb-kbd", # for keyboard
|
||||||
|
"-device", "usb-tablet", # for mouse
|
||||||
|
"-smp", str(os.cpu_count()), # for max cores
|
||||||
|
"-drive", f"file={edk2}/edk2-aarch64-code.fd,if=pflash,format=raw,unit=0,readonly=on",
|
||||||
|
"-drive", f"file={edk2}/edk2-arm-vars.fd,if=pflash,format=raw,unit=1,snapshot=on,readonly=off"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
qemu_args += [
|
||||||
|
"-bios", "/usr/share/edk2/aarch64/QEMU_EFI.fd",
|
||||||
|
"-boot", "efi"
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
exit_error(f"unsupported architecture {args.arch}")
|
||||||
|
|
||||||
|
accel_enabled = True
|
||||||
|
if 'kvm' in accel_list and os.path.exists("/dev/kvm"):
|
||||||
|
qemu_args += ['-enable-kvm']
|
||||||
|
elif 'hvf' in accel_list:
|
||||||
|
qemu_args += ['-accel', 'hvf']
|
||||||
|
else:
|
||||||
|
accel_enabled = False
|
||||||
|
print_verbose("Acceleration: off")
|
||||||
|
|
||||||
|
qemu_args += [
|
||||||
|
"-m", str(args.memory),
|
||||||
|
"-machine", machine,
|
||||||
|
"-cpu", "host" if accel_enabled else default_cpu
|
||||||
|
]
|
||||||
|
|
||||||
|
guestfwds=""
|
||||||
|
|
||||||
|
if args.publish_dir:
|
||||||
|
if shutil.which("netcat") is None:
|
||||||
|
print("Command `netcat` not found in path, ignoring publish-dir")
|
||||||
|
else:
|
||||||
|
httpd_port = run_http_server(args.publish_dir)
|
||||||
|
guestfwds = f"guestfwd=tcp:10.0.2.100:80-cmd:netcat 127.0.0.1 {httpd_port},"
|
||||||
|
print_verbose(f"publishing {args.publish_dir} on http://10.0.2.100/")
|
||||||
|
|
||||||
|
portfwd = {
|
||||||
|
available_tcp_port(args.ssh_port): 22
|
||||||
|
}
|
||||||
|
for local, remote in portfwd.items():
|
||||||
|
print_verbose(f"port: {local} → {remote}")
|
||||||
|
|
||||||
|
fwds = [f"hostfwd=tcp::{h}-:{g}" for h, g in portfwd.items()]
|
||||||
|
|
||||||
|
macstr = generate_mac_address()
|
||||||
|
print_verbose(f"MAC: {macstr}")
|
||||||
|
|
||||||
|
qemu_args += [
|
||||||
|
"-device", f"virtio-net-pci,netdev=n0,mac={macstr}",
|
||||||
|
"-netdev", "user,id=n0,net=10.0.2.0/24," + guestfwds + ",".join(fwds),
|
||||||
|
]
|
||||||
|
|
||||||
|
if args.nographics:
|
||||||
|
qemu_args += ["-nographic"]
|
||||||
|
|
||||||
|
runvm_id = random_id()
|
||||||
|
|
||||||
|
tmpdir = tempfile.TemporaryDirectory(prefix=f"runvm-{runvm_id}")
|
||||||
|
|
||||||
|
watchdog_pid = 0
|
||||||
|
if args.watchdog:
|
||||||
|
qmp_socket_path = os.path.join(tmpdir.name, "qmp-socket")
|
||||||
|
watch_socket_path = os.path.join(tmpdir.name, "watch-socket")
|
||||||
|
|
||||||
|
qemu_args += [
|
||||||
|
"-qmp", f"unix:{qmp_socket_path},server=on,wait=off",
|
||||||
|
"-device", "virtio-serial", "-chardev", f"socket,path={watch_socket_path},server=on,wait=off,id=watchdog",
|
||||||
|
"-device", "virtserialport,chardev=watchdog,name=watchdog.0"
|
||||||
|
]
|
||||||
|
|
||||||
|
watchdog_pid = os.fork()
|
||||||
|
if watchdog_pid == 0:
|
||||||
|
run_watchdog(watch_socket_path, qmp_socket_path)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args.tpm2:
|
||||||
|
if shutil.which("swtpm") is None:
|
||||||
|
exit_error("Command `swtpm` not found in path, this is needed for tpm2 support")
|
||||||
|
|
||||||
|
tpm2_socket = os.path.join(tmpdir.name, "tpm-socket")
|
||||||
|
|
||||||
|
if args.snapshot:
|
||||||
|
tpm2_path = os.path.join(tmpdir.name, "tpm2_state")
|
||||||
|
else:
|
||||||
|
tpm2_path = ".tpm2_state"
|
||||||
|
os.makedirs(tpm2_path, exist_ok=True)
|
||||||
|
|
||||||
|
swtpm_args = ["swtpm", "socket", "--tpm2", "--tpmstate", f"dir={tpm2_path}", "--ctrl", f"type=unixio,path={tpm2_socket}" ]
|
||||||
|
res = subprocess.Popen(swtpm_args)
|
||||||
|
|
||||||
|
qemu_args += [
|
||||||
|
"-chardev", f"socket,id=chrtpm,path={tpm2_socket}",
|
||||||
|
"-tpmdev", "emulator,id=tpm0,chardev=chrtpm",
|
||||||
|
"-device", "tpm-tis,tpmdev=tpm0"
|
||||||
|
]
|
||||||
|
|
||||||
|
print_verbose(f"Image: {args.image}")
|
||||||
|
|
||||||
|
if args.image.endswith(".raw"):
|
||||||
|
qemu_args += [
|
||||||
|
"-drive", f"file={args.image},index=0,media=disk,format=raw,if=virtio,snapshot={bool_arg(args.snapshot)}",
|
||||||
|
]
|
||||||
|
else: # assume qcow2
|
||||||
|
qemu_args += [
|
||||||
|
"-drive", f"file={args.image},index=0,media=disk,format=qcow2,if=virtio,snapshot={bool_arg(args.snapshot)}",
|
||||||
|
]
|
||||||
|
|
||||||
|
if args.cdrom:
|
||||||
|
qemu_args += [
|
||||||
|
"-cdrom", args.cdrom,
|
||||||
|
"-boot", "d"
|
||||||
|
]
|
||||||
|
|
||||||
|
qemu_args += args.extra_args
|
||||||
|
|
||||||
|
print_verbose(f"Running: {' '.join(qemu_args)}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = subprocess.run(qemu_args, check=False)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
exit_error("Aborted")
|
||||||
|
|
||||||
|
if watchdog_pid:
|
||||||
|
os.kill(watchdog_pid, signal.SIGTERM)
|
||||||
|
|
||||||
|
tmpdir.cleanup()
|
||||||
|
|
||||||
|
return res.returncode
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
def intersect(x;y):
|
||||||
|
( (x|unique) + (y|unique) | sort) as $sorted
|
||||||
|
| reduce range(1; $sorted|length) as $i
|
||||||
|
([];
|
||||||
|
if $sorted[$i] == $sorted[$i-1] then . + [$sorted[$i]] else . end) ;
|
||||||
|
|
||||||
|
def difference($a; $b):
|
||||||
|
($a | unique) - $b;
|
||||||
|
|
||||||
|
{
|
||||||
|
cs9: {
|
||||||
|
common: ((intersect($aarch64;$x86_64)) | sort_by(ascii_downcase)),
|
||||||
|
arch: {
|
||||||
|
x86_64: (($x86_64 - $aarch64) | sort_by(ascii_downcase)),
|
||||||
|
aarch64: (($aarch64 - $x86_64) | sort_by(ascii_downcase))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# SPDX-License-Identifier: MIT-0
|
||||||
|
set -e
|
||||||
|
[ "$DEBUG" == 'true' ] && set -x
|
||||||
|
|
||||||
|
ARGC=$#
|
||||||
|
if [ $ARGC -ne 3 ]; then
|
||||||
|
echo "USAGE: $(basename $0) <Image Path> <S3 Bucket Name> <AMI Image Size in GB>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
IMAGE_FILE_PATH=$1
|
||||||
|
IMPORT_BUCKET_NAME=$2
|
||||||
|
AMI_DISK_SIZE_GB=$3
|
||||||
|
|
||||||
|
declare -A ARCHS_MAP=( ["x86_64"]="x86_64" ["aarch64"]="arm64")
|
||||||
|
|
||||||
|
IMAGE_NAME="$(basename -- ${IMAGE_FILE_PATH})"
|
||||||
|
AMI_NAME="${IMAGE_NAME%.*}"
|
||||||
|
IMAGE_ARCH="${AMI_NAME##*.}"
|
||||||
|
|
||||||
|
TMPDIR=$(mktemp -d)
|
||||||
|
IMAGE_IMPORT_JSON_FILE="${TMPDIR}/image-import.json"
|
||||||
|
AMI_REGISTER_JSON_FILE="${TMPDIR}/register-ami.json"
|
||||||
|
|
||||||
|
aws s3 cp "${IMAGE_FILE_PATH}" "s3://${IMPORT_BUCKET_NAME}"
|
||||||
|
|
||||||
|
cat <<EOF > "${IMAGE_IMPORT_JSON_FILE}"
|
||||||
|
{
|
||||||
|
"Description": "CentOS Stream 9 with Container support",
|
||||||
|
"Format": "RAW",
|
||||||
|
"UserBucket": {
|
||||||
|
"S3Bucket": "${IMPORT_BUCKET_NAME}",
|
||||||
|
"S3Key": "${IMAGE_NAME}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "Importing image file into snapshot "
|
||||||
|
IMPORT_TASK_ID=$(aws ec2 import-snapshot --disk-container "file://${IMAGE_IMPORT_JSON_FILE}" | jq -r '.ImportTaskId')
|
||||||
|
|
||||||
|
IMPORT_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
|
||||||
|
x=0
|
||||||
|
while [ "$IMPORT_STATUS" = "active" ] && [ $x -lt 120 ]
|
||||||
|
do
|
||||||
|
IMPORT_STATUS=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.Status')
|
||||||
|
IMPORT_STATUS_MSG=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.StatusMessage')
|
||||||
|
echo "Import Status: ${IMPORT_STATUS} / ${IMPORT_STATUS_MSG}"
|
||||||
|
x=$(( $x + 1 ))
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
if [ $x -eq 120 ]; then
|
||||||
|
echo "ERROR: Import task taking too long, exiting..."; exit 1;
|
||||||
|
elif [ "$IMPORT_STATUS" = "completed" ]; then
|
||||||
|
echo "Import completed Successfully"
|
||||||
|
else
|
||||||
|
echo "Import Failed, exiting"; exit 2;
|
||||||
|
fi
|
||||||
|
|
||||||
|
SNAPSHOT_ID=$(aws ec2 describe-import-snapshot-tasks --import-task-ids $IMPORT_TASK_ID | jq -r '.ImportSnapshotTasks[].SnapshotTaskDetail.SnapshotId')
|
||||||
|
|
||||||
|
aws ec2 wait snapshot-completed --snapshot-ids $SNAPSHOT_ID
|
||||||
|
|
||||||
|
|
||||||
|
echo "Registering AMI with Snapshot $SNAPSHOT_ID"
|
||||||
|
cat <<EOF > "${AMI_REGISTER_JSON_FILE}"
|
||||||
|
{
|
||||||
|
"Architecture": "${ARCHS_MAP[$IMAGE_ARCH]}",
|
||||||
|
"BlockDeviceMappings": [
|
||||||
|
{
|
||||||
|
"DeviceName": "/dev/sda1",
|
||||||
|
"Ebs": {
|
||||||
|
"DeleteOnTermination": true,
|
||||||
|
"SnapshotId": "${SNAPSHOT_ID}",
|
||||||
|
"VolumeSize": ${AMI_DISK_SIZE_GB},
|
||||||
|
"VolumeType": "gp2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Description": "CS9 image with container support for ${IMAGE_ARCH}",
|
||||||
|
"RootDeviceName": "/dev/sda1",
|
||||||
|
"BootMode": "uefi",
|
||||||
|
"VirtualizationType": "hvm",
|
||||||
|
"EnaSupport": true
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
aws ec2 register-image --name ${AMI_NAME} --cli-input-json="file://${AMI_REGISTER_JSON_FILE}"
|
||||||
|
echo "AMI name: "${AMI_NAME}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
def basenames:
|
||||||
|
.path | split("/") | last;
|
||||||
|
|
||||||
|
def parseURL:
|
||||||
|
capture("^((?<scheme>[^:/?#]+):)?(//(?<authority>(?<domain>[^/?#:]*)(:(?<port>[0-9]*))?))?(?<path>[^?#]*)(\\?(?<query>([^#]*)))?(#(?<fragment>(.*)))?");
|
||||||
|
|
||||||
|
def splitRPM:
|
||||||
|
capture("(?<name>(.*))\\.(?<arch>[a-zA-Z0-9_]+).rpm");
|
||||||
|
|
||||||
|
def manifestUrls:
|
||||||
|
.sources["org.osbuild.curl"].items | to_entries[] | .value | parseURL;
|
||||||
|
|
||||||
|
def urlsToRpms:
|
||||||
|
basenames | splitRPM;
|
||||||
|
|
||||||
|
def mergeArches:
|
||||||
|
reduce .[] as $item ({}; .[$item.arch][$item.name] = true) | with_entries(.value = (.value | keys));
|
||||||
|
|
||||||
|
manifestUrls | select(.domain == "mirror.stream.centos.org") | urlsToRpms | .name
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# Generates single-file from-scratch and delta update files for all or some of the
|
||||||
|
# refs in an OSTree repo.
|
||||||
|
#
|
||||||
|
# To use it run "generate-deltas REPODIR DESTDIR" which will look at all the refs in the
|
||||||
|
# repo and make updates to the latest version putting them in the DESTDIR directory.
|
||||||
|
|
||||||
|
# To apply these on a live system, do something like:
|
||||||
|
# $ ostree static-delta apply-offline cs9-x86_64-qemu-upgrade-demo-79da0b2f1b119e99137eaef9680fae9820a9edcd5cac4f6d7c23279498c578f6.update
|
||||||
|
# $ rpm-ostree rebase 79da0b2f1b119e99137eaef9680fae9820a9edcd5cac4f6d7c23279498c578f6
|
||||||
|
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
echo "Usage generate-deltas REPODIR DESTDIR [REFS..]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
REPO=$1
|
||||||
|
DIR=$2
|
||||||
|
|
||||||
|
shift 2
|
||||||
|
|
||||||
|
if [ "$#" -gt 0 ]; then
|
||||||
|
REFS="$@"
|
||||||
|
else
|
||||||
|
REFS=$(ostree --repo=$REPO refs)
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $DIR
|
||||||
|
|
||||||
|
NUM_DELTAS=3
|
||||||
|
for REF in $REFS; do
|
||||||
|
REF_AS_FILE=$(echo $REF | sed "s%/%-%g" )
|
||||||
|
HEAD=$(ostree --repo=$REPO rev-parse $REF)
|
||||||
|
|
||||||
|
# Generate full update for HEAD:
|
||||||
|
echo Generating non-delta update for $REF commit $HEAD
|
||||||
|
ostree static-delta generate --repo=$REPO --inline --min-fallback-size=0 --empty --filename=$DIR/$REF_AS_FILE-$HEAD.update $HEAD
|
||||||
|
|
||||||
|
# Generate deltas to HEAD from up to the last 3 parents
|
||||||
|
PARENT=$HEAD
|
||||||
|
for i in seq $NUM_DELTAS; do
|
||||||
|
if ! PARENT=$(ostree --repo=$REPO rev-parse $PARENT^ 2>/dev/null); then
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
echo Generating delta update for $REF commit $HEAD from commit $PARENT
|
||||||
|
ostree static-delta generate --repo=$REPO --inline --min-fallback-size=0 --from=$PARENT --filename=$DIR/$REF_AS_FILE-$PARENT-$HEAD.update $HEAD
|
||||||
|
done
|
||||||
|
|
||||||
|
done
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This is a helper used by the makefile to handle the OSTREE_REPO mpp
|
||||||
|
# support. It creates a json dict mapping all the refs in the repo
|
||||||
|
# (if it exists) to the latest commit. This is then passed to osbuild-mpp
|
||||||
|
# as the ostree_parent_refs variable that is used by the manifests to pick
|
||||||
|
# the right parent commit.
|
||||||
|
|
||||||
|
REPOPATH=$1
|
||||||
|
FIRST=1
|
||||||
|
echo -n "{"
|
||||||
|
if test -d $REPOPATH; then
|
||||||
|
for ref in $(ostree refs --repo=$REPOPATH); do
|
||||||
|
if [ $FIRST == 1 ]; then
|
||||||
|
FIRST=0
|
||||||
|
else
|
||||||
|
echo -n ,
|
||||||
|
fi
|
||||||
|
echo -n \"$ref\":\"$(ostree rev-parse --repo=$REPOPATH $ref)\"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
echo -n "}"
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# This is a helper for the makefile rule to build a particular image
|
||||||
|
# from the preprocessed json manifest. It is a shellscript rather
|
||||||
|
# than just some make lines because some of the complexities just
|
||||||
|
# are painful to do in make.
|
||||||
|
#
|
||||||
|
# Features:
|
||||||
|
#
|
||||||
|
# * Knows what target to export based on the extensions.
|
||||||
|
# * Knows what the exported filename based on the extensions.
|
||||||
|
# * Supports building natively or in a VM via osbuildvm.
|
||||||
|
# * Runs only the minimal required commands as root, and
|
||||||
|
# chowns the resulting files to the user
|
||||||
|
# * Supports exporting an extra ostree commit and pulling that
|
||||||
|
# into an existing repo.
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DEST="$1"
|
||||||
|
JSON="$2"
|
||||||
|
TARGET="$3"
|
||||||
|
IMAGETYPE="$4"
|
||||||
|
ARCH="$5"
|
||||||
|
EXTENSION="$6"
|
||||||
|
|
||||||
|
# Map extension => export pipeline name
|
||||||
|
declare -A EXPORT_BY_EXT
|
||||||
|
EXPORT_BY_EXT[img]=image
|
||||||
|
EXPORT_BY_EXT[oci.tar]=container
|
||||||
|
EXPORT_BY_EXT[qcow2]=qcow2
|
||||||
|
EXPORT_BY_EXT[repo]=ostree-commit
|
||||||
|
EXPORT_BY_EXT[rootfs]=rootfs
|
||||||
|
EXPORT_BY_EXT[ext4]=ext4
|
||||||
|
EXPORT_BY_EXT[tar]=tar
|
||||||
|
|
||||||
|
# Map extension to name of exported file by pipeline
|
||||||
|
declare -A EXPORT_FILE_BY_EXT
|
||||||
|
EXPORT_FILE_BY_EXT[img]=disk.img
|
||||||
|
EXPORT_FILE_BY_EXT[qcow2]=disk.qcow2
|
||||||
|
EXPORT_FILE_BY_EXT[oci.tar]=container.tar
|
||||||
|
EXPORT_FILE_BY_EXT[repo]=repo
|
||||||
|
EXPORT_FILE_BY_EXT[rootfs]=
|
||||||
|
EXPORT_FILE_BY_EXT[ext4]=rootfs.ext4
|
||||||
|
EXPORT_FILE_BY_EXT[tar]=rootfs.tar
|
||||||
|
|
||||||
|
EXPORT=${EXPORT_BY_EXT[${EXTENSION}]}
|
||||||
|
EXPORT_FILE=${EXPORT_FILE_BY_EXT[${EXTENSION}]}
|
||||||
|
|
||||||
|
HOST_ARCH=$(arch)
|
||||||
|
CURRENT_UIDGID="$(id -u):$(id -g)"
|
||||||
|
|
||||||
|
if [ $ARCH == $HOST_ARCH -a $VM == 0 ]; then
|
||||||
|
SUDO="sudo"
|
||||||
|
OSBUILD="sudo osbuild"
|
||||||
|
else
|
||||||
|
SUDO=
|
||||||
|
OSBUILD="osbuildvm/osbuildvm --arch=$ARCH"
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXPORT_ARGS="--export $EXPORT"
|
||||||
|
|
||||||
|
CHECKPOINT_ARGS=
|
||||||
|
for CP in $CHECKPOINTS; do
|
||||||
|
CHECKPOINT_ARGS="${CHECKPOINT_ARGS} --checkpoint ${CP}"
|
||||||
|
done
|
||||||
|
|
||||||
|
CHOWNARGS=
|
||||||
|
if [ $EXTENSION == repo ]; then
|
||||||
|
CHOWNARGS=-R # Chown entire repo dir as it doesn't care about permissions
|
||||||
|
fi
|
||||||
|
|
||||||
|
EXPORTDIRS=$OUTPUTDIR/$EXPORT
|
||||||
|
|
||||||
|
# If OSTREE_REPO is set, and we're building an image that has an
|
||||||
|
# ostree commit, then we also export that commit to the repo specified
|
||||||
|
# by OSTREE_REPO.
|
||||||
|
ALSO_EXPORT_OSTREE=0
|
||||||
|
if [ "$OSTREE_REPO" != "" -a "$IMAGETYPE" == "ostree" ]; then
|
||||||
|
ALSO_EXPORT_OSTREE=1
|
||||||
|
if [ $EXPORT != "ostree-commit" ]; then
|
||||||
|
EXPORT_ARGS="$EXPORT_ARGS --export ostree-commit"
|
||||||
|
EXPORTDIRS="$EXPORTDIRS $OUTPUTDIR/ostree-commit"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure we have a repo to export to
|
||||||
|
ostree init --repo=$OSTREE_REPO --mode archive
|
||||||
|
fi
|
||||||
|
|
||||||
|
set -x
|
||||||
|
|
||||||
|
$SUDO rm -rf $EXPORTDIRS
|
||||||
|
mkdir -p $EXPORTDIRS # Own export dirs by user, not root
|
||||||
|
|
||||||
|
$OSBUILD $CHECKPOINT_ARGS --store $STOREDIR --output-directory $OUTPUTDIR $EXPORT_ARGS $OSBUILD_ARGS $JSON
|
||||||
|
|
||||||
|
if [ $ALSO_EXPORT_OSTREE == "1" ]; then
|
||||||
|
ostree pull-local --repo=$OSTREE_REPO $OUTPUTDIR/ostree-commit/repo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract and chown exported file
|
||||||
|
rm -rf $DEST
|
||||||
|
$SUDO chown $CHOWNARGS $CURRENT_UIDGID $OUTPUTDIR/$EXPORT/$EXPORT_FILE
|
||||||
|
$SUDO mv $OUTPUTDIR/$EXPORT/$EXPORT_FILE $DEST
|
||||||
|
|
||||||
|
$SUDO rm -rf $EXPORTDIRS
|
||||||
|
|
@ -0,0 +1,602 @@
|
||||||
|
{
|
||||||
|
"cs9": {
|
||||||
|
"common": [
|
||||||
|
"acl-2.3.1-3.el9",
|
||||||
|
"alsa-lib-1.2.7.2-1.el9",
|
||||||
|
"alternatives-1.20-2.el9",
|
||||||
|
"annobin-10.73-3.el9",
|
||||||
|
"audit-3.0.7-103.el9",
|
||||||
|
"audit-libs-3.0.7-103.el9",
|
||||||
|
"autoconf-2.69-38.el9",
|
||||||
|
"automake-1.16.2-6.el9",
|
||||||
|
"basesystem-11-13.el9",
|
||||||
|
"bash-5.1.8-4.el9",
|
||||||
|
"bc-1.07.1-14.el9",
|
||||||
|
"binutils-2.35.2-24.el9",
|
||||||
|
"binutils-gold-2.35.2-24.el9",
|
||||||
|
"bison-3.7.4-5.el9",
|
||||||
|
"boost-1.75.0-8.el9",
|
||||||
|
"boost-atomic-1.75.0-8.el9",
|
||||||
|
"boost-chrono-1.75.0-8.el9",
|
||||||
|
"boost-container-1.75.0-8.el9",
|
||||||
|
"boost-context-1.75.0-8.el9",
|
||||||
|
"boost-contract-1.75.0-8.el9",
|
||||||
|
"boost-coroutine-1.75.0-8.el9",
|
||||||
|
"boost-date-time-1.75.0-8.el9",
|
||||||
|
"boost-devel-1.75.0-8.el9",
|
||||||
|
"boost-fiber-1.75.0-8.el9",
|
||||||
|
"boost-filesystem-1.75.0-8.el9",
|
||||||
|
"boost-graph-1.75.0-8.el9",
|
||||||
|
"boost-iostreams-1.75.0-8.el9",
|
||||||
|
"boost-locale-1.75.0-8.el9",
|
||||||
|
"boost-log-1.75.0-8.el9",
|
||||||
|
"boost-math-1.75.0-8.el9",
|
||||||
|
"boost-nowide-1.75.0-8.el9",
|
||||||
|
"boost-numpy3-1.75.0-8.el9",
|
||||||
|
"boost-program-options-1.75.0-8.el9",
|
||||||
|
"boost-python3-1.75.0-8.el9",
|
||||||
|
"boost-random-1.75.0-8.el9",
|
||||||
|
"boost-regex-1.75.0-8.el9",
|
||||||
|
"boost-serialization-1.75.0-8.el9",
|
||||||
|
"boost-stacktrace-1.75.0-8.el9",
|
||||||
|
"boost-system-1.75.0-8.el9",
|
||||||
|
"boost-test-1.75.0-8.el9",
|
||||||
|
"boost-thread-1.75.0-8.el9",
|
||||||
|
"boost-timer-1.75.0-8.el9",
|
||||||
|
"boost-type_erasure-1.75.0-8.el9",
|
||||||
|
"boost-wave-1.75.0-8.el9",
|
||||||
|
"brotli-1.0.9-6.el9",
|
||||||
|
"brotli-devel-1.0.9-6.el9",
|
||||||
|
"bubblewrap-0.4.1-6.el9",
|
||||||
|
"bzip2-1.0.8-8.el9",
|
||||||
|
"bzip2-devel-1.0.8-8.el9",
|
||||||
|
"bzip2-libs-1.0.8-8.el9",
|
||||||
|
"ca-certificates-2022.2.54-90.0.el9",
|
||||||
|
"cairo-1.17.4-7.el9",
|
||||||
|
"centos-gpg-keys-9.0-12.el9",
|
||||||
|
"centos-stream-release-9.0-12.el9",
|
||||||
|
"centos-stream-repos-9.0-12.el9",
|
||||||
|
"checkpolicy-3.4-1.el9",
|
||||||
|
"chrony-4.2-1.el9",
|
||||||
|
"clevis-18-102.el9",
|
||||||
|
"cmake-3.20.2-7.el9",
|
||||||
|
"cmake-data-3.20.2-7.el9",
|
||||||
|
"cmake-filesystem-3.20.2-7.el9",
|
||||||
|
"cmake-rpm-macros-3.20.2-7.el9",
|
||||||
|
"conmon-2.1.2-2.el9",
|
||||||
|
"container-selinux-2.189.0-1.el9",
|
||||||
|
"containers-common-1-39.el9",
|
||||||
|
"coreutils-8.32-32.el9",
|
||||||
|
"coreutils-common-8.32-32.el9",
|
||||||
|
"cpio-2.13-16.el9",
|
||||||
|
"cpp-11.3.1-2.1.el9",
|
||||||
|
"cracklib-2.9.6-27.el9",
|
||||||
|
"cracklib-dicts-2.9.6-27.el9",
|
||||||
|
"criu-3.17-2.el9",
|
||||||
|
"criu-libs-3.17-2.el9",
|
||||||
|
"crun-1.4.5-2.el9",
|
||||||
|
"crypto-policies-20220427-1.gitb2323a1.el9",
|
||||||
|
"cryptsetup-2.4.3-4.el9",
|
||||||
|
"cryptsetup-libs-2.4.3-4.el9",
|
||||||
|
"curl-7.76.1-18.el9",
|
||||||
|
"cyrus-sasl-lib-2.1.27-20.el9",
|
||||||
|
"dbus-1.12.20-5.el9",
|
||||||
|
"dbus-broker-28-5.el9",
|
||||||
|
"dbus-common-1.12.20-5.el9",
|
||||||
|
"dbus-libs-1.12.20-5.el9",
|
||||||
|
"dejavu-sans-fonts-2.37-18.el9",
|
||||||
|
"device-mapper-1.02.185-1.el9",
|
||||||
|
"device-mapper-event-1.02.185-1.el9",
|
||||||
|
"device-mapper-event-libs-1.02.185-1.el9",
|
||||||
|
"device-mapper-libs-1.02.185-1.el9",
|
||||||
|
"device-mapper-persistent-data-0.9.0-13.el9",
|
||||||
|
"dhcp-client-4.4.2-17.b1.el9",
|
||||||
|
"dhcp-common-4.4.2-17.b1.el9",
|
||||||
|
"diffutils-3.7-12.el9",
|
||||||
|
"dnf-4.12.0-2.el9",
|
||||||
|
"dnf-data-4.12.0-2.el9",
|
||||||
|
"dosfstools-4.2-3.el9",
|
||||||
|
"dracut-057-10.git20220721.el9",
|
||||||
|
"dracut-config-generic-057-10.git20220721.el9",
|
||||||
|
"dwarves-1.22-1.el9",
|
||||||
|
"dwz-0.14-3.el9",
|
||||||
|
"e2fsprogs-1.46.5-3.el9",
|
||||||
|
"e2fsprogs-libs-1.46.5-3.el9",
|
||||||
|
"ed-1.14.2-12.el9",
|
||||||
|
"efi-filesystem-4-8.el9",
|
||||||
|
"efi-srpm-macros-4-8.el9",
|
||||||
|
"efibootmgr-16-12.el9",
|
||||||
|
"efivar-libs-38-2.el9",
|
||||||
|
"elfutils-0.187-5.el9",
|
||||||
|
"elfutils-debuginfod-client-0.187-5.el9",
|
||||||
|
"elfutils-default-yama-scope-0.187-5.el9",
|
||||||
|
"elfutils-devel-0.187-5.el9",
|
||||||
|
"elfutils-libelf-0.187-5.el9",
|
||||||
|
"elfutils-libelf-devel-0.187-5.el9",
|
||||||
|
"elfutils-libs-0.187-5.el9",
|
||||||
|
"emacs-common-27.1-3.el9",
|
||||||
|
"emacs-filesystem-27.1-3.el9",
|
||||||
|
"emacs-nox-27.1-3.el9",
|
||||||
|
"expat-2.4.7-1.el9",
|
||||||
|
"file-5.39-8.el9",
|
||||||
|
"file-libs-5.39-8.el9",
|
||||||
|
"filesystem-3.16-2.el9",
|
||||||
|
"findutils-4.8.0-5.el9",
|
||||||
|
"flex-2.6.4-9.el9",
|
||||||
|
"flexiblas-3.0.4-8.el9",
|
||||||
|
"flexiblas-netlib-3.0.4-8.el9",
|
||||||
|
"flexiblas-openblas-openmp-3.0.4-8.el9",
|
||||||
|
"fontconfig-2.14.0-1.el9",
|
||||||
|
"fonts-filesystem-2.0.5-7.el9.1",
|
||||||
|
"fonts-srpm-macros-2.0.5-7.el9.1",
|
||||||
|
"freetype-2.10.4-9.el9",
|
||||||
|
"freetype-devel-2.10.4-9.el9",
|
||||||
|
"fuse-2.9.9-15.el9",
|
||||||
|
"fuse-common-3.10.2-5.el9",
|
||||||
|
"fuse-libs-2.9.9-15.el9",
|
||||||
|
"fuse-overlayfs-1.9-1.el9",
|
||||||
|
"fuse3-3.10.2-5.el9",
|
||||||
|
"fuse3-libs-3.10.2-5.el9",
|
||||||
|
"fwupd-1.5.9-3.el9",
|
||||||
|
"gawk-5.1.0-6.el9",
|
||||||
|
"gawk-all-langpacks-5.1.0-6.el9",
|
||||||
|
"gcc-11.3.1-2.1.el9",
|
||||||
|
"gcc-c++-11.3.1-2.1.el9",
|
||||||
|
"gcc-plugin-annobin-11.3.1-2.1.el9",
|
||||||
|
"gcc-plugin-devel-11.3.1-2.1.el9",
|
||||||
|
"gdb-10.2-10.el9",
|
||||||
|
"gdb-headless-10.2-10.el9",
|
||||||
|
"gdbm-libs-1.19-4.el9",
|
||||||
|
"gettext-0.21-7.el9",
|
||||||
|
"gettext-libs-0.21-7.el9",
|
||||||
|
"ghc-srpm-macros-1.5.0-6.el9",
|
||||||
|
"git-2.31.1-2.el9.2",
|
||||||
|
"git-core-2.31.1-2.el9.2",
|
||||||
|
"git-core-doc-2.31.1-2.el9.2",
|
||||||
|
"glib2-2.68.4-5.el9",
|
||||||
|
"glib2-devel-2.68.4-5.el9",
|
||||||
|
"glibc-2.34-39.el9",
|
||||||
|
"glibc-common-2.34-39.el9",
|
||||||
|
"glibc-devel-2.34-39.el9",
|
||||||
|
"glibc-gconv-extra-2.34-39.el9",
|
||||||
|
"glibc-langpack-en-2.34-39.el9",
|
||||||
|
"gmp-6.2.0-10.el9",
|
||||||
|
"gmp-c++-6.2.0-10.el9",
|
||||||
|
"gmp-devel-6.2.0-10.el9",
|
||||||
|
"gnupg2-2.3.3-1.el9",
|
||||||
|
"gnutls-3.7.3-10.el9",
|
||||||
|
"go-srpm-macros-3.0.9-9.el9",
|
||||||
|
"gpgme-1.15.1-6.el9",
|
||||||
|
"gpm-libs-1.20.7-29.el9",
|
||||||
|
"graphite2-1.3.14-9.el9",
|
||||||
|
"graphite2-devel-1.3.14-9.el9",
|
||||||
|
"greenboot-0.14.0-3.el9",
|
||||||
|
"grep-3.6-5.el9",
|
||||||
|
"groff-base-1.22.4-10.el9",
|
||||||
|
"grub2-common-2.06-38.el9",
|
||||||
|
"grub2-tools-2.06-38.el9",
|
||||||
|
"grub2-tools-minimal-2.06-38.el9",
|
||||||
|
"gzip-1.12-1.el9",
|
||||||
|
"harfbuzz-2.7.4-8.el9",
|
||||||
|
"harfbuzz-devel-2.7.4-8.el9",
|
||||||
|
"harfbuzz-icu-2.7.4-8.el9",
|
||||||
|
"hostapd-2.10-1.el9",
|
||||||
|
"hostname-3.23-6.el9",
|
||||||
|
"ima-evm-utils-1.4-4.el9",
|
||||||
|
"info-6.7-15.el9",
|
||||||
|
"inih-49-6.el9",
|
||||||
|
"initscripts-service-10.11.4-1.el9",
|
||||||
|
"ipcalc-1.0.0-5.el9",
|
||||||
|
"iproute-5.18.0-1.el9",
|
||||||
|
"iptables-libs-1.8.8-2.el9",
|
||||||
|
"iptables-nft-1.8.8-2.el9",
|
||||||
|
"iputils-20210202-7.el9",
|
||||||
|
"jansson-2.14-1.el9",
|
||||||
|
"jbigkit-libs-2.1-23.el9",
|
||||||
|
"jitterentropy-3.4.0-1.el9",
|
||||||
|
"jose-11-3.el9",
|
||||||
|
"jq-1.6-9.el9",
|
||||||
|
"json-c-0.14-11.el9",
|
||||||
|
"json-glib-1.6.6-1.el9",
|
||||||
|
"kbd-2.4.0-8.el9",
|
||||||
|
"kbd-misc-2.4.0-8.el9",
|
||||||
|
"kernel-automotive-5.14.0-133.95.el9s",
|
||||||
|
"kernel-automotive-core-5.14.0-133.95.el9s",
|
||||||
|
"kernel-automotive-modules-5.14.0-133.95.el9s",
|
||||||
|
"kernel-headers-5.14.0-134.el9",
|
||||||
|
"kernel-srpm-macros-1.0-11.el9",
|
||||||
|
"keyutils-libs-1.6.1-4.el9",
|
||||||
|
"kmod-28-7.el9",
|
||||||
|
"kmod-libs-28-7.el9",
|
||||||
|
"kpartx-0.8.7-10.el9",
|
||||||
|
"krb5-libs-1.19.1-22.el9",
|
||||||
|
"langpacks-core-font-en-3.0-16.el9",
|
||||||
|
"less-590-1.el9",
|
||||||
|
"libacl-2.3.1-3.el9",
|
||||||
|
"libaio-0.3.111-13.el9",
|
||||||
|
"libarchive-3.5.3-3.el9",
|
||||||
|
"libassuan-2.5.5-3.el9",
|
||||||
|
"libattr-2.5.1-3.el9",
|
||||||
|
"libbabeltrace-1.5.8-10.el9",
|
||||||
|
"libblkid-2.37.4-3.el9",
|
||||||
|
"libblkid-devel-2.37.4-3.el9",
|
||||||
|
"libbpf-0.6.0-1.el9",
|
||||||
|
"libbrotli-1.0.9-6.el9",
|
||||||
|
"libcap-2.48-8.el9",
|
||||||
|
"libcap-ng-0.8.2-7.el9",
|
||||||
|
"libcbor-0.7.0-5.el9",
|
||||||
|
"libcom_err-1.46.5-3.el9",
|
||||||
|
"libcomps-0.1.18-1.el9",
|
||||||
|
"libcurl-7.76.1-18.el9",
|
||||||
|
"libcurl-devel-7.76.1-18.el9",
|
||||||
|
"libdb-5.3.28-53.el9",
|
||||||
|
"libdnf-0.67.0-1.el9",
|
||||||
|
"libdwarves1-1.22-1.el9",
|
||||||
|
"libeconf-0.4.1-2.el9",
|
||||||
|
"libedit-3.1-37.20210216cvs.el9",
|
||||||
|
"libestr-0.1.11-4.el9",
|
||||||
|
"libevent-2.1.12-6.el9",
|
||||||
|
"libfastjson-0.99.9-3.el9",
|
||||||
|
"libfdisk-2.37.4-3.el9",
|
||||||
|
"libffi-3.4.2-7.el9",
|
||||||
|
"libffi-devel-3.4.2-7.el9",
|
||||||
|
"libfido2-1.6.0-7.el9",
|
||||||
|
"libgcab1-1.4-6.el9",
|
||||||
|
"libgcc-11.3.1-2.1.el9",
|
||||||
|
"libgcrypt-1.10.0-4.el9",
|
||||||
|
"libgfortran-11.3.1-2.1.el9",
|
||||||
|
"libgomp-11.3.1-2.1.el9",
|
||||||
|
"libgpg-error-1.42-5.el9",
|
||||||
|
"libgudev-237-1.el9",
|
||||||
|
"libgusb-0.3.6-3.el9",
|
||||||
|
"libibverbs-37.2-1.el9",
|
||||||
|
"libicu-67.1-9.el9",
|
||||||
|
"libicu-devel-67.1-9.el9",
|
||||||
|
"libidn2-2.3.0-7.el9",
|
||||||
|
"libjcat-0.1.6-3.el9",
|
||||||
|
"libjose-11-3.el9",
|
||||||
|
"libjpeg-turbo-2.0.90-5.el9",
|
||||||
|
"libjpeg-turbo-devel-2.0.90-5.el9",
|
||||||
|
"libkcapi-1.3.1-3.el9",
|
||||||
|
"libkcapi-hmaccalc-1.3.1-3.el9",
|
||||||
|
"libksba-1.5.1-4.el9",
|
||||||
|
"liblockfile-1.14-9.el9",
|
||||||
|
"libluksmeta-9-12.el9",
|
||||||
|
"libmnl-1.0.4-15.el9",
|
||||||
|
"libmodulemd-2.13.0-2.el9",
|
||||||
|
"libmount-2.37.4-3.el9",
|
||||||
|
"libmount-devel-2.37.4-3.el9",
|
||||||
|
"libmpc-1.2.1-4.el9",
|
||||||
|
"libmpc-devel-1.2.1-4.el9",
|
||||||
|
"libndp-1.8-4.el9",
|
||||||
|
"libnet-1.2-6.el9",
|
||||||
|
"libnetfilter_conntrack-1.0.8-4.el9",
|
||||||
|
"libnfnetlink-1.0.1-21.el9",
|
||||||
|
"libnftnl-1.2.2-1.el9",
|
||||||
|
"libnghttp2-1.43.0-5.el9",
|
||||||
|
"libnl3-3.7.0-1.el9",
|
||||||
|
"libogg-1.3.4-6.el9",
|
||||||
|
"libogg-devel-1.3.4-6.el9",
|
||||||
|
"libpcap-1.10.0-4.el9",
|
||||||
|
"libpkgconf-1.7.3-9.el9",
|
||||||
|
"libpng-1.6.37-12.el9",
|
||||||
|
"libpng-devel-1.6.37-12.el9",
|
||||||
|
"libpsl-0.21.1-5.el9",
|
||||||
|
"libpwquality-1.4.4-8.el9",
|
||||||
|
"libqb-2.0.6-1.el9",
|
||||||
|
"librepo-1.14.2-2.el9",
|
||||||
|
"libreport-filesystem-2.15.2-6.el9",
|
||||||
|
"libseccomp-2.5.2-2.el9",
|
||||||
|
"libselinux-3.4-3.el9",
|
||||||
|
"libselinux-devel-3.4-3.el9",
|
||||||
|
"libselinux-utils-3.4-3.el9",
|
||||||
|
"libsemanage-3.4-1.el9",
|
||||||
|
"libsepol-3.4-1.1.el9",
|
||||||
|
"libsepol-devel-3.4-1.1.el9",
|
||||||
|
"libsigsegv-2.13-4.el9",
|
||||||
|
"libslirp-4.4.0-4.el9",
|
||||||
|
"libsmartcols-2.37.4-3.el9",
|
||||||
|
"libsolv-0.7.22-1.el9",
|
||||||
|
"libss-1.46.5-3.el9",
|
||||||
|
"libssh-0.9.6-3.el9",
|
||||||
|
"libssh-config-0.9.6-3.el9",
|
||||||
|
"libstdc++-11.3.1-2.1.el9",
|
||||||
|
"libstdc++-devel-11.3.1-2.1.el9",
|
||||||
|
"libtasn1-4.16.0-7.el9",
|
||||||
|
"libtiff-4.4.0-2.el9",
|
||||||
|
"libtiff-devel-4.4.0-2.el9",
|
||||||
|
"libtool-2.4.6-45.el9",
|
||||||
|
"libunistring-0.9.10-15.el9",
|
||||||
|
"libusbx-1.0.26-1.el9",
|
||||||
|
"libuser-0.63-7.el9",
|
||||||
|
"libutempter-1.2.1-6.el9",
|
||||||
|
"libuuid-2.37.4-3.el9",
|
||||||
|
"libuv-1.42.0-1.el9",
|
||||||
|
"libverto-0.3.2-3.el9",
|
||||||
|
"libvorbis-1.3.7-5.el9",
|
||||||
|
"libvorbis-devel-1.3.7-5.el9",
|
||||||
|
"libwebp-1.2.0-3.el9",
|
||||||
|
"libwebp-devel-1.2.0-3.el9",
|
||||||
|
"libX11-1.7.0-7.el9",
|
||||||
|
"libX11-common-1.7.0-7.el9",
|
||||||
|
"libXau-1.0.9-8.el9",
|
||||||
|
"libxcb-1.13.1-9.el9",
|
||||||
|
"libxcrypt-4.4.18-3.el9",
|
||||||
|
"libxcrypt-compat-4.4.18-3.el9",
|
||||||
|
"libxcrypt-devel-4.4.18-3.el9",
|
||||||
|
"libXext-1.3.4-8.el9",
|
||||||
|
"libxml2-2.9.13-2.el9",
|
||||||
|
"libxmlb-0.3.3-1.el9",
|
||||||
|
"libXrender-0.9.10-16.el9",
|
||||||
|
"libyaml-0.2.5-7.el9",
|
||||||
|
"libzstd-1.5.1-2.el9",
|
||||||
|
"libzstd-devel-1.5.1-2.el9",
|
||||||
|
"linux-firmware-automotive-20220310-132.el9s",
|
||||||
|
"linux-firmware-whence-20220509-126.el9",
|
||||||
|
"llvm-libs-14.0.5-1.el9",
|
||||||
|
"lua-libs-5.4.2-4.el9",
|
||||||
|
"lua-srpm-macros-1-6.el9",
|
||||||
|
"luksmeta-9-12.el9",
|
||||||
|
"lvm2-2.03.16-1.el9",
|
||||||
|
"lvm2-libs-2.03.16-1.el9",
|
||||||
|
"lz4-libs-1.9.3-5.el9",
|
||||||
|
"m4-1.4.19-1.el9",
|
||||||
|
"make-4.3-7.el9",
|
||||||
|
"memstrack-0.2.4-1.el9",
|
||||||
|
"mokutil-0.4.0-9.el9",
|
||||||
|
"mpfr-4.1.0-7.el9",
|
||||||
|
"mpfr-devel-4.1.0-7.el9",
|
||||||
|
"mtools-4.0.26-4.el9",
|
||||||
|
"nano-5.6.1-5.el9",
|
||||||
|
"ncurses-6.2-8.20210508.el9",
|
||||||
|
"ncurses-base-6.2-8.20210508.el9",
|
||||||
|
"ncurses-c++-libs-6.2-8.20210508.el9",
|
||||||
|
"ncurses-devel-6.2-8.20210508.el9",
|
||||||
|
"ncurses-libs-6.2-8.20210508.el9",
|
||||||
|
"net-tools-2.0-0.62.20160912git.el9",
|
||||||
|
"netavark-1.0.1-39.el9",
|
||||||
|
"nettle-3.7.3-2.el9",
|
||||||
|
"NetworkManager-1.39.10-1.el9",
|
||||||
|
"NetworkManager-libnm-1.39.10-1.el9",
|
||||||
|
"nftables-1.0.4-2.el9",
|
||||||
|
"npth-1.6-8.el9",
|
||||||
|
"nss-altfiles-2.18.1-20.el9",
|
||||||
|
"ocaml-srpm-macros-6-6.el9",
|
||||||
|
"oniguruma-6.9.6-1.el9.5",
|
||||||
|
"openblas-0.3.15-3.el9",
|
||||||
|
"openblas-openmp-0.3.15-3.el9",
|
||||||
|
"openblas-srpm-macros-2-11.el9",
|
||||||
|
"openldap-2.6.2-2.el9",
|
||||||
|
"openldap-compat-2.6.2-2.el9",
|
||||||
|
"openssh-8.7p1-19.el9",
|
||||||
|
"openssh-clients-8.7p1-19.el9",
|
||||||
|
"openssh-server-8.7p1-19.el9",
|
||||||
|
"openssl-3.0.1-38.el9",
|
||||||
|
"openssl-devel-3.0.1-38.el9",
|
||||||
|
"openssl-libs-3.0.1-38.el9",
|
||||||
|
"openssl-pkcs11-0.4.11-7.el9",
|
||||||
|
"opus-1.3.1-10.el9",
|
||||||
|
"opus-devel-1.3.1-10.el9",
|
||||||
|
"os-prober-1.77-9.el9",
|
||||||
|
"ostree-2022.3-2.el9",
|
||||||
|
"ostree-libs-2022.3-2.el9",
|
||||||
|
"p11-kit-0.24.1-2.el9",
|
||||||
|
"p11-kit-trust-0.24.1-2.el9",
|
||||||
|
"pam-1.5.1-12.el9",
|
||||||
|
"passwd-0.80-12.el9",
|
||||||
|
"patch-2.7.6-16.el9",
|
||||||
|
"pcre-8.44-3.el9.3",
|
||||||
|
"pcre-cpp-8.44-3.el9.3",
|
||||||
|
"pcre-devel-8.44-3.el9.3",
|
||||||
|
"pcre-utf16-8.44-3.el9.3",
|
||||||
|
"pcre-utf32-8.44-3.el9.3",
|
||||||
|
"pcre2-10.40-2.el9",
|
||||||
|
"pcre2-devel-10.40-2.el9",
|
||||||
|
"pcre2-syntax-10.40-2.el9",
|
||||||
|
"pcre2-utf16-10.40-2.el9",
|
||||||
|
"pcre2-utf32-10.40-2.el9",
|
||||||
|
"perl-AutoSplit-5.74-479.el9",
|
||||||
|
"perl-B-1.80-479.el9",
|
||||||
|
"perl-base-2.27-479.el9",
|
||||||
|
"perl-Benchmark-1.23-479.el9",
|
||||||
|
"perl-Carp-1.50-460.el9",
|
||||||
|
"perl-Class-Struct-0.66-479.el9",
|
||||||
|
"perl-constant-1.33-461.el9",
|
||||||
|
"perl-Data-Dumper-2.174-462.el9",
|
||||||
|
"perl-devel-5.32.1-479.el9",
|
||||||
|
"perl-Devel-PPPort-3.62-4.el9",
|
||||||
|
"perl-DynaLoader-1.47-479.el9",
|
||||||
|
"perl-Encode-3.08-462.el9",
|
||||||
|
"perl-Errno-1.30-479.el9",
|
||||||
|
"perl-Error-0.17029-7.el9",
|
||||||
|
"perl-Exporter-5.74-461.el9",
|
||||||
|
"perl-ExtUtils-Command-7.60-3.el9",
|
||||||
|
"perl-ExtUtils-Constant-0.25-479.el9",
|
||||||
|
"perl-ExtUtils-Install-2.20-4.el9",
|
||||||
|
"perl-ExtUtils-MakeMaker-7.60-3.el9",
|
||||||
|
"perl-ExtUtils-Manifest-1.73-4.el9",
|
||||||
|
"perl-ExtUtils-ParseXS-3.40-460.el9",
|
||||||
|
"perl-Fcntl-1.13-479.el9",
|
||||||
|
"perl-File-Basename-2.85-479.el9",
|
||||||
|
"perl-File-Compare-1.100.600-479.el9",
|
||||||
|
"perl-File-Copy-2.34-479.el9",
|
||||||
|
"perl-File-Find-1.37-479.el9",
|
||||||
|
"perl-File-Path-2.18-4.el9",
|
||||||
|
"perl-File-stat-1.09-479.el9",
|
||||||
|
"perl-File-Temp-0.231.100-4.el9",
|
||||||
|
"perl-Getopt-Long-2.52-4.el9",
|
||||||
|
"perl-Getopt-Std-1.12-479.el9",
|
||||||
|
"perl-Git-2.31.1-2.el9.2",
|
||||||
|
"perl-HTTP-Tiny-0.076-460.el9",
|
||||||
|
"perl-if-0.60.800-479.el9",
|
||||||
|
"perl-interpreter-5.32.1-479.el9",
|
||||||
|
"perl-IO-1.43-479.el9",
|
||||||
|
"perl-IPC-Open3-1.21-479.el9",
|
||||||
|
"perl-lib-0.65-479.el9",
|
||||||
|
"perl-libs-5.32.1-479.el9",
|
||||||
|
"perl-locale-1.09-479.el9",
|
||||||
|
"perl-MIME-Base64-3.16-4.el9",
|
||||||
|
"perl-mro-1.23-479.el9",
|
||||||
|
"perl-overload-1.31-479.el9",
|
||||||
|
"perl-overloading-0.02-479.el9",
|
||||||
|
"perl-parent-0.238-460.el9",
|
||||||
|
"perl-PathTools-3.78-461.el9",
|
||||||
|
"perl-Pod-Escapes-1.07-460.el9",
|
||||||
|
"perl-Pod-Perldoc-3.28.01-461.el9",
|
||||||
|
"perl-Pod-Simple-3.42-4.el9",
|
||||||
|
"perl-Pod-Usage-2.01-4.el9",
|
||||||
|
"perl-podlators-4.14-460.el9",
|
||||||
|
"perl-POSIX-1.94-479.el9",
|
||||||
|
"perl-Scalar-List-Utils-1.56-461.el9",
|
||||||
|
"perl-SelectSaver-1.02-479.el9",
|
||||||
|
"perl-Socket-2.031-4.el9",
|
||||||
|
"perl-srpm-macros-1-41.el9",
|
||||||
|
"perl-Storable-3.21-460.el9",
|
||||||
|
"perl-subs-1.03-479.el9",
|
||||||
|
"perl-Symbol-1.08-479.el9",
|
||||||
|
"perl-Term-ANSIColor-5.01-461.el9",
|
||||||
|
"perl-Term-Cap-1.17-460.el9",
|
||||||
|
"perl-TermReadKey-2.38-11.el9",
|
||||||
|
"perl-Test-Harness-3.42-461.el9",
|
||||||
|
"perl-Text-ParseWords-3.30-460.el9",
|
||||||
|
"perl-Text-Tabs+Wrap-2013.0523-460.el9",
|
||||||
|
"perl-Thread-Queue-3.14-460.el9",
|
||||||
|
"perl-threads-2.25-460.el9",
|
||||||
|
"perl-threads-shared-1.61-460.el9",
|
||||||
|
"perl-Time-Local-1.300-7.el9",
|
||||||
|
"perl-vars-1.05-479.el9",
|
||||||
|
"perl-version-0.99.28-4.el9",
|
||||||
|
"pigz-2.5-4.el9",
|
||||||
|
"pixman-0.40.0-5.el9",
|
||||||
|
"pkgconf-1.7.3-9.el9",
|
||||||
|
"pkgconf-m4-1.7.3-9.el9",
|
||||||
|
"pkgconf-pkg-config-1.7.3-9.el9",
|
||||||
|
"podman-4.1.1-3.el9",
|
||||||
|
"podman-catatonit-4.1.1-3.el9",
|
||||||
|
"policycoreutils-3.4-1.el9",
|
||||||
|
"policycoreutils-python-utils-3.4-1.el9",
|
||||||
|
"polkit-0.117-10.el9",
|
||||||
|
"polkit-libs-0.117-10.el9",
|
||||||
|
"polkit-pkla-compat-0.1-21.el9",
|
||||||
|
"popt-1.18-8.el9",
|
||||||
|
"procps-ng-3.3.17-5.el9",
|
||||||
|
"protobuf-3.14.0-13.el9",
|
||||||
|
"protobuf-c-1.3.3-12.el9",
|
||||||
|
"psmisc-23.4-3.el9",
|
||||||
|
"publicsuffix-list-dafsa-20210518-3.el9",
|
||||||
|
"python-rpm-macros-3.9-52.el9",
|
||||||
|
"python-srpm-macros-3.9-52.el9",
|
||||||
|
"python-unversioned-command-3.9.13-2.el9",
|
||||||
|
"python3-3.9.13-2.el9",
|
||||||
|
"python3-audit-3.0.7-103.el9",
|
||||||
|
"python3-devel-3.9.13-2.el9",
|
||||||
|
"python3-dnf-4.12.0-2.el9",
|
||||||
|
"python3-gpg-1.15.1-6.el9",
|
||||||
|
"python3-hawkey-0.67.0-1.el9",
|
||||||
|
"python3-iniparse-0.4-45.el9",
|
||||||
|
"python3-libcomps-0.1.18-1.el9",
|
||||||
|
"python3-libdnf-0.67.0-1.el9",
|
||||||
|
"python3-libs-3.9.13-2.el9",
|
||||||
|
"python3-libselinux-3.4-3.el9",
|
||||||
|
"python3-libsemanage-3.4-1.el9",
|
||||||
|
"python3-numpy-1.20.1-5.el9",
|
||||||
|
"python3-packaging-20.9-5.el9",
|
||||||
|
"python3-pip-wheel-21.2.3-6.el9",
|
||||||
|
"python3-policycoreutils-3.4-1.el9",
|
||||||
|
"python3-pyparsing-2.4.7-9.el9",
|
||||||
|
"python3-rpm-4.16.1.3-15.el9",
|
||||||
|
"python3-rpm-generators-12-8.el9",
|
||||||
|
"python3-rpm-macros-3.9-52.el9",
|
||||||
|
"python3-setools-4.4.0-5.el9",
|
||||||
|
"python3-setuptools-53.0.0-10.el9",
|
||||||
|
"python3-setuptools-wheel-53.0.0-10.el9",
|
||||||
|
"python3-six-1.15.0-9.el9",
|
||||||
|
"qemu-img-7.0.0-8.el9",
|
||||||
|
"qt5-srpm-macros-5.15.3-1.el9",
|
||||||
|
"readline-8.1-4.el9",
|
||||||
|
"redhat-rpm-config-196-1.el9",
|
||||||
|
"rng-tools-6.15-1.el9",
|
||||||
|
"rootfiles-8.1-31.el9",
|
||||||
|
"rpm-4.16.1.3-15.el9",
|
||||||
|
"rpm-build-4.16.1.3-15.el9",
|
||||||
|
"rpm-build-libs-4.16.1.3-15.el9",
|
||||||
|
"rpm-libs-4.16.1.3-15.el9",
|
||||||
|
"rpm-ostree-2022.8-3.el9",
|
||||||
|
"rpm-ostree-libs-2022.8-3.el9",
|
||||||
|
"rpm-plugin-selinux-4.16.1.3-15.el9",
|
||||||
|
"rpm-sign-libs-4.16.1.3-15.el9",
|
||||||
|
"rsyslog-8.2102.0-105.el9",
|
||||||
|
"rust-srpm-macros-17-4.el9",
|
||||||
|
"sed-4.8-9.el9",
|
||||||
|
"selinux-policy-34.1.38-1.el9",
|
||||||
|
"selinux-policy-targeted-34.1.38-1.el9",
|
||||||
|
"setup-2.13.7-7.el9",
|
||||||
|
"shadow-utils-4.9-4.el9",
|
||||||
|
"shadow-utils-subid-4.9-4.el9",
|
||||||
|
"shared-mime-info-2.1-4.el9",
|
||||||
|
"skopeo-1.9.0-1.el9",
|
||||||
|
"slirp4netns-1.2.0-2.el9",
|
||||||
|
"source-highlight-3.1.9-11.el9",
|
||||||
|
"sqlite-3.34.1-5.el9",
|
||||||
|
"sqlite-devel-3.34.1-5.el9",
|
||||||
|
"sqlite-libs-3.34.1-5.el9",
|
||||||
|
"strace-5.18-2.el9",
|
||||||
|
"sudo-1.9.5p2-7.el9",
|
||||||
|
"sysprof-capture-devel-3.40.1-3.el9",
|
||||||
|
"systemd-250-7.el9",
|
||||||
|
"systemd-libs-250-7.el9",
|
||||||
|
"systemd-pam-250-7.el9",
|
||||||
|
"systemd-rpm-macros-250-7.el9",
|
||||||
|
"systemd-udev-250-7.el9",
|
||||||
|
"systemtap-sdt-devel-4.7-2.el9",
|
||||||
|
"tar-1.34-5.el9",
|
||||||
|
"tpm2-tools-5.2-1.el9",
|
||||||
|
"tpm2-tss-3.0.3-7.el9",
|
||||||
|
"tzdata-2022a-1.el9",
|
||||||
|
"unzip-6.0-56.el9",
|
||||||
|
"usbguard-1.0.0-10.el9",
|
||||||
|
"userspace-rcu-0.12.1-6.el9",
|
||||||
|
"util-linux-2.37.4-3.el9",
|
||||||
|
"util-linux-core-2.37.4-3.el9",
|
||||||
|
"vim-common-8.2.2637-16.el9",
|
||||||
|
"vim-enhanced-8.2.2637-16.el9",
|
||||||
|
"vim-filesystem-8.2.2637-16.el9",
|
||||||
|
"wget-1.21.1-7.el9",
|
||||||
|
"which-2.21-28.el9",
|
||||||
|
"wpa_supplicant-2.10-4.el9",
|
||||||
|
"xfsprogs-5.14.2-1.el9",
|
||||||
|
"xml-common-0.6.3-58.el9",
|
||||||
|
"xz-5.2.5-8.el9",
|
||||||
|
"xz-devel-5.2.5-8.el9",
|
||||||
|
"xz-libs-5.2.5-8.el9",
|
||||||
|
"yajl-2.1.0-20.el9",
|
||||||
|
"yum-4.12.0-2.el9",
|
||||||
|
"zip-3.0-33.el9",
|
||||||
|
"zlib-1.2.11-33.el9",
|
||||||
|
"zlib-devel-1.2.11-33.el9",
|
||||||
|
"zstd-1.5.1-2.el9"
|
||||||
|
],
|
||||||
|
"arch": {
|
||||||
|
"aarch64": [
|
||||||
|
"grub2-efi-aa64-2.06-38.el9",
|
||||||
|
"grub2-efi-aa64-cdboot-2.06-38.el9",
|
||||||
|
"libasan-11.3.1-2.1.el9",
|
||||||
|
"libatomic-11.3.1-2.1.el9",
|
||||||
|
"libubsan-11.3.1-2.1.el9",
|
||||||
|
"shim-aa64-15-15.el8_2"
|
||||||
|
],
|
||||||
|
"x86_64": [
|
||||||
|
"glibc-headers-2.34-39.el9",
|
||||||
|
"grub2-efi-x64-2.06-38.el9",
|
||||||
|
"grub2-efi-x64-cdboot-2.06-38.el9",
|
||||||
|
"grub2-tools-efi-2.06-38.el9",
|
||||||
|
"libipt-2.0.4-3.el9",
|
||||||
|
"libquadmath-11.3.1-2.1.el9",
|
||||||
|
"libquadmath-devel-11.3.1-2.1.el9",
|
||||||
|
"libsmbios-2.4.3-4.el9",
|
||||||
|
"microcode_ctl-20220510-1.el9",
|
||||||
|
"shim-x64-15-15.el8_2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
*.src.rpm
|
||||||
|
*~
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles/
|
||||||
|
cmake_install.cmake
|
||||||
|
radio-client
|
||||||
|
radio-service
|
||||||
|
engine-service
|
||||||
|
auto-apps-*.tar.gz
|
||||||
|
auto-apps.spec
|
||||||
|
Makefile
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
project(auto-apps)
|
||||||
|
|
||||||
|
cmake_minimum_required (VERSION 2.10)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
find_package (vsomeip3 2.6.0 REQUIRED)
|
||||||
|
find_package( Boost 1.55 COMPONENTS system thread log REQUIRED )
|
||||||
|
|
||||||
|
set (INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
|
||||||
|
set (INSTALL_BIN_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
|
||||||
|
set (INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
|
||||||
|
|
||||||
|
include_directories (
|
||||||
|
${Boost_INCLUDE_DIR}
|
||||||
|
${VSOMEIP_INCLUDE_DIRS}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
add_executable(radio-service radio-service.cpp services.hpp radio-stations.cpp)
|
||||||
|
target_link_libraries(radio-service vsomeip3 ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
add_executable(radio-client radio-client.cpp services.hpp)
|
||||||
|
target_link_libraries(radio-client vsomeip3 ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
add_executable(engine-service engine-service.cpp services.hpp)
|
||||||
|
target_link_libraries(engine-service vsomeip3 ${Boost_LIBRARIES})
|
||||||
|
|
||||||
|
install (
|
||||||
|
TARGETS radio-service radio-client engine-service
|
||||||
|
RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT bin
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
Permission is hereby granted, without written agreement and without
|
||||||
|
license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
software and its documentation for any purpose, provided that the
|
||||||
|
above copyright notice and the following two paragraphs appear in
|
||||||
|
all copies of this software.
|
||||||
|
|
||||||
|
IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
DAMAGE.
|
||||||
|
|
||||||
|
THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
FROM centos:stream9-development AS installroot
|
||||||
|
|
||||||
|
RUN dnf update -y
|
||||||
|
|
||||||
|
# Enable copr
|
||||||
|
RUN dnf install -y 'dnf-command(copr)'
|
||||||
|
RUN dnf copr -y enable alexl/cs9-sample-images
|
||||||
|
|
||||||
|
RUN dnf install --installroot /installroot -y --nogpgcheck vsomeip3 bash \
|
||||||
|
boost-system boost-thread boost-log boost-chrono boost-date-time boost-atomic \
|
||||||
|
boost-log boost-filesystem boost-regex auto-apps
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
COPY --from=installroot /installroot ./
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
PREFIX=registry.gitlab.com/centos/automotive/sample-images
|
||||||
|
IMAGE=${PREFIX}/demo/auto-apps
|
||||||
|
|
||||||
|
build:
|
||||||
|
podman build -f Containerfile.auto-apps -t ${IMAGE}:latest-$$(arch) .
|
||||||
|
|
||||||
|
push:
|
||||||
|
podman push ${IMAGE}:latest-$$(arch)
|
||||||
|
|
||||||
|
multiarch:
|
||||||
|
podman pull ${IMAGE}:latest-aarch64
|
||||||
|
podman pull ${IMAGE}:latest-x86_64
|
||||||
|
podman manifest rm ${IMAGE}:latest || true
|
||||||
|
podman manifest create ${IMAGE}:latest ${IMAGE}:latest-x86_64 ${IMAGE}:latest-aarch64
|
||||||
|
|
||||||
|
push-multiarch:
|
||||||
|
podman manifest push --all --format v2s2 ${IMAGE}:latest docker://${IMAGE}:latest
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
VERSION=0.1
|
||||||
|
|
||||||
|
TOPDIR=$(shell pwd)
|
||||||
|
|
||||||
|
auto-apps-$(VERSION).tar.gz:
|
||||||
|
git archive HEAD . --prefix=auto-apps-$(VERSION)/ --output=auto-apps-$(VERSION).tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
srpm: auto-apps-$(VERSION).tar.gz auto-apps.spec.in
|
||||||
|
sed s/@@VERSION@@/$(VERSION)/g auto-apps.spec.in > auto-apps.spec
|
||||||
|
rpmbuild -bs --define "_srcrpmdir $(TOPDIR)" --define "_sourcedir $(TOPDIR)" auto-apps.spec
|
||||||
|
|
||||||
|
rpm: auto-apps-$(VERSION).tar.gz auto-apps.spec.in
|
||||||
|
sed s/@@VERSION@@/$(VERSION)/g auto-apps.spec.in > auto-apps.spec
|
||||||
|
rpmbuild -ba --define "_srcrpmdir $(TOPDIR)" --define "_sourcedir $(TOPDIR)" auto-apps.spec
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Sample automotive applications
|
||||||
|
|
||||||
|
This directory contains a set of applications that demonstrate how
|
||||||
|
typical automotive applications use SOME/IP to talk to each
|
||||||
|
other. These apps work both natively and in a container, as
|
||||||
|
demonstated by the container sample image [described
|
||||||
|
here](https://sigs.centos.org/automotive/building/containers/).
|
||||||
|
|
||||||
|
## The apps
|
||||||
|
|
||||||
|
### engine-service
|
||||||
|
|
||||||
|
This is a very simple service with a single event that signals that
|
||||||
|
the car is reversing, which is regularly emitted.
|
||||||
|
|
||||||
|
### radio-service
|
||||||
|
|
||||||
|
This is a service that emulates a radio, regularly publishing
|
||||||
|
information about the current song, radio station and volume. It
|
||||||
|
accepts requests to turn on/off, switch channel, and change volume.
|
||||||
|
If the engine service is available it will listen for events from it
|
||||||
|
and temporarily lower the volume while reversing.
|
||||||
|
|
||||||
|
### radio-client
|
||||||
|
|
||||||
|
This is a command line program that displays the current state of the
|
||||||
|
radio service, as well as allow you to control it. The keyboard controls
|
||||||
|
are displayed on the screen.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
The apps depend on boost and vsomeip3, and can be build with cmake like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cmake .
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
There is also a makefile that allows building rpms and srpms:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make -f Makefile.rpm srpm
|
||||||
|
$ make -f Makefile.rpm rpm
|
||||||
|
```
|
||||||
|
|
||||||
|
These rpms, in addition to required dependencies (dlt-daemon,
|
||||||
|
vsomeip3) are pre-build for cs9 it in [this copr
|
||||||
|
repo](https://copr.fedorainfracloud.org/coprs/alexl/cs9-sample-images/packages/).
|
||||||
|
|
||||||
|
Additionally, there is a
|
||||||
|
[Containerfile.auto-apps](Containerfile.auto-apps) file that allows
|
||||||
|
installing these apps into a container, using the above rpms. You can
|
||||||
|
build it like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ podman build -f Containerfile.auto-apps
|
||||||
|
```
|
||||||
|
|
||||||
|
Or use the Makefile.container helpers:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make -f Makefile.container build
|
||||||
|
```
|
||||||
|
|
||||||
|
A pre-built version of these containers for aarch64 and x86-64 is
|
||||||
|
available in the [automotive sig container
|
||||||
|
repo](https://gitlab.com/CentOS/automotive/sample-images/container_registry/2944592).
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
Name: auto-apps
|
||||||
|
Version: @@VERSION@@
|
||||||
|
Release: 1%{?dist}
|
||||||
|
Summary: Sample auto apps
|
||||||
|
|
||||||
|
License: MIT
|
||||||
|
Source0: auto-apps-%{version}.tar.gz
|
||||||
|
|
||||||
|
|
||||||
|
BuildRequires: cmake make gcc-c++ boost-devel vsomeip3-devel
|
||||||
|
|
||||||
|
%description
|
||||||
|
Sample auto applications
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%autosetup
|
||||||
|
|
||||||
|
%build
|
||||||
|
%cmake
|
||||||
|
%cmake_build
|
||||||
|
|
||||||
|
%install
|
||||||
|
%cmake_install
|
||||||
|
|
||||||
|
%files
|
||||||
|
%{_bindir}/engine-service
|
||||||
|
%{_bindir}/radio-client
|
||||||
|
%{_bindir}/radio-service
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Mon Mar 14 2022 Alexander Larsson <alexl@redhat.com>
|
||||||
|
- Initial version
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
#include <csignal>
|
||||||
|
#include <iostream>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
#include <vsomeip/vsomeip.hpp>
|
||||||
|
|
||||||
|
#include "services.hpp"
|
||||||
|
|
||||||
|
class engine_service {
|
||||||
|
public:
|
||||||
|
engine_service() :
|
||||||
|
app(vsomeip::runtime::get()->create_application("Engine")),
|
||||||
|
is_registered(false),
|
||||||
|
main_blocked(false),
|
||||||
|
main_running(true),
|
||||||
|
in_reverse(false),
|
||||||
|
is_offered(false),
|
||||||
|
main_thread(std::bind(&engine_service::run, this)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool init() {
|
||||||
|
std::lock_guard<std::mutex> its_lock(main_mutex);
|
||||||
|
|
||||||
|
if (!app->init()) {
|
||||||
|
std::cerr << "Couldn't initialize application" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
app->register_state_handler(
|
||||||
|
std::bind(&engine_service::on_state, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
|
||||||
|
app->register_message_handler(
|
||||||
|
ENGINE_SERVICE_ID,
|
||||||
|
ENGINE_INSTANCE_ID,
|
||||||
|
ENGINE_GET_REVERSE_METHOD_ID,
|
||||||
|
std::bind(&engine_service::on_get_reverse, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
|
||||||
|
std::set<vsomeip::eventgroup_t> its_groups;
|
||||||
|
its_groups.insert(ENGINE_EVENTGROUP_ID);
|
||||||
|
app->offer_event(
|
||||||
|
ENGINE_SERVICE_ID,
|
||||||
|
ENGINE_INSTANCE_ID,
|
||||||
|
ENGINE_REVERSE_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
|
||||||
|
false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
|
||||||
|
|
||||||
|
main_blocked = true;
|
||||||
|
main_condition.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
app->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
main_running = false;
|
||||||
|
main_blocked = true;
|
||||||
|
main_condition.notify_one();
|
||||||
|
app->clear_all_handler();
|
||||||
|
stop_offer();
|
||||||
|
main_thread.join();
|
||||||
|
app->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void offer() {
|
||||||
|
app->offer_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
is_offered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_offer() {
|
||||||
|
app->stop_offer_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_state(vsomeip::state_type_e _state) {
|
||||||
|
std::cout << "Application " << app->get_name() << " is "
|
||||||
|
<< (_state == vsomeip::state_type_e::ST_REGISTERED ?
|
||||||
|
"registered." : "deregistered.") << std::endl;
|
||||||
|
|
||||||
|
if (_state == vsomeip::state_type_e::ST_REGISTERED) {
|
||||||
|
if (!is_registered) {
|
||||||
|
is_registered = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
is_registered = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call with lock held
|
||||||
|
std::shared_ptr<vsomeip::payload> get_reverse_payload() {
|
||||||
|
return payload_with_arg (in_reverse ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_get_reverse(const std::shared_ptr<vsomeip::message> &_message) {
|
||||||
|
std::cout << "ENGINE: Received get_reverse" << std::endl;
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()->create_response(_message);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> its_lock(main_mutex);
|
||||||
|
its_response->set_payload(get_reverse_payload());
|
||||||
|
}
|
||||||
|
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
while (!main_blocked)
|
||||||
|
main_condition.wait(its_lock);
|
||||||
|
|
||||||
|
offer();
|
||||||
|
|
||||||
|
while (main_running) {
|
||||||
|
auto timeout = 10s;
|
||||||
|
|
||||||
|
if (in_reverse) {
|
||||||
|
timeout = 4s;
|
||||||
|
std::cout << "ENGINE: Reversing..." << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "ENGINE: Driving..." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep a bit
|
||||||
|
bool timed_out = main_condition.wait_for(its_lock, timeout) == std::cv_status::timeout;
|
||||||
|
|
||||||
|
if (timed_out) {
|
||||||
|
// Change direction
|
||||||
|
in_reverse = !in_reverse;
|
||||||
|
std::shared_ptr<vsomeip::payload> payload = get_reverse_payload();
|
||||||
|
|
||||||
|
app->notify(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_REVERSE_EVENT_ID, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<vsomeip::application> app;
|
||||||
|
bool is_registered;
|
||||||
|
|
||||||
|
// main_blocked / is_offered must be initialized before starting the threads!
|
||||||
|
std::thread main_thread;
|
||||||
|
|
||||||
|
std::mutex main_mutex;
|
||||||
|
std::condition_variable main_condition;
|
||||||
|
bool main_blocked;
|
||||||
|
bool main_running;
|
||||||
|
bool is_offered;
|
||||||
|
|
||||||
|
// Engine state:
|
||||||
|
bool in_reverse;
|
||||||
|
};
|
||||||
|
|
||||||
|
engine_service *its_engine_ptr(nullptr);
|
||||||
|
static void handle_signal(int _signal) {
|
||||||
|
if (its_engine_ptr != nullptr &&
|
||||||
|
(_signal == SIGINT || _signal == SIGTERM))
|
||||||
|
its_engine_ptr->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
engine_service its_engine;
|
||||||
|
|
||||||
|
its_engine_ptr = &its_engine;
|
||||||
|
signal(SIGINT, handle_signal);
|
||||||
|
signal(SIGTERM, handle_signal);
|
||||||
|
|
||||||
|
if (!its_engine.init()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
its_engine.start();
|
||||||
|
// Work around dlt-daemon timeout on exit
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <thread>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include <vsomeip/vsomeip.hpp>
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
#include "services.hpp"
|
||||||
|
|
||||||
|
std::shared_ptr< vsomeip::application > app;
|
||||||
|
std::mutex mutex;
|
||||||
|
std::condition_variable condition;
|
||||||
|
|
||||||
|
bool running = true;
|
||||||
|
bool data_changed = false;
|
||||||
|
bool service_available = false;
|
||||||
|
bool in_reverse = false;
|
||||||
|
std::string radio_station = "";
|
||||||
|
std::string song = "";
|
||||||
|
std::string artist = "";
|
||||||
|
uint32_t volume = 0;
|
||||||
|
bool sent_off = false;
|
||||||
|
|
||||||
|
static std::string volume_meter(uint32_t volume)
|
||||||
|
{
|
||||||
|
std::string vol_str = "";
|
||||||
|
for (uint32_t i = 0; i <= 20; i++) {
|
||||||
|
if (volume > i * 5 || volume == 100)
|
||||||
|
vol_str += "#";
|
||||||
|
else
|
||||||
|
vol_str += " ";
|
||||||
|
}
|
||||||
|
return vol_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_volume_message(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
volume = get_arg0(_event);
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_song_message(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
song = get_arg0_string(_event);
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_artist_message(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
artist = get_arg0_string(_event);
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_station_message(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
radio_station = get_arg0_string(_event);
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void input_thread() {
|
||||||
|
while (true) {
|
||||||
|
int c = getchar();
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 'q':
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
running = false;
|
||||||
|
condition.notify_one();
|
||||||
|
app->stop();
|
||||||
|
}
|
||||||
|
return; /* End thread */
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
{
|
||||||
|
std::shared_ptr< vsomeip::message > request = new_request (RADIO_CHANGE_VOLUME_METHOD_ID, 10);
|
||||||
|
app->send(request);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
{
|
||||||
|
std::shared_ptr< vsomeip::message > request = new_request (RADIO_CHANGE_VOLUME_METHOD_ID, (uint32_t)(int32_t)-10);
|
||||||
|
app->send(request);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
{
|
||||||
|
std::shared_ptr< vsomeip::message > request = new_request (RADIO_SWITCH_STATION_METHOD_ID, 0);
|
||||||
|
app->send(request);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '\e':
|
||||||
|
{
|
||||||
|
std::shared_ptr< vsomeip::message > request = new_request (RADIO_SET_PLAYING_METHOD_ID, sent_off ? 1 : 0);
|
||||||
|
sent_off = !sent_off;
|
||||||
|
app->send(request);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// pass
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_VOLUME_EVENT_ID,
|
||||||
|
on_volume_message);
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_STATION_EVENT_ID,
|
||||||
|
on_station_message);
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_SONG_EVENT_ID,
|
||||||
|
on_song_message);
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_ARTIST_EVENT_ID,
|
||||||
|
on_artist_message);
|
||||||
|
|
||||||
|
std::set<vsomeip::eventgroup_t> its_groups;
|
||||||
|
its_groups.insert(RADIO_EVENTGROUP_ID);
|
||||||
|
app->request_event(RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_SONG_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->request_event(RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_ARTIST_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->request_event(RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_VOLUME_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->request_event(RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_STATION_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->subscribe(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_EVENTGROUP_ID);
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
if (data_changed) {
|
||||||
|
std::cout
|
||||||
|
<< "\e[s" // Save cursor
|
||||||
|
<< "\e[6;1H" // Goto row 6
|
||||||
|
<< "\e[1J" // Clear to start of screen
|
||||||
|
<< "\e[1;1H" // Goto row 1;
|
||||||
|
;
|
||||||
|
if (service_available) {
|
||||||
|
std::cout
|
||||||
|
<< "Station: " << radio_station << std::endl
|
||||||
|
<< "Song: " << song << std::endl
|
||||||
|
<< "Artist: " << artist << std::endl
|
||||||
|
<< "Volume: [" << volume_meter(volume) << "] " << std::endl
|
||||||
|
<< (in_reverse ?
|
||||||
|
"------------------------------[REVERSING]-" :
|
||||||
|
"------------------------------------------")
|
||||||
|
<< std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout
|
||||||
|
<< "Connecting to radio service";
|
||||||
|
}
|
||||||
|
std::cout
|
||||||
|
<< "\e[u" // Restore cursor
|
||||||
|
<< std::flush;
|
||||||
|
data_changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
condition.wait_for(its_lock, 5s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
service_available = _is_available;
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_engine_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
if (!_is_available)
|
||||||
|
{
|
||||||
|
in_reverse = false;
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_engine_reverse_event(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(mutex);
|
||||||
|
bool reversed = get_arg0(_event) != 0;
|
||||||
|
|
||||||
|
in_reverse = reversed;
|
||||||
|
data_changed = true;
|
||||||
|
condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *argv[]) {
|
||||||
|
struct termios old_tio, new_tio;
|
||||||
|
unsigned char c;
|
||||||
|
|
||||||
|
tcgetattr(STDIN_FILENO,&old_tio);
|
||||||
|
new_tio=old_tio;
|
||||||
|
|
||||||
|
/* disable canonical mode (buffered i/o) and local echo */
|
||||||
|
new_tio.c_lflag &=(~ICANON & ~ECHO);
|
||||||
|
tcsetattr(STDIN_FILENO,TCSANOW,&new_tio);
|
||||||
|
|
||||||
|
std::cout
|
||||||
|
<< "\e[2J" // Clear screen
|
||||||
|
<< "\e[1;1H" // Goto row 1
|
||||||
|
<< "\e[6;1H" // Goto row 6
|
||||||
|
<< " Usage: volume: +/-, station: SPACE on/off: ESC, quit: Q" << std::endl;
|
||||||
|
|
||||||
|
app = vsomeip::runtime::get()->create_application("Radio client");
|
||||||
|
app->init();
|
||||||
|
app->register_availability_handler(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, on_availability);
|
||||||
|
app->request_service(RADIO_SERVICE_ID, RADIO_INSTANCE_ID);
|
||||||
|
|
||||||
|
app->register_availability_handler(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, on_engine_availability);
|
||||||
|
app->request_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
std::set<vsomeip::eventgroup_t> its_groups;
|
||||||
|
its_groups.insert(ENGINE_EVENTGROUP_ID);
|
||||||
|
app->request_event(ENGINE_SERVICE_ID,
|
||||||
|
ENGINE_INSTANCE_ID,
|
||||||
|
ENGINE_REVERSE_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->subscribe(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_EVENTGROUP_ID);
|
||||||
|
|
||||||
|
app->register_message_handler(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_REVERSE_EVENT_ID,
|
||||||
|
on_engine_reverse_event);
|
||||||
|
|
||||||
|
std::thread input(input_thread);
|
||||||
|
std::thread sender(run);
|
||||||
|
app->start();
|
||||||
|
|
||||||
|
sender.join();
|
||||||
|
input.join();
|
||||||
|
|
||||||
|
|
||||||
|
app->clear_all_handler();
|
||||||
|
app->release_service(RADIO_SERVICE_ID, RADIO_INSTANCE_ID);
|
||||||
|
app->release_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
|
||||||
|
tcsetattr(STDIN_FILENO,TCSANOW,&old_tio);
|
||||||
|
|
||||||
|
// Work around dlt-daemon timeout on exit
|
||||||
|
_exit(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,437 @@
|
||||||
|
#include <csignal>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
|
#include <vsomeip/vsomeip.hpp>
|
||||||
|
|
||||||
|
#include "services.hpp"
|
||||||
|
#include "radio-stations.hpp"
|
||||||
|
|
||||||
|
class radio_service {
|
||||||
|
public:
|
||||||
|
radio_service() :
|
||||||
|
app(vsomeip::runtime::get()->create_application("Radio")),
|
||||||
|
verbose(false),
|
||||||
|
main_blocked(false),
|
||||||
|
main_running(true),
|
||||||
|
is_offered(false),
|
||||||
|
engine_available(false),
|
||||||
|
next_volume(50),
|
||||||
|
next_radio_station(0),
|
||||||
|
next_playing(false),
|
||||||
|
next_reversed(false),
|
||||||
|
main_thread(std::bind(&radio_service::run, this)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool init() {
|
||||||
|
std::lock_guard<std::mutex> its_lock(main_mutex);
|
||||||
|
|
||||||
|
if (!app->init()) {
|
||||||
|
std::cerr << "Couldn't initialize application" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_SET_PLAYING_METHOD_ID,
|
||||||
|
std::bind(&radio_service::on_message_set_playing, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_IS_PLAYING_METHOD_ID,
|
||||||
|
std::bind(&radio_service::on_message_is_playing, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_GET_VOLUME_METHOD_ID,
|
||||||
|
std::bind(&radio_service::on_message_get_volume, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_CHANGE_VOLUME_METHOD_ID,
|
||||||
|
std::bind(&radio_service::on_message_change_volume, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
app->register_message_handler(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_SWITCH_STATION_METHOD_ID,
|
||||||
|
std::bind(&radio_service::on_message_switch_station, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
|
||||||
|
std::set<vsomeip::eventgroup_t> its_groups_radio;
|
||||||
|
its_groups_radio.insert(RADIO_EVENTGROUP_ID);
|
||||||
|
app->offer_event(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_VOLUME_EVENT_ID,
|
||||||
|
its_groups_radio,
|
||||||
|
vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
|
||||||
|
false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
|
||||||
|
app->offer_event(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_STATION_EVENT_ID,
|
||||||
|
its_groups_radio,
|
||||||
|
vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
|
||||||
|
false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
|
||||||
|
app->offer_event(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_SONG_EVENT_ID,
|
||||||
|
its_groups_radio,
|
||||||
|
vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
|
||||||
|
false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
|
||||||
|
app->offer_event(
|
||||||
|
RADIO_SERVICE_ID,
|
||||||
|
RADIO_INSTANCE_ID,
|
||||||
|
RADIO_ARTIST_EVENT_ID,
|
||||||
|
its_groups_radio,
|
||||||
|
vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
|
||||||
|
false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
|
||||||
|
|
||||||
|
app->register_availability_handler(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID,
|
||||||
|
std::bind(&radio_service::on_engine_availability, this,
|
||||||
|
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||||
|
app->request_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
std::set<vsomeip::eventgroup_t> its_groups;
|
||||||
|
its_groups.insert(ENGINE_EVENTGROUP_ID);
|
||||||
|
app->request_event(
|
||||||
|
ENGINE_SERVICE_ID,
|
||||||
|
ENGINE_INSTANCE_ID,
|
||||||
|
ENGINE_REVERSE_EVENT_ID,
|
||||||
|
its_groups,
|
||||||
|
vsomeip::event_type_e::ET_FIELD);
|
||||||
|
app->subscribe(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_EVENTGROUP_ID);
|
||||||
|
|
||||||
|
app->register_message_handler(
|
||||||
|
ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_REVERSE_EVENT_ID,
|
||||||
|
std::bind(&radio_service::on_engine_reverse_event, this,
|
||||||
|
std::placeholders::_1));
|
||||||
|
|
||||||
|
main_blocked = true;
|
||||||
|
main_condition.notify_one();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
set_playing(true);
|
||||||
|
app->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop() {
|
||||||
|
main_running = false;
|
||||||
|
main_blocked = true;
|
||||||
|
main_condition.notify_one();
|
||||||
|
app->clear_all_handler();
|
||||||
|
app->unsubscribe(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_EVENTGROUP_ID);
|
||||||
|
app->release_event(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID, ENGINE_REVERSE_EVENT_ID);
|
||||||
|
app->release_service(ENGINE_SERVICE_ID, ENGINE_INSTANCE_ID);
|
||||||
|
stop_offer();
|
||||||
|
main_thread.join();
|
||||||
|
app->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void offer() {
|
||||||
|
app->offer_service(RADIO_SERVICE_ID, RADIO_INSTANCE_ID);
|
||||||
|
is_offered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop_offer() {
|
||||||
|
app->stop_offer_service(RADIO_SERVICE_ID, RADIO_INSTANCE_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() {
|
||||||
|
uint32_t current_volume = next_volume;
|
||||||
|
bool currently_playing = false;
|
||||||
|
bool current_reversed = false;
|
||||||
|
uint32_t saved_volume;
|
||||||
|
bool next_volume_is_auto = false;
|
||||||
|
bool volume_is_auto = false;
|
||||||
|
uint32_t current_station = 0xffffffff;
|
||||||
|
const radio_station_info_t *station_info = NULL;
|
||||||
|
uint32_t current_song = 0;
|
||||||
|
bool goto_next_song = true;
|
||||||
|
std::chrono::time_point<std::chrono::system_clock> next_song_at;
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
std::cout << "RADIO: Started main thread" << std::endl;
|
||||||
|
|
||||||
|
offer();
|
||||||
|
|
||||||
|
while (main_running) {
|
||||||
|
bool display = false;
|
||||||
|
|
||||||
|
if (next_reversed != current_reversed) {
|
||||||
|
if (next_reversed) {
|
||||||
|
saved_volume = current_volume;
|
||||||
|
next_volume = 30;
|
||||||
|
next_volume_is_auto = true;
|
||||||
|
std::cout << "RADIO: Lowering volume due to reverse" << std::endl;
|
||||||
|
} else {
|
||||||
|
if (volume_is_auto) {
|
||||||
|
next_volume = saved_volume;
|
||||||
|
std::cout << "RADIO: Restoring volume due to cancelled reverse" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_reversed = next_reversed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_volume != current_volume) {
|
||||||
|
current_volume = next_volume;
|
||||||
|
volume_is_auto = next_volume_is_auto;
|
||||||
|
next_volume_is_auto = false;
|
||||||
|
display = true;
|
||||||
|
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_VOLUME_EVENT_ID, payload_with_arg (current_volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_radio_station != current_station) {
|
||||||
|
current_station = next_radio_station;
|
||||||
|
goto_next_song = true;
|
||||||
|
station_info = get_radio_stations(current_station);
|
||||||
|
display = true;
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_STATION_EVENT_ID, payload_with_string (station_info->name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_playing) {
|
||||||
|
if (!currently_playing) {
|
||||||
|
std::cout << "RADIO: Started playing" << std::endl;
|
||||||
|
goto_next_song = true;
|
||||||
|
}
|
||||||
|
currently_playing = true;
|
||||||
|
|
||||||
|
if (goto_next_song) {
|
||||||
|
auto old = current_song;
|
||||||
|
do {
|
||||||
|
current_song = rand() % station_info->n_songs;
|
||||||
|
} while (old == current_song);
|
||||||
|
goto_next_song = false;
|
||||||
|
next_song_at = std::chrono::system_clock::now() + 3s + (rand() % 3000) * 1ms;
|
||||||
|
display = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display) {
|
||||||
|
struct song_info_t *song = &station_info->songs[current_song];
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_SONG_EVENT_ID, payload_with_string (song->name));
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_ARTIST_EVENT_ID, payload_with_string (song->artist));
|
||||||
|
std::cout << "RADIO: Playing song \""
|
||||||
|
<< song->name << "\" by " << song->artist
|
||||||
|
<< " (on " << station_info->name << ") "
|
||||||
|
<< std::dec << current_volume << "% volume"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (currently_playing)
|
||||||
|
std::cout << "RADIO: Paused playing" << std::endl;
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_SONG_EVENT_ID, payload_with_string ("-off-"));
|
||||||
|
app->notify(RADIO_SERVICE_ID, RADIO_INSTANCE_ID, RADIO_ARTIST_EVENT_ID, payload_with_string (""));
|
||||||
|
currently_playing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (main_condition.wait_until(its_lock, next_song_at) == std::cv_status::timeout) {
|
||||||
|
goto_next_song = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_message_set_playing(const std::shared_ptr<vsomeip::message> &_request) {
|
||||||
|
bool arg = get_arg0(_request) != 0;
|
||||||
|
bool was_playing;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received set_playing "
|
||||||
|
<< arg
|
||||||
|
<< " from Client/Session ["
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
was_playing = set_playing (arg);
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = response (_request, was_playing ? 1 : 0);
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_message_is_playing(const std::shared_ptr<vsomeip::message> &_request) {
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received is_playing "
|
||||||
|
<< "from Client/Session ["
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = response (_request, get_playing () ? 1 : 0);
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_message_change_volume(const std::shared_ptr<vsomeip::message> &_request) {
|
||||||
|
int32_t arg = (int32_t)get_arg0(_request);
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received change_volume "
|
||||||
|
<< arg
|
||||||
|
<< " from Client/Session ["
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
result = change_volume (arg);
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = response (_request, result);
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_message_get_volume(const std::shared_ptr<vsomeip::message> &_request) {
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received get_volume "
|
||||||
|
<< "from Client/Session ["
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
uint32_t volume = get_volume();
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = response (_request, volume);
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_message_switch_station(const std::shared_ptr<vsomeip::message> &_request) {
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received switch_station "
|
||||||
|
<< "from Client/Session ["
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_client() << "/"
|
||||||
|
<< std::setw(4) << std::setfill('0') << std::hex << _request->get_session() << "] "
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
switch_station();
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = response (_request, 0);
|
||||||
|
app->send(its_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_engine_reverse_event(const std::shared_ptr<vsomeip::message> &_event) {
|
||||||
|
bool reversed = get_arg0(_event) != 0;
|
||||||
|
if (verbose)
|
||||||
|
std::cout << "RADIO: Received event: "
|
||||||
|
<< (reversed ? "engine reversed" : "engine forward")
|
||||||
|
<< std::endl;
|
||||||
|
set_reversed(reversed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_engine_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
|
||||||
|
std::cout << "Engine Service is "
|
||||||
|
<< (_is_available ? "available." : "NOT available.")
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> its_lock(main_mutex);
|
||||||
|
engine_available = _is_available;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool set_playing (bool new_playing) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
bool old = new_playing;
|
||||||
|
|
||||||
|
if (next_playing != new_playing) {
|
||||||
|
next_playing = new_playing;
|
||||||
|
main_condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_playing (void) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
return next_playing;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t change_volume (int32_t delta_volume) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
int32_t new_volume;
|
||||||
|
|
||||||
|
new_volume = (int32_t)next_volume + delta_volume;
|
||||||
|
if (new_volume < 0)
|
||||||
|
new_volume = 0;
|
||||||
|
else {
|
||||||
|
if (new_volume > 100)
|
||||||
|
new_volume = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (next_volume != new_volume) {
|
||||||
|
next_volume = new_volume;
|
||||||
|
main_condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_volume (void) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
return next_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
void switch_station (void) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
|
||||||
|
next_radio_station = (next_radio_station + 1) % n_radio_stations();
|
||||||
|
main_condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_reversed (bool new_reversed) {
|
||||||
|
std::unique_lock<std::mutex> its_lock(main_mutex);
|
||||||
|
next_reversed = new_reversed;
|
||||||
|
main_condition.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr< vsomeip::application > app;
|
||||||
|
|
||||||
|
std::thread main_thread;
|
||||||
|
std::mutex main_mutex;
|
||||||
|
std::condition_variable main_condition;
|
||||||
|
bool main_blocked;
|
||||||
|
bool main_running;
|
||||||
|
bool is_offered;
|
||||||
|
bool engine_available;
|
||||||
|
|
||||||
|
bool verbose;
|
||||||
|
|
||||||
|
uint32_t next_volume;
|
||||||
|
uint32_t next_radio_station;
|
||||||
|
bool next_playing;
|
||||||
|
bool next_reversed;
|
||||||
|
};
|
||||||
|
|
||||||
|
radio_service *its_radio_ptr(nullptr);
|
||||||
|
static void handle_signal(int _signal) {
|
||||||
|
if (its_radio_ptr != nullptr &&
|
||||||
|
(_signal == SIGINT || _signal == SIGTERM))
|
||||||
|
its_radio_ptr->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
radio_service its_radio;
|
||||||
|
|
||||||
|
its_radio_ptr = &its_radio;
|
||||||
|
signal(SIGINT, handle_signal);
|
||||||
|
signal(SIGTERM, handle_signal);
|
||||||
|
|
||||||
|
if (!its_radio.init()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
its_radio.start();
|
||||||
|
|
||||||
|
// Work around dlt-daemon timeout on exit
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,508 @@
|
||||||
|
#include "radio-stations.hpp"
|
||||||
|
|
||||||
|
#define SONGS(_station) (_station ## _songs), sizeof(_station ## _songs)/sizeof(struct song_info_t)
|
||||||
|
|
||||||
|
static struct song_info_t radio_los_santos_songs[] = {
|
||||||
|
{ "YG", "I'm A Real 1", 2013 },
|
||||||
|
{ "100s", "Life of a Mack", 2013 },
|
||||||
|
{ "Ab-Soul feat. Kendrick Lamar", "ILLuminate", 2012 },
|
||||||
|
{ "A$AP Rocky feat. Aston Matthews & Joey Fatts", "R-Cali", 2013 },
|
||||||
|
{ "Marion Band$ feat. Nipsey Hussle", "Hold Up", 2013 },
|
||||||
|
{ "BJ the Chicago Kid feat. Freddie Gibbs & Problem", "Smokin' and Ridin'", 2013 },
|
||||||
|
{ "Kendrick Lamar", "A.D.H.D", 2011 },
|
||||||
|
{ "Jay Rock feat. Kendrick Lamar", "Hood Gone Love It", 2011 },
|
||||||
|
{ "The Game feat. 2 Chainz & Rick Ross", "Ali Bomaye", 2012 },
|
||||||
|
{ "Freddie Gibbs", "Still Livin'", 2012 },
|
||||||
|
{ "DJ Esco feat. Future", "How It Was", 2013 },
|
||||||
|
{ "Problem feat. Glasses Malone", "Say That Then", 2013 },
|
||||||
|
{ "Clyde Carson feat. The Team", "Slow Down", 2012 },
|
||||||
|
{ "Gucci Mane feat. Ciara", "Too Hood", 2011 },
|
||||||
|
{ "Gangrene", "Bassheads", 2013 },
|
||||||
|
{ "Danny Brown & Action Bronson", "Bad News", 2013 },
|
||||||
|
{ "G-Side feat. G-Mane", "Relaxin'", 2010 },
|
||||||
|
{ "A$AP Ferg", "Work", 2013 },
|
||||||
|
{ "Trouble feat. Gucci Mane", "Everyday", 2012 },
|
||||||
|
{ "Kendrick Lamar", "Swimming Pools, Drank", 2012 },
|
||||||
|
{ "Travi$ Scott feat. 2 Chainz & T.I.", "Upper Echelon", 2013 },
|
||||||
|
{ "Danny Brown feat. A$AP Rocky & Zelooperz", "Kush Coma", 2013 },
|
||||||
|
{ "Ace Hood feat. Future & Rick Ross", "Bugatti", 2013 },
|
||||||
|
{ "Schoolboy Q feat. Kendrick Lamar", "Collard Greens", 2013 },
|
||||||
|
{ "Chuck Inglish feat. Ab-Soul & Mac Miller", "Came Thru/Easily", 2013 },
|
||||||
|
{ "Young Scooter feat. Gucci Mane", "Work", 2013 },
|
||||||
|
{ "Problem & IamSu feat. Bad Lucc & Sage The Gemini", "Do It Big", 2013 },
|
||||||
|
{ "Skeme", "Millions", 2013 },
|
||||||
|
{ "Ab-Soul feat. Schoolboy Q", "Hunnid Stax", 2014 },
|
||||||
|
{ "Freddie Gibbs & Mike Dean", "Sellin' Dope", 2014 },
|
||||||
|
{ "Young Scooter feat. Trinidad James", "I Can't Wait", 2013 },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static struct song_info_t space_103_2_songs[] = {
|
||||||
|
{ "Bootsy's Rubber Band", "I'd Rather Be With You", 1976 },
|
||||||
|
{ "D-Train", "You're the One for Me", 1981 },
|
||||||
|
{ "Eddie Murphy", "Party All the Time", 1985 },
|
||||||
|
{ "Evelyn \"Champagne\" King", "I'm in Love, 12\" Version", 1981 },
|
||||||
|
{ "Kano", "Can't Hold Back, Your Loving", 1981 },
|
||||||
|
{ "Kleeer", "Tonight", 1984 },
|
||||||
|
{ "Bernard Wright", "Haboglabotribin’", 1981 },
|
||||||
|
{ "One Way", "Cutie Pie", 1982 },
|
||||||
|
{ "Rick James", "Give It to Me Baby", 1981 },
|
||||||
|
{ "Sho Nuff", "Funkasize You", 1978 },
|
||||||
|
{ "Stevie Wonder", "Skeletons", 1987 },
|
||||||
|
{ "Taana Gardner", "Heartbeat, Club Version", 1981 },
|
||||||
|
{ "Zapp", "Heartbreaker, Pts. 1-2", 1983 },
|
||||||
|
{ "Dazz Band", "Joystick", 1983 },
|
||||||
|
{ "Roger", "Do It Roger", 1981 },
|
||||||
|
{ "Imagination", "Flashback", 1981 },
|
||||||
|
{ "Parliament", "Mothership Connection, Star Child", 1975 },
|
||||||
|
{ "The Fatback Band", "Gotta Get My Hands On Some, Money", 1979 },
|
||||||
|
{ "Billy Ocean", "Nights, Feel Like Gettin' Down", 1981 },
|
||||||
|
{ "Parliament", "Flash Light", 1977 },
|
||||||
|
{ "Cameo", "Back and Forth", 1986 },
|
||||||
|
{ "Central Line", "Walking Into Sunshine", 1981 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t west_cost_classics_songs[] = {
|
||||||
|
{ "2Pac", "Ambitionz Az a Ridah", 1996 },
|
||||||
|
{ "Compton's Most Wanted", "Late Night Hype", 1990 },
|
||||||
|
{ "DJ Quik", "Dollaz + Sense", 1995 },
|
||||||
|
{ "Dr. Dre feat. Snoop Dogg", "Still D.R.E", 1999 },
|
||||||
|
{ "King Tee", "Played Like a Piano", 1990 },
|
||||||
|
{ "Dr. Dre feat. Snoop Dogg, Kurupt & Nate Dogg", "The Next Episode", 1999 },
|
||||||
|
{ "Ice Cube", "You Know How We Do It", 1994 },
|
||||||
|
{ "Kausion feat. Ice Cube", "What You Wanna Do?", 1995 },
|
||||||
|
{ "Kurupt", "C-Walk", 1998 },
|
||||||
|
{ "Mack 10 & Tha Dogg Pound", "Nothin' But the Cavi Hit", 1996 },
|
||||||
|
{ "MC Eiht", "Streiht Up Menace", 1993 },
|
||||||
|
{ "N.W.A", "Appetite for Destruction", 1991 },
|
||||||
|
{ "N.W.A", "Gangsta Gangsta", 1988 },
|
||||||
|
{ "Tha Dogg Pound", "What Would U Do?", 1995 },
|
||||||
|
{ "Snoop Dogg", "Gin and Juice", 1993 },
|
||||||
|
{ "Geto Boys", "Mind Playing Tricks on Me", 1991 },
|
||||||
|
{ "Too $hort", "So You Want to Be a Gangster", 1992 },
|
||||||
|
{ "Jayo Felony", "Sherm Stick", 1995 },
|
||||||
|
{ "Warren G", "This D.J.", 1994 },
|
||||||
|
{ "CPO feat. MC Ren", "Ballad Of A Menace", 1990 },
|
||||||
|
{ "E-40 feat. The Click", "Captain Save a Hoe", 1994 },
|
||||||
|
{ "The Conscious Daughters", "We Roll Deep", 1993 },
|
||||||
|
{ "Eazy-E feat. Ice Cube", "No More ?'s", 1988 },
|
||||||
|
{ "South Central Cartel", "Servin' 'Em Heat", 1993 },
|
||||||
|
{ "The Lady of Rage feat. Snoop Dogg", "Afro Puffs", 1994 },
|
||||||
|
{ "Westside Connection", "Bow Down", 1996 },
|
||||||
|
{ "Spice 1 feat. MC Eiht", "The Murda Show", 1993 },
|
||||||
|
{ "Bone Thugs-N-Harmony", "1st of Tha Month", 1995 },
|
||||||
|
{ "Luniz feat. Michael Marshall", "I Got 5 On It", 1995 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t rebel_radio_songs[] = {
|
||||||
|
{ "Charlie Feathers", "Can't Hardly Stand It", 1956 },
|
||||||
|
{ "Hank Thompson", "It Don't Hurt Anymore", 1957 },
|
||||||
|
{ "Hasil Adkins", "Get Outta My Car", 1966 },
|
||||||
|
{ "Jerry Reed", "You Took All the Ramblin' Out of Me", 1972 },
|
||||||
|
{ "Johnny Cash", "The General Lee", 1981 },
|
||||||
|
{ "Johnny Paycheck", "(It Won't Be Long And I'll Be Hating You", 1968 },
|
||||||
|
{ "Ozark Mountain Daredevils", "If You Wanna Get to Heaven", 1973 },
|
||||||
|
{ "Waylon Jennings", "Are You Sure Hank Done It This Way", 1975 },
|
||||||
|
{ "Waylon Jennings", "I Ain't Living Long Like This", 1979 },
|
||||||
|
{ "Willie Nelson", "Whiskey River", 1973 },
|
||||||
|
{ "C.W. McCall", "Convoy", 1975 },
|
||||||
|
{ "Homer & Jethro", "She Made Toothpicks Of The Timber Of My Heart", 1963 },
|
||||||
|
{ "The Highwaymen", "Highwayman", 1985 },
|
||||||
|
{ "Tammy Wynette", "D-I-V-O-R-C-E", 1968 },
|
||||||
|
{ "Ray Price", "Crazy Arms", 1956 },
|
||||||
|
{ "Marvin Jackson", "Dippin' Snuff", 1957 },
|
||||||
|
{ "Charlie Feathers", "Get With It", 1956 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t los_santos_rock_radio_songs[] = {
|
||||||
|
{ "Billy Squier", "Lonely Is the Night", 1981 },
|
||||||
|
{ "Bob Seger & The Silver Bullet Band", "Hollywood Nights", 1978 },
|
||||||
|
{ "Bob Seger & The Silver Bullet Band", "Night Moves", 1976 },
|
||||||
|
{ "Chicago", "If You Leave Me Now", 1976 },
|
||||||
|
{ "Def Leppard", "Photograph", 1983 },
|
||||||
|
{ "Don Johnson", "Heartbeat", 1986 },
|
||||||
|
{ "Elton John", "Saturday Night's Alright for Fighting", 1973 },
|
||||||
|
{ "Foreigner", "Dirty White Boy", 1979 },
|
||||||
|
{ "Gerry Rafferty", "Baker Street", 1978 },
|
||||||
|
{ "The Greg Kihn Band", "The Breakup Song, They Don't Write 'Em", 1981 },
|
||||||
|
{ "Julian Lennon", "Too Late for Goodbyes", 1984 },
|
||||||
|
{ "Kenny Loggins", "I'm Free, Heaven Helps the Man", 1984 },
|
||||||
|
{ "Phil Collins", "I Don't Care Anymore", 1982 },
|
||||||
|
{ "Queen", "Radio Ga Ga", 1984 },
|
||||||
|
{ "Robert Plant", "Big Log", 1983 },
|
||||||
|
{ "Simple Minds", "All the Things She Said", 1985 },
|
||||||
|
{ "The Small Faces", "Ogdens' Nut Gone Flake", 1968 },
|
||||||
|
{ "Steve Winwood", "Higher Love", 1986 },
|
||||||
|
{ "Stevie Nicks", "I Can't Wait", 1985 },
|
||||||
|
{ "The Alan Parsons Project", "I Wouldn't Want To Be Like You", 1977 },
|
||||||
|
{ "The Doobie Brothers", "What a Fool Believes", 1979 },
|
||||||
|
{ "The Cult", "Rain", 1985 },
|
||||||
|
{ "Steve Miller Band", "Rock'n Me", 1976 },
|
||||||
|
{ "Creedence Clearwater Revival", "Fortunate Son", 1969 },
|
||||||
|
{ "Starship", "We Built This City", 1985 },
|
||||||
|
{ "Mountain", "Mississippi Queen", 1970 },
|
||||||
|
{ "Kenny Loggins", "Danger Zone", 1986 },
|
||||||
|
{ "Alannah Myles", "Black Velvet", 1989 },
|
||||||
|
{ "Pat Benatar", "Shadows of the Night", 1982 },
|
||||||
|
{ "Belinda Carlisle", "Circle in the Sand", 1987 },
|
||||||
|
{ "Kansas", "Carry On Wayward Son", 1976 },
|
||||||
|
{ "Boston", "Peace Of Mind", 1976 },
|
||||||
|
{ "Harry Chapin", "Cat's In the Cradle", 1974 },
|
||||||
|
{ "Survivor", "Burning Heart", 1986 },
|
||||||
|
{ "Humble Pie", "30 Days In the Hole", 1972 },
|
||||||
|
{ "ZZ Top", "Gimme All Your Lovin'", 1983 },
|
||||||
|
{ "Yes", "Roundabout", 1972 },
|
||||||
|
{ "Broken English", "Comin' On Strong", 1987 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t the_lowdown_songs[] = {
|
||||||
|
{ "Aaron Neville", "Hercules", 1973 },
|
||||||
|
{ "B.T. Express", "Do It, 'Til You're Satisfied", 1974 },
|
||||||
|
{ "El Chicano", "Viva Tirado", 1970 },
|
||||||
|
{ "George McCrae", "I Get Lifted", 1974 },
|
||||||
|
{ "Marlena Shaw", "California Soul", 1969 },
|
||||||
|
{ "Smokey Robinson", "Cruisin'", 1979 },
|
||||||
|
{ "The Delfonics", "Ready or Not Here I Come, Can't Hide from Love", 1968 },
|
||||||
|
{ "The Five Stairsteps", "O-O-H Child", 1970 },
|
||||||
|
{ "The Soul Searchers", "Ashley's Roachclip", 1974 },
|
||||||
|
{ "The Trammps", "Rubber Band", 1972 },
|
||||||
|
{ "The Undisputed Truth", "Smiling Faces Sometimes", 1971 },
|
||||||
|
{ "War", "The Cisco Kid", 1973 },
|
||||||
|
{ "Pleasure", "Bouncy Lady", 1975 },
|
||||||
|
{ "The Delfonics", "Funny Feeling", 1970 },
|
||||||
|
{ "Ohio Players", "Climax", 1974 },
|
||||||
|
{ "The Chakachas", "Stories", 1972 },
|
||||||
|
{ "Eric Burdon & War", "Magic Mountain", 1976 },
|
||||||
|
{ "Johnny \"Guitar\" Watson", "Superman Lover", 1976 },
|
||||||
|
{ "The Jackson Sisters", "I Believe In Miracles", 1973 },
|
||||||
|
{ "Brass Construction", "Changin'", 1975 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t the_blue_ark_songs[] = {
|
||||||
|
{ "Chronixx", "Odd Ras", 2012 },
|
||||||
|
{ "Dennis Brown", "Money In My Pocket", 1972 },
|
||||||
|
{ "Gregory Isaacs", "Night Nurse", 1982 },
|
||||||
|
{ "Half Pint", "Crazy Girl", 1997 },
|
||||||
|
{ "Joe Gibbs & The Professionals", "Chapter Three", 1978 },
|
||||||
|
{ "Junior Delgado", "Sons Of Slaves", 1977 },
|
||||||
|
{ "Konshens", "Gun Shot A Fire", 2012 },
|
||||||
|
{ "Lee \"Scratch\" Perry & The Upsetters", "I Am A Madman", 1986 },
|
||||||
|
{ "Lee \"Scratch\" Perry & The Full Experience", "Disco Devil", 1977 },
|
||||||
|
{ "The Upsetters", "Grumblin' Dub", 1977 },
|
||||||
|
{ "Tommy Lee Sparta", "Psycho", 2012 },
|
||||||
|
{ "Vybz Kartel feat. Popcaan", "We Never Fear Dem", 2011 },
|
||||||
|
{ "Yellowman", "Nobody Move, Nobody Get Hurt", 1984 },
|
||||||
|
{ "Protoje", "Kingston Be Wise", 2012 },
|
||||||
|
{ "Demarco", "Loyal, Royals Remix", 2014 },
|
||||||
|
{ "Busy Signal feat. Damian \"Jr. Gong\" Marley", "Kingston Town, Remix", 2012 },
|
||||||
|
{ "I-Octane", "Topic of the Day", 2011 },
|
||||||
|
{ "Vybz Kartel", "Addi Truth", 2014 },
|
||||||
|
{ "Lee \"Scratch\" Perry", "Money Come and Money Go", 2010 },
|
||||||
|
{ "Lee \"Scratch\" Perry", "Roast Fish & Cornbread", 1978 },
|
||||||
|
{ "Danny Hensworth", "Mr. Money Man", 1978 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t non_stop_pop_songs[] = {
|
||||||
|
{ "All Saints", "Pure Shores", 1999 },
|
||||||
|
{ "Britney Spears", "Gimme More", 2007 },
|
||||||
|
{ "Corona", "The Rhythm of the Night, Rapino Bros. 7'' Single", 1993 },
|
||||||
|
{ "Fergie feat. Ludacris", "Glamorous", 2006 },
|
||||||
|
{ "Hall & Oates", "Adult Education", 1983 },
|
||||||
|
{ "Jane Child", "Don't Wanna Fall In Love", 1990 },
|
||||||
|
{ "Kelly Rowland", "Work, Freemasons Remix", 2007 },
|
||||||
|
{ "Mis-Teeq", "Scandalous", 2003 },
|
||||||
|
{ "Modjo", "Lady, Hear Me Tonight", 2000 },
|
||||||
|
{ "N-Joi", "Anthem", 1990 },
|
||||||
|
{ "Pet Shop Boys", "West End Girls", 1985 },
|
||||||
|
{ "Rihanna", "Only Girl, In The World", 2010 },
|
||||||
|
{ "Robyn feat. Kleerup", "With Every Heartbeat", 2007 },
|
||||||
|
{ "Stardust", "Music Sounds Better With You", 1998 },
|
||||||
|
{ "Wham!", "Everything She Wants", 1984 },
|
||||||
|
{ "Amerie", "1 Thing", 2005 },
|
||||||
|
{ "Robert Howard & Kym Mazelle", "Wait", 1989 },
|
||||||
|
{ "Sly Fox", "Let's Go All the Way", 1985 },
|
||||||
|
{ "Taylor Dayne", "Tell It to My Heart", 1987 },
|
||||||
|
{ "Living In A Box", "Living In A Box", 1987 },
|
||||||
|
{ "INXS", "New Sensation", 1988 },
|
||||||
|
{ "Bobby Brown", "On Our Own", 1989 },
|
||||||
|
{ "Bronski Beat", "Smalltown Boy", 1984 },
|
||||||
|
{ "Naked Eyes", "Promises, Promises", 1983 },
|
||||||
|
{ "Simply Red", "Something Got Me Started, Hurley's House Mix", 1991 },
|
||||||
|
{ "Sneaker Pimps", "6 Underground", 1996 },
|
||||||
|
{ "Backstreet Boys", "I Want It That Way", 1999 },
|
||||||
|
{ "Jamiroquai", "Alright", 1996 },
|
||||||
|
{ "Morcheeba", "Tape Loop, Shortcheeba Mix", 1996 },
|
||||||
|
{ "Moloko", "The Time Is Now", 2000 },
|
||||||
|
{ "Gorillaz feat. De La Soul", "Feel Good Inc.", 2005 },
|
||||||
|
{ "Robbie Williams & Kylie Minogue", "Kids", 2000 },
|
||||||
|
{ "Dirty Vegas", "Days Go By", 2001 },
|
||||||
|
{ "Cassie", "Me & U", 2006 },
|
||||||
|
{ "Maroon 5 feat. Christina Aguilera", "Moves Like Jagger", 2011 },
|
||||||
|
{ "M.I.A.", "Bad Girls", 2012 },
|
||||||
|
{ "M83", "Midnight City", 2011 },
|
||||||
|
{ "Lady Gaga", "Applause", 2013 },
|
||||||
|
{ "Mike Posner", "Cooler Than Me", 2010 },
|
||||||
|
{ "Lorde", "Tennis Court", 2013 },
|
||||||
|
{ "The Black Eyed Peas", "Meet Me Halfway", 2009 },
|
||||||
|
{ "Real Life", "Send Me An Angel '89", 1989 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t east_los_songs[] = {
|
||||||
|
{ "Hechizeros Band", "El Sonidito", 2008 },
|
||||||
|
{ "Los Buitres de Culiacan", "El Cocaino", 2012 },
|
||||||
|
{ "Mexican Institute of Sound", "Es-Toy", 2012 },
|
||||||
|
{ "Niña Dioz", "Criminal Sound, El Hijo De La Cumbia Remix", 2010 },
|
||||||
|
{ "La Vida Bohème", "Radio Capital", 2011 },
|
||||||
|
{ "Fandango", "Autos, Moda y Rock and Roll", 1987 },
|
||||||
|
{ "Don Cheto", "El Tatuado", 2007 },
|
||||||
|
{ "La Sonora Dinamita", "Se Me Perdió La Cadenita", 1978 },
|
||||||
|
{ "Fiebre de Jack", "She's A Tease", 2010 },
|
||||||
|
{ "Maldita Vecindad", "Pachuco", 1991 },
|
||||||
|
{ "Jessy Bulbo", "Maldito", 2007 },
|
||||||
|
{ "Milkman", "Fresco", 2012 },
|
||||||
|
{ "La Liga ft. Alika", "Tengo El Don", 2012 },
|
||||||
|
{ "Los Tigres Del Norte", "La Granja", 2009 },
|
||||||
|
{ "Los Ángeles Negros", "El Rey Y Yo", 1970 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t worldwide_songs[] = {
|
||||||
|
{ "Cashmere Cat", "Mirror Maru", 2012 },
|
||||||
|
{ "The Hics", "Cold Air", 2013 },
|
||||||
|
{ "inc.", "The Place", 2013 },
|
||||||
|
{ "Trickski", "Beginning", 2011 },
|
||||||
|
{ "Mala", "Ghost", 2012 },
|
||||||
|
{ "Swindle", "Forest Funk", 2012 },
|
||||||
|
{ "Tom Browne", "Throw Down", 1979 },
|
||||||
|
{ "Donald Byrd", "You And The Music", 1975 },
|
||||||
|
{ "Candido", "Thousand Finger Man", 1970 },
|
||||||
|
{ "Toro Y Moi", "Harm in Change", 2013 },
|
||||||
|
{ "Kyodai", "Breaking", 2012 },
|
||||||
|
{ "Django Django", "Waveforms", 2011 },
|
||||||
|
{ "The Gaslamp Killer", "Nissim", 2012 },
|
||||||
|
{ "Owiny Sigoma Band", "Harpoon Land", 2013 },
|
||||||
|
{ "Guts", "Brand New Revolution", 2011 },
|
||||||
|
{ "Yuna", "Live Your Life, MELO-X MOTHERLAND GOD MIX", 2012 },
|
||||||
|
{ "Tucillo & Kiko Navarro feat. Amor", "Lovery, Slow Cuban Vibe Mix", 2012 },
|
||||||
|
{ "Richard Spaven", "1759, Outro", 2010 },
|
||||||
|
{ "Hackman", "Forgotten Notes", 2012 },
|
||||||
|
{ "Sinkane feat. Salvatore Principato", "Shark Week", 2014 },
|
||||||
|
{ "William Onyeabor", "Body & Soul", 1980 },
|
||||||
|
{ "Four Tet", "Kool FM", 2013 },
|
||||||
|
{ "Mount Kimbie", "Made To Stray", 2013 },
|
||||||
|
{ "Anushka", "World in a Room", 2014 },
|
||||||
|
{ "Smokey Robinson", "Why You Wanna See My Bad Side?", 1978 },
|
||||||
|
{ "Randy Crawford", "Street Life", 1979 },
|
||||||
|
{ "Flume", "What You Need", 2012 },
|
||||||
|
{ "Earl Sweatshirt feat. Vince Staples & Casey Veggies", "Hive", 2013 },
|
||||||
|
{ "Portishead", "Numb", 1994 },
|
||||||
|
{ "Jon Wayne", "Black Magic", 2013 },
|
||||||
|
{ "Roman GianArthur", "I-69", 2013 },
|
||||||
|
{ "Lion Babe", "Treat Me Like Fire", 2013 },
|
||||||
|
{ "Dam-Funk", "Killdat", 2009 },
|
||||||
|
{ "Jamie Lidell", "Runaway", 2014 },
|
||||||
|
{ "CHVRCHES", "Recover, Cid Rim Remix", 2013 },
|
||||||
|
{ "Jimmy Edgar", "Let Yrself Be", 2012 },
|
||||||
|
{ "Clap! Clap!", "Viajero", 2014 },
|
||||||
|
{ "Maga Bo feat. Rosangela Macedo and Marcelo Yuka", "No Balanço da Canoa", 2012 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t channel_x_songs[] = {
|
||||||
|
{ "Agent Orange", "Bored of You", 1980 },
|
||||||
|
{ "Black Flag", "My War", 1984 },
|
||||||
|
{ "Circle Jerks", "Rock House", 1985 },
|
||||||
|
{ "Fear", "The Mouth Don't Stop, The Trouble With Women Is", 1985 },
|
||||||
|
{ "OFF!", "What's Next", 2013 },
|
||||||
|
{ "Adolescents", "Amoeba", 1981 },
|
||||||
|
{ "Descendents", "Pervert", 1985 },
|
||||||
|
{ "The Germs", "Lexicon Devil", 1978 },
|
||||||
|
{ "The Weirdos", "Life of Crime", 1977 },
|
||||||
|
{ "T.S.O.L.", "Abolish Government/Silent Majority", 1981 },
|
||||||
|
{ "Youth Brigade", "Blown Away", 1983 },
|
||||||
|
{ "Suicidal Tendencies", "Subliminal", 1983 },
|
||||||
|
{ "D.O.A.", "The Enemy", 1980 },
|
||||||
|
{ "MDC", "John Wayne Was a Nazi", 1980 },
|
||||||
|
{ "The Zeros", "Don't Push Me Around", 1980 },
|
||||||
|
{ "X", "Los Angeles", 1980 },
|
||||||
|
{ "D.R.I.", "I Don't Need Society", 1985 },
|
||||||
|
{ "Redd Kross", "Linda Blair", 1982 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t radio_mirror_park_songs[] = {
|
||||||
|
{ "Battle Tapes", "Feel the Same", 2012 },
|
||||||
|
{ "Dan Croll", "From Nowhere, Baardsen Remix", 2012 },
|
||||||
|
{ "DJ Mehdi", "Lucky Boy, Outlines Remix", 2006 },
|
||||||
|
{ "Feathers", "Dark Matter", 2013 },
|
||||||
|
{ "Jai Paul", "Jasmine, Demo Version", 2012 },
|
||||||
|
{ "Living Days", "Little White Lie", 2010 },
|
||||||
|
{ "Miami Horror", "Sometimes", 2009 },
|
||||||
|
{ "Tony Castles", "Heart In The Pipes, KAUF Remix", 2011 },
|
||||||
|
{ "Toro Y Moi", "So Many Details", 2012 },
|
||||||
|
{ "Twin Shadow", "Shooting Holes", 2010 },
|
||||||
|
{ "Twin Shadow", "Old Love / New Love", 2013 },
|
||||||
|
{ "Y.A.C.H.T.", "Psychic City, Classixx Remix", 2009 },
|
||||||
|
{ "Black Strobe", "Boogie in Zero Gravity", 2012 },
|
||||||
|
{ "Age of Consent", "Colours", 2013 },
|
||||||
|
{ "Favored Nations", "The Set Up", 2013 },
|
||||||
|
{ "Neon Indian", "Change Of Coast", 2013 },
|
||||||
|
{ "Nite Jewel", "Nowhere To Go", 2013 },
|
||||||
|
{ "Yeasayer", "Don't Come Close", 2013 },
|
||||||
|
{ "The Chain Gang of 1974", "Sleepwalking", 2013 },
|
||||||
|
{ "Poolside", "Do You Believe?", 2010 },
|
||||||
|
{ "The C90s", "Shine A Light, Flight Facilities Remix", 2010 },
|
||||||
|
{ "HEALTH", "High Pressure Dave", 2013 },
|
||||||
|
{ "The Ruby Suns", "In Real Life", 2013 },
|
||||||
|
{ "Neon Indian", "Polish Girl", 2011 },
|
||||||
|
{ "Mitzi", "Truly Alive", 2013 },
|
||||||
|
{ "KAUF", "When You're Out", 2013 },
|
||||||
|
{ "Panama", "Always", 2014 },
|
||||||
|
{ "Twin Shadow", "Forget", 2010 },
|
||||||
|
{ "!!!", "One Girl/One Boy", 2013 },
|
||||||
|
{ "SBTRKT feat. Roses Gabor", "Pharaohs", 2011 },
|
||||||
|
{ "Yeasayer", "O.N.E.", 2010 },
|
||||||
|
{ "Toro Y Moi", "New Beat", 2011 },
|
||||||
|
{ "Niki and the Dove", "The Drummer", 2011 },
|
||||||
|
{ "Little Dragon", "Crystalfilm", 2011 },
|
||||||
|
{ "Hot Chip", "Flutes", 2012 },
|
||||||
|
{ "Dom", "Living In America", 2010 },
|
||||||
|
{ "Holy Ghost!", "Hold On", 2011 },
|
||||||
|
{ "Scenic", "Mesmerised", 2013 },
|
||||||
|
{ "Cut Copy", "Strangers in the Wind", 2008 },
|
||||||
|
{ "Age of Consent", "Heartbreak", 2012 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t vinewood_boulevard_songs[] = {
|
||||||
|
{ "Wavves", "Nine Is God", 2013 },
|
||||||
|
{ "FIDLAR", "Cocaine", 2013 },
|
||||||
|
{ "Bass Drum of Death", "Crawling After You", 2013 },
|
||||||
|
{ "Hot Snakes", "This Mystic Decade", 2004 },
|
||||||
|
{ "Moon Duo", "Sleepwalker", 2012 },
|
||||||
|
{ "Sam Flax", "Fire Doesn't Burn Itself", 2012 },
|
||||||
|
{ "Shark?", "California Grrls", 2013 },
|
||||||
|
{ "The Black Angels", "Black Grease", 2005 },
|
||||||
|
{ "METZ", "Wet Blanket", 2012 },
|
||||||
|
{ "Ceremony", "Hysteria", 2012 },
|
||||||
|
{ "Ty Segall Band", "Diddy Wah Diddy", 2012 },
|
||||||
|
{ "Thee Oh Sees", "The Dream", 2011 },
|
||||||
|
{ "The Men", "Turn It Around", 2012 },
|
||||||
|
{ "Bleached", "Next Stop", 2013 },
|
||||||
|
{ "JEFF the Brotherhood", "Sixpack", 2012 },
|
||||||
|
{ "Coliseum", "Used Blood", 2013 },
|
||||||
|
{ "The Soft Pack", "Answer to Yourself", 2009 },
|
||||||
|
{ "The Orwells", "Who Needs You", 2013 },
|
||||||
|
{ "Nobunny", "Gone For Good", 2010 },
|
||||||
|
{ "Mind Spiders", "Fall in Line", 2012 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t soulwax_songs[] = {
|
||||||
|
{ "Palmbomen", "Stock, Soulwax Remix", 2013 },
|
||||||
|
{ "Fatal Error", "Fatal Error", 1988 },
|
||||||
|
{ "Supersempfft", "Let's Beam Him Up", 1979 },
|
||||||
|
{ "Mim Suleiman", "Mingi", 2010 },
|
||||||
|
{ "FKClub", "The Strange Art, Inflagranti Remix", 2013 },
|
||||||
|
{ "Matias Aguayo", "El Sucu Tucu", 2013 },
|
||||||
|
{ "Daniel Avery", "Naive Response", 2013 },
|
||||||
|
{ "Joe Goddard feat. Valentina", "Gabriel, Soulwax Remix", 2012 },
|
||||||
|
{ "Daniel Maloso", "Body Music, Original Mix", 2012 },
|
||||||
|
{ "Green Velvet & Harvard Bass", "Lazer Beams", 2012 },
|
||||||
|
{ "Zombie Nation", "Tryouts", 2012 },
|
||||||
|
{ "Tom Rowlands", "Nothing But Pleasure", 2013 },
|
||||||
|
{ "Jackson and His Computerband", "Arp #1", 2013 },
|
||||||
|
{ "Goose", "Synrise, Soulwax Remix", 2013 },
|
||||||
|
{ "Transistorcake", "Mr. Croissant Taker", 2013 },
|
||||||
|
{ "Tiga", "Plush, Jacques Lu Cont Remix", 2012 },
|
||||||
|
{ "The Hacker", "Shockwave, Gesaffelstein Remix", 2012 },
|
||||||
|
{ "Pulp", "After You, Soulwax Remix", 2013 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t flylo_songs[] = {
|
||||||
|
{ "Flying Lotus feat. Niki Randa", "Getting There", 2012 },
|
||||||
|
{ "Clams Casino", "Crystals", 2013 },
|
||||||
|
{ "Flying Lotus", "Crosswerved", 2013 },
|
||||||
|
{ "Flying Lotus", "Be Spin", 2013 },
|
||||||
|
{ "Flying Lotus feat. Erykah Badu", "See Thru To U", 2013 },
|
||||||
|
{ "Flying Lotus", "The Diddler", 2013 },
|
||||||
|
{ "Flying Lotus", "Computer Face Rmx", 2011 },
|
||||||
|
{ "Hudson Mohawke", "100hm", 2013 },
|
||||||
|
{ "Flying Lotus feat. Niki Randa", "The Kill", 2013 },
|
||||||
|
{ "Tyler, the Creator", "Garbage", 2013 },
|
||||||
|
{ "Outkast", "Elevators, Me & You", 1996 },
|
||||||
|
{ "Captain Murphy", "Evil Grin", 2013 },
|
||||||
|
{ "Flying Lotus", "Catapult Man", 2013 },
|
||||||
|
{ "Dabrye", "Encoded Flow", 2006 },
|
||||||
|
{ "Machinedrum", "She Died There", 2011 },
|
||||||
|
{ "DJ Rashad", "It's Wack", 2013 },
|
||||||
|
{ "Thundercat", "Oh Sheit It's X", 2013 },
|
||||||
|
{ "Flying Lotus", "Stonecutters", 2013 },
|
||||||
|
{ "Shadow Child", "23", 2012 },
|
||||||
|
{ "Kingdom", "Stalker Ha", 2011 },
|
||||||
|
{ "Aphex Twin", "Windowlicker", 1999 },
|
||||||
|
{ "Curtis Mayfield", "Eddie You Should Know Better", 1972 },
|
||||||
|
{ "Doris", "You Never Come Closer", 1970 },
|
||||||
|
{ "Flying Lotus feat. Krayzie Bone", "Medication Medication", 2014 },
|
||||||
|
{ "XXYYXX", "Work Title: What We Want", 2014 },
|
||||||
|
{ "Lapalux", "Make Money", 2014 },
|
||||||
|
{ "The Gaslamp Killer", "Shred You To Bits", 2014 },
|
||||||
|
{ "Mono/Poly & Thundercat", "B Adams", 2014 },
|
||||||
|
{ "Flying Lotus", "Osaka Trade", 2013 },
|
||||||
|
{ "DOOM", "Masquatch", 2014 },
|
||||||
|
{ "Flying Lotus", "Early Mountain", 2014 },
|
||||||
|
{ "Dimlite", "Into Vogon Skulls", 2012 },
|
||||||
|
{ "KNOWER", "Fuck the Makeup, Skip the Shower", 2010 },
|
||||||
|
{ "Kaskade", "4 AM, Araabmuzik Remix", 2006 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct song_info_t the_lab_songs[] = {
|
||||||
|
{ "Gangrene feat. Samuel T. Herring & Earl Sweatshirt", "Play It Cool", 2015 },
|
||||||
|
{ "Ab-Soul feat. Aloe Blacc", "Trouble", 2015 },
|
||||||
|
{ "Tunde Adebimpe feat. Sal P & Sinkane", "Speedline Miracle Masterpiece", 2015 },
|
||||||
|
{ "MC Eiht & Freddie Gibbs feat. Kokane", "Welcome to Los Santos", 2015 },
|
||||||
|
{ "Phantogram", "K.Y.S.A", 2015 },
|
||||||
|
{ "Vybz Kartel", "Fast Life", 2015 },
|
||||||
|
{ "King Avriel feat. A$AP Ferg", "20's 50's 100's", 2015 },
|
||||||
|
{ "MNDR feat. Killer Mike", "Lock & Load", 2015 },
|
||||||
|
{ "Popcaan feat. Freddie Gibbs", "Born Bad", 2015 },
|
||||||
|
{ "E-40 feat. Dam-Funk & Ariel Pink", "California", 2015 },
|
||||||
|
{ "Wavves", "Leave", 2015 },
|
||||||
|
{ "Curren$y & Freddie Gibbs", "Fetti", 2015 },
|
||||||
|
{ "Little Dragon", "Wanderer", 2015 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radio_station_info_t radio_stations[] = {
|
||||||
|
{ "Radio Los Santos", SONGS(radio_los_santos) },
|
||||||
|
{ "Space 103.2", SONGS(space_103_2) },
|
||||||
|
{ "West Coast Classics", SONGS(west_cost_classics) },
|
||||||
|
{ "Rebel Radio", SONGS(rebel_radio) },
|
||||||
|
{ "Los Santos Rock Radio", SONGS(los_santos_rock_radio) },
|
||||||
|
{ "The Lowdown 91.1", SONGS(the_lowdown) },
|
||||||
|
{ "The Blue Ark", SONGS(the_blue_ark) },
|
||||||
|
{ "Non-Stop-Pop FM", SONGS(non_stop_pop) },
|
||||||
|
{ "East Los FM", SONGS(east_los) },
|
||||||
|
{ "WorldWide FM", SONGS(worldwide) },
|
||||||
|
{ "Channel X", SONGS(channel_x) },
|
||||||
|
{ "Radio Mirror Park", SONGS(radio_mirror_park) },
|
||||||
|
{ "Vinewood Boulevard Radio", SONGS(vinewood_boulevard) },
|
||||||
|
{ "Soulwax FM", SONGS(soulwax) },
|
||||||
|
{ "FlyLo FM", SONGS(flylo) },
|
||||||
|
{ "The Lab", SONGS(the_lab) },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define N_STATIONS sizeof(radio_stations)/sizeof(struct radio_station_info_t)
|
||||||
|
|
||||||
|
void
|
||||||
|
radio_stations_init(void)
|
||||||
|
{
|
||||||
|
for (uint32_t i = 0; i < N_STATIONS; i++)
|
||||||
|
radio_stations[i].id = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
n_radio_stations(void)
|
||||||
|
{
|
||||||
|
return N_STATIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const radio_station_info_t *
|
||||||
|
get_radio_stations(uint32_t id)
|
||||||
|
{
|
||||||
|
return &radio_stations[id];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct song_info_t {
|
||||||
|
const char *artist;
|
||||||
|
const char *name;
|
||||||
|
uint32_t year;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct radio_station_info_t {
|
||||||
|
const char *name;
|
||||||
|
song_info_t *songs;
|
||||||
|
uint32_t n_songs;
|
||||||
|
uint32_t id;
|
||||||
|
};
|
||||||
|
|
||||||
|
void radio_stations_init(void);
|
||||||
|
uint32_t n_radio_stations(void);
|
||||||
|
const radio_station_info_t *get_radio_stations(uint32_t id);
|
||||||
|
|
@ -0,0 +1,119 @@
|
||||||
|
#include <vsomeip/vsomeip.hpp>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#define RADIO_SERVICE_ID 0x1000
|
||||||
|
#define RADIO_INSTANCE_ID 1
|
||||||
|
|
||||||
|
#define RADIO_IS_PLAYING_METHOD_ID 1
|
||||||
|
#define RADIO_SET_PLAYING_METHOD_ID 2
|
||||||
|
#define RADIO_GET_VOLUME_METHOD_ID 3
|
||||||
|
#define RADIO_CHANGE_VOLUME_METHOD_ID 4
|
||||||
|
#define RADIO_SWITCH_STATION_METHOD_ID 5
|
||||||
|
|
||||||
|
#define RADIO_EVENTGROUP_ID 0x4001
|
||||||
|
#define RADIO_VOLUME_EVENT_ID 0x8000 + 1
|
||||||
|
#define RADIO_STATION_EVENT_ID 0x8000 + 2
|
||||||
|
#define RADIO_SONG_EVENT_ID 0x8000 + 3
|
||||||
|
#define RADIO_ARTIST_EVENT_ID 0x8000 + 4
|
||||||
|
|
||||||
|
#define ENGINE_SERVICE_ID 0x1001
|
||||||
|
#define ENGINE_INSTANCE_ID 1
|
||||||
|
|
||||||
|
#define ENGINE_GET_REVERSE_METHOD_ID 1
|
||||||
|
|
||||||
|
#define ENGINE_EVENTGROUP_ID 0x4002
|
||||||
|
#define ENGINE_REVERSE_EVENT_ID 0x8000 + 1
|
||||||
|
|
||||||
|
static uint32_t inline
|
||||||
|
payload_get_arg(std::shared_ptr<vsomeip::payload> its_payload)
|
||||||
|
{
|
||||||
|
vsomeip::byte_t *data = its_payload->get_data();
|
||||||
|
vsomeip::length_t l = its_payload->get_length();
|
||||||
|
|
||||||
|
if (l < 4)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return (uint32_t)data[0]<< 24 | data[1]<< 16 | data[2]<< 8 | data[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string inline
|
||||||
|
payload_get_string(std::shared_ptr<vsomeip::payload> its_payload)
|
||||||
|
{
|
||||||
|
vsomeip::byte_t *data = its_payload->get_data();
|
||||||
|
vsomeip::length_t l = its_payload->get_length();
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
for (vsomeip::length_t i=0; i<l; i++)
|
||||||
|
ss << (unsigned char)data[i];
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static std::shared_ptr<vsomeip::payload> inline
|
||||||
|
payload_with_arg(uint32_t arg)
|
||||||
|
{
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()->create_payload();
|
||||||
|
std::vector<vsomeip::byte_t> its_payload_data;
|
||||||
|
its_payload_data.push_back((arg >> 24) & 0xff);
|
||||||
|
its_payload_data.push_back((arg >> 16) & 0xff);
|
||||||
|
its_payload_data.push_back((arg >> 8) & 0xff);
|
||||||
|
its_payload_data.push_back((arg >> 0) & 0xff);
|
||||||
|
its_payload->set_data(its_payload_data);
|
||||||
|
|
||||||
|
return its_payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<vsomeip::payload> inline
|
||||||
|
payload_with_string(std::string arg)
|
||||||
|
{
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get()->create_payload();
|
||||||
|
std::vector<vsomeip::byte_t> its_payload_data;
|
||||||
|
for (vsomeip::byte_t i=0; i<arg.size(); i++) {
|
||||||
|
its_payload_data.push_back(arg[i]);
|
||||||
|
}
|
||||||
|
its_payload->set_data(its_payload_data);
|
||||||
|
|
||||||
|
return its_payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr< vsomeip::message > inline
|
||||||
|
new_request (uint32_t method, uint32_t arg)
|
||||||
|
{
|
||||||
|
std::shared_ptr< vsomeip::message > request;
|
||||||
|
request = vsomeip::runtime::get()->create_request();
|
||||||
|
request->set_service(RADIO_SERVICE_ID);
|
||||||
|
request->set_instance(RADIO_INSTANCE_ID);
|
||||||
|
request->set_method(method);
|
||||||
|
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = payload_with_arg (arg);
|
||||||
|
request->set_payload(its_payload);
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t inline
|
||||||
|
get_arg0(const std::shared_ptr<vsomeip::message> _request) {
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
|
||||||
|
|
||||||
|
return payload_get_arg(its_payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string inline
|
||||||
|
get_arg0_string(const std::shared_ptr<vsomeip::message> _request) {
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = _request->get_payload();
|
||||||
|
|
||||||
|
return payload_get_string(its_payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::shared_ptr<vsomeip::message> inline
|
||||||
|
response (const std::shared_ptr<vsomeip::message> &_request,
|
||||||
|
uint32_t arg)
|
||||||
|
{
|
||||||
|
std::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get()->create_response(_request);
|
||||||
|
std::shared_ptr<vsomeip::payload> its_payload = payload_with_arg (arg);
|
||||||
|
|
||||||
|
its_response->set_payload(its_payload);
|
||||||
|
|
||||||
|
return its_response;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
Tinyrepo
|
||||||
|
========
|
||||||
|
|
||||||
|
This folder contains some utility scripts that are used to sample images that
|
||||||
|
can be easily downloaded and used.
|
||||||
|
|
||||||
|
## Creating sample images
|
||||||
|
|
||||||
|
The sample images are a sub-set of the images one can build using the osbuild
|
||||||
|
manifest present in this repository.
|
||||||
|
|
||||||
|
The creating of the images is handled by the `build_images.sh` shell script
|
||||||
|
which simply calls sequentially different `make` commands, then compress the
|
||||||
|
resulting images and places them in a timestamped directory available to apache.
|
||||||
|
Finally, it creates a symlink between the newest folder and a `latest` folder,
|
||||||
|
thus giving a stable location where one can find the most recently built images.
|
||||||
|
|
||||||
|
|
||||||
|
## Cron job
|
||||||
|
|
||||||
|
The `build_images.sh` shell script present in this folder are ran via the
|
||||||
|
following cron job configuration:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
0 2 * * 1 sh /path/to/automotive-sig/tinyrepo/build_images.sh /path/to/clone/of/automotive-sig/osbuild-manifests/ /path/to/root/folder/in/apache
|
||||||
|
|
||||||
|
|
||||||
|
This allows to build new images weekly.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
d=`date "+%Y%m%d"`
|
||||||
|
AUTOSIGREPO=$1
|
||||||
|
HTMLROOT=$2
|
||||||
|
|
||||||
|
pushd $AUTOSIGREPO/osbuild-manifests
|
||||||
|
|
||||||
|
# Let's update the git repo
|
||||||
|
git pull --rebase
|
||||||
|
|
||||||
|
# Clean all all cached data
|
||||||
|
make clean
|
||||||
|
rm *.log || true
|
||||||
|
rm *.img || true
|
||||||
|
rm *.qcow2 || true
|
||||||
|
rm *.img.xz || true
|
||||||
|
rm *.qcow2.xz || true
|
||||||
|
dnf clean all
|
||||||
|
sudo dnf clean all
|
||||||
|
|
||||||
|
# Build all images
|
||||||
|
sudo make cs9-rpi4-neptune-ostree.aarch64.img > cs9-rpi4-neptune-ostree.aarch64.log
|
||||||
|
sudo make cs9-rpi4-neptune-regular.aarch64.img > cs9-rpi4-neptune-regular.aarch64.log
|
||||||
|
sudo make cs9-qemu-developer-regular.aarch64.qcow2 > cs9-qemu-developer-regular.aarch64.log
|
||||||
|
sudo make cs9-qemu-developer-regular.aarch64.oci.tar > cs9-qemu-developer-regular.aarch64.oci.tar.log
|
||||||
|
sudo make osbuildvm-images > osbuildvm-images.log
|
||||||
|
|
||||||
|
# Compact them
|
||||||
|
xz cs9-rpi4-neptune-ostree.aarch64.img &
|
||||||
|
xz cs9-rpi4-neptune-regular.aarch64.img &
|
||||||
|
xz cs9-qemu-developer-regular.aarch64.qcow2 &
|
||||||
|
tar cfz osbuildvm-images.tar.gz _build/osbuildvm-aarch64.* &
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Move the images to apache
|
||||||
|
mkdir -p $HTMLROOT/images/$d
|
||||||
|
cp $AUTOSIGREPO/osbuild-manifests/*.xz $HTMLROOT/images/$d/
|
||||||
|
cp $AUTOSIGREPO/osbuild-manifests/*.tar $HTMLROOT/images/$d/
|
||||||
|
cp $AUTOSIGREPO/osbuild-manifests/*.tar.gz $HTMLROOT/images/$d/
|
||||||
|
|
||||||
|
# Update the `latest` symlink
|
||||||
|
ln -nsf $d $HTMLROOT/images/latest
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
d=`date "+%Y%m%d"`
|
||||||
|
AUTOSIGREPO=$1
|
||||||
|
HTMLROOT=$2
|
||||||
|
|
||||||
|
python $AUTOSIGREPO/tinyrepo/initiate_repo.py \
|
||||||
|
$HTMLROOT/cs9-stream/ \
|
||||||
|
--pkgslist=$HTMLROOT/cs9-stream/pkgslist_$d
|
||||||
|
|
||||||
|
for arch in aarch64 x86_64
|
||||||
|
do
|
||||||
|
mkdir -p $HTMLROOT/cs9-stream/$arch/$d
|
||||||
|
pushd $HTMLROOT/cs9-stream/$arch/$d
|
||||||
|
createrepo_c ../packages/ -o . -i ../../pkgslist_$d
|
||||||
|
popd
|
||||||
|
|
||||||
|
# Update the `latest` symlink
|
||||||
|
ln -nsf $d $HTMLROOT/cs9-stream/$arch/latest
|
||||||
|
done
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
This script queries content resolver at: https://tiny.distro.builders to retrieve
|
||||||
|
a list of all the packages of interest for the automotive SIG.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
- python-requests
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
environments = [
|
||||||
|
"https://tiny.distro.builders/workload--automotive-c9s-workload-development--automotive-c9s-env-minimum--automotive-c9s-repositories--aarch64.json",
|
||||||
|
"https://tiny.distro.builders/workload--automotive-c9s-workload-minimum--automotive-c9s-env-minimum--automotive-c9s-repositories--aarch64.json",
|
||||||
|
"https://tiny.distro.builders/workload--automotive-c9s-workload-neptune--automotive-c9s-env-minimum--automotive-c9s-repositories--aarch64.json",
|
||||||
|
"https://tiny.distro.builders/workload--automotive-c9s-workload-ostree--automotive-c9s-env-minimum--automotive-c9s-repositories--aarch64.json",
|
||||||
|
"https://tiny.distro.builders/workload--automotive-c9s-workload-podman--automotive-c9s-env-minimum--automotive-c9s-repositories--aarch64.json",
|
||||||
|
]
|
||||||
|
|
||||||
|
cs_urls = [
|
||||||
|
"http://mirror.stream.centos.org/9-stream/AppStream/{arch}/os/Packages/{nvr}",
|
||||||
|
"http://mirror.stream.centos.org/9-stream/BaseOS/{arch}/os/Packages/{nvr}",
|
||||||
|
"http://mirror.stream.centos.org/9-stream/CRB/{arch}/os/Packages/{nvr}",
|
||||||
|
"https://composes.stream.centos.org/development/latest-CentOS-Stream/compose/BaseOS/{arch}/os/Packages/{nvr}",
|
||||||
|
"https://composes.stream.centos.org/development/latest-CentOS-Stream/compose/AppStream/{arch}/os/Packages/{nvr}",
|
||||||
|
"https://composes.stream.centos.org/development/latest-CentOS-Stream/compose/CRB/{arch}/os/Packages/{nvr}",
|
||||||
|
]
|
||||||
|
|
||||||
|
epoch_re = re.compile("-\d+:")
|
||||||
|
|
||||||
|
|
||||||
|
def get_packages():
|
||||||
|
""" Queries content resolver and returns a tuple of two set, the first
|
||||||
|
set contains the name of every package, the second set contains the NVR
|
||||||
|
of every package.
|
||||||
|
"""
|
||||||
|
packages_set = set()
|
||||||
|
nvr_set = set()
|
||||||
|
for env in environments:
|
||||||
|
req = requests.get(env)
|
||||||
|
if not req.ok:
|
||||||
|
print(f"Failed to retrieve info from {env}")
|
||||||
|
continue
|
||||||
|
data = req.json()
|
||||||
|
data = data["data"]
|
||||||
|
for key in ("pkg_env_ids", "pkg_added_ids"):
|
||||||
|
for pkg in data[key]:
|
||||||
|
name = pkg.rsplit("-", 2)[0]
|
||||||
|
# Drop the architecture
|
||||||
|
nvr = pkg.rsplit(".", 1)[0]
|
||||||
|
# Drop epoch if there is one
|
||||||
|
if len(epoch_re.findall(nvr)) == 1:
|
||||||
|
for mat in epoch_re.findall(nvr):
|
||||||
|
nvr = nvr.replace(mat, "-")
|
||||||
|
elif len(epoch_re.findall(nvr)) > 1:
|
||||||
|
print("More than one -\d: matched in {nvr}")
|
||||||
|
packages_set.add(name)
|
||||||
|
nvr_set.add(nvr)
|
||||||
|
|
||||||
|
return (packages_set, nvr_set)
|
||||||
|
|
||||||
|
|
||||||
|
def download_nvrs(folder, nvrs):
|
||||||
|
""" Queries the CentOS-Stream mirror and download the package specified by
|
||||||
|
the given NVR.
|
||||||
|
"""
|
||||||
|
notfound = 0
|
||||||
|
out_files = []
|
||||||
|
for nvr in sorted(nvrs):
|
||||||
|
for arch in ("x86_64", "aarch64"):
|
||||||
|
out_filename = f"{nvr}.{arch}.rpm"
|
||||||
|
output_folder = os.path.join(folder, arch, "packages")
|
||||||
|
out_path = os.path.join(output_folder, out_filename)
|
||||||
|
|
||||||
|
if not os.path.exists(output_folder):
|
||||||
|
os.makedirs(output_folder)
|
||||||
|
|
||||||
|
if os.path.exists(out_path):
|
||||||
|
out_files.append(out_filename)
|
||||||
|
continue
|
||||||
|
|
||||||
|
found = False
|
||||||
|
for url in cs_urls:
|
||||||
|
nurl = f"{url}.{arch}.rpm".format(arch=arch, nvr=nvr)
|
||||||
|
req = requests.head(nurl)
|
||||||
|
# print(req.status_code, url)
|
||||||
|
if req.ok:
|
||||||
|
found = True
|
||||||
|
out_files.append(out_filename)
|
||||||
|
req = requests.get(nurl)
|
||||||
|
with open(out_path, "wb") as stream:
|
||||||
|
stream.write(req.content)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# print(req.status_code, nurl)
|
||||||
|
# Check if it's a noarch RPM
|
||||||
|
nurl = f"{url}.noarch.rpm".format(arch=arch, nvr=nvr)
|
||||||
|
req = requests.head(nurl)
|
||||||
|
if req.ok:
|
||||||
|
found = True
|
||||||
|
out_files.append(f"{nvr}.noarch.rpm")
|
||||||
|
req = requests.get(nurl)
|
||||||
|
with open(out_path, "wb") as stream:
|
||||||
|
stream.write(req.content)
|
||||||
|
break
|
||||||
|
# else:
|
||||||
|
# print(req.status_code, nurl)
|
||||||
|
if not found:
|
||||||
|
print(f"Package {nvr}.{arch} not found on the mirrors")
|
||||||
|
notfound += 1
|
||||||
|
|
||||||
|
print(f"{notfound} packages not found on the mirrors")
|
||||||
|
return out_files
|
||||||
|
|
||||||
|
|
||||||
|
def parse_arguments(args):
|
||||||
|
"""Parse the CLI arguments and return the corresponding argparse object.
|
||||||
|
"""
|
||||||
|
parser = argparse.ArgumentParser(description="Instantiate george")
|
||||||
|
parser.add_argument("folder", nargs="?", default=".",
|
||||||
|
help="Folder in which to put the downloaded RPMs")
|
||||||
|
parser.add_argument("--pkgslist",
|
||||||
|
help="Name of the file in which to output the list of all the RPMs found")
|
||||||
|
|
||||||
|
return parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = parse_arguments(sys.argv[1:])
|
||||||
|
pkgs, nvrs = get_packages()
|
||||||
|
# print("-", "\n- ".join(sorted(pkgs)))
|
||||||
|
print(len(pkgs), "packages found")
|
||||||
|
print("Corresponding to", len(nvrs), "nvr")
|
||||||
|
out_files = download_nvrs(args.folder, nvrs)
|
||||||
|
if args.pkgslist:
|
||||||
|
with open(args.pkgslist, "w") as stream:
|
||||||
|
stream.write("\n".join(out_files))
|
||||||
Loading…
Reference in New Issue