Merge branch 'no-root-build' into 'master'

Merge no-root-build branch into master

Closes #22

See merge request archlinux/archlinux-docker!38
This commit is contained in:
hashworks 2020-08-28 23:21:02 +00:00
commit a0d65ca9a9
12 changed files with 213 additions and 64 deletions

3
.dockerignore Normal file
View File

@ -0,0 +1,3 @@
*
!archlinux.tar
!archlinux.tar.xz

View File

@ -1,12 +0,0 @@
name: Github-Actions
on: [push, pull_request]
jobs:
ci-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: make ci-test
run: make ci-test

1
.gitignore vendored
View File

@ -2,4 +2,5 @@
*.orig
/.idea
/archlinux.tar
/archlinux.tar.xz
rootfs/etc/pacman.conf

50
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,50 @@
stages:
- rootfs
- docker
- test
roofs:
stage: rootfs
image: archlinux:latest
script:
- pacman -Syu --noconfirm make devtools fakechroot fakeroot
- make compress-rootfs
artifacts:
paths:
- archlinux.tar.xz
expire_in: 10m
docker:
stage: docker
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- test -f archlinux.tar.xz
# kaniko can't process .tar.xz archives
# https://github.com/GoogleContainerTools/kaniko/issues/1107
- unxz archlinux.tar.xz
- test -f archlinux.tar
- sed -i 's/archlinux\.tar\.xz/archlinux\.tar/g' Dockerfile
- echo "Building ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}"
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- /kaniko/executor
--whitelist-var-run="false"
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
test:
stage: test
image: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_SLUG}
needs:
- job: docker
artifacts: false
script:
- pacman -Sy
- pacman -Qqk
- pacman -Syu --noconfirm docker grep
- docker -v
- id -u http
- locale | grep -q UTF-8

View File

@ -1,9 +0,0 @@
sudo: required
language: bash
services:
- docker
script:
- make ci-test

View File

@ -1,4 +1,15 @@
FROM scratch
ADD archlinux.tar /
ADD archlinux.tar.xz /
# manually run all alpm hooks that can't be run inside the fakechroot
RUN ldconfig && update-ca-trust && locale-gen
RUN sh -c 'ls usr/lib/sysusers.d/*.conf | /usr/share/libalpm/scripts/systemd-hook sysusers '
# update /etc/os-release
RUN ln -s /usr/lib/os-release /etc/os-release
# initialize the archlinux keyring, but discard any private key that may be shipped.
RUN pacman-key --init && pacman-key --populate archlinux && rm -rf etc/pacman.d/gnupg/{openpgp-revocs.d/,private-keys-v1.d/,pubring.gpg~,gnupg.S.}*
ENV LANG=en_US.UTF-8
CMD ["/usr/bin/bash"]

View File

@ -1,38 +1,52 @@
DOCKER_USER:=pierres
DOCKER_ORGANIZATION=archlinux
DOCKER_IMAGE:=base
BUILDDIR=build
PWD=$(shell pwd)
rootfs:
$(eval TMPDIR := $(shell mktemp -d))
XZ_THREADS ?= 0
hooks:
mkdir -p alpm-hooks/usr/share/libalpm/hooks
find /usr/share/libalpm/hooks -exec ln -sf /dev/null $(PWD)/alpm-hooks{} \;
rootfs: hooks
mkdir -vp $(BUILDDIR)/var/lib/pacman/
cp /usr/share/devtools/pacman-extra.conf rootfs/etc/pacman.conf
cat pacman-conf.d-noextract.conf >> rootfs/etc/pacman.conf
env -i pacstrap -C rootfs/etc/pacman.conf -c -d -G -M $(TMPDIR) $(shell cat packages)
cp --recursive --preserve=timestamps --backup --suffix=.pacnew rootfs/* $(TMPDIR)/
arch-chroot $(TMPDIR) locale-gen
arch-chroot $(TMPDIR) pacman-key --init
arch-chroot $(TMPDIR) pacman-key --populate archlinux
tar --numeric-owner --xattrs --acls --exclude-from=exclude -C $(TMPDIR) -c . -f archlinux.tar
rm -rf $(TMPDIR)
fakechroot -- fakeroot -- pacman -Sy -r $(BUILDDIR) \
--noconfirm --dbpath $(PWD)/$(BUILDDIR)/var/lib/pacman \
--config rootfs/etc/pacman.conf \
--noscriptlet \
--hookdir $(PWD)/alpm-hooks/usr/share/libalpm/hooks/ $(shell cat packages)
cp --recursive --preserve=timestamps --backup --suffix=.pacnew rootfs/* $(BUILDDIR)/
# remove passwordless login for root (see CVE-2019-5021 for reference)
sed -i -e 's/^root::/root:!:/' "$(BUILDDIR)/etc/shadow"
docker-image: rootfs
# fakeroot to map the gid/uid of the builder process to root
# fixes #22
fakeroot -- tar --numeric-owner --xattrs --acls --exclude-from=exclude -C $(BUILDDIR) -c . -f archlinux.tar
rm -rf $(BUILDDIR) alpm-hooks
archlinux.tar: rootfs
compress-rootfs: archlinux.tar
xz -9 -T"$(XZ_THREADS)" -f archlinux.tar
docker-image: compress-rootfs
docker build -t $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) .
docker-image-test: docker-image
# FIXME: /etc/mtab is hidden by docker so the stricter -Qkk fails
docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) sh -c "/usr/bin/pacman -Sy && /usr/bin/pacman -Qqk"
docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) sh -c "/usr/bin/pacman -Syu --noconfirm docker && docker -v"
# Ensure that the image does not include a private key
docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) sh -c "/usr/bin/pacman -Syu --noconfirm docker && docker -v" # Ensure that the image does not include a private key
! docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) pacman-key --lsign-key pierre@archlinux.de
docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) sh -c "/usr/bin/id -u http"
docker run --rm $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) sh -c "/usr/bin/pacman -Syu --noconfirm grep && locale | grep -q UTF-8"
ci-test:
docker run --rm --privileged --tmpfs=/tmp:exec --tmpfs=/run/shm -v /run/docker.sock:/run/docker.sock \
-v $(PWD):/app -w /app $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE) \
sh -c 'pacman -Syu --noconfirm make devtools docker && make docker-image-test'
docker-push:
docker login -u $(DOCKER_USER)
docker push $(DOCKER_ORGANIZATION)/$(DOCKER_IMAGE)
.PHONY: rootfs docker-image docker-image-test ci-test docker-push
.PHONY: rootfs docker-image docker-image-test docker-push

View File

@ -5,6 +5,8 @@ Install the following Arch Linux packages:
* make
* devtools
* docker
* fakechroot
* fakeroot
## Usage
Run `make docker-image` as root to build the base image.
## Purpose

29
exclude
View File

@ -1,13 +1,16 @@
.dockerenv
.dockerinit
etc/hostname
etc/machine-id
etc/pacman.d/gnupg/openpgp-revocs.d/*
etc/pacman.d/gnupg/private-keys-v1.d/*
etc/pacman.d/gnupg/pubring.gpg~
etc/pacman.d/gnupg/S.*
root/*
tmp/*
var/cache/pacman/pkg/*
var/lib/pacman/sync/*
var/tmp/*
./.dockerenv
./.dockerinit
./sys
./proc
./dev
./etc/hostname
./etc/machine-id
./etc/pacman.d/gnupg/openpgp-revocs.d/*
./etc/pacman.d/gnupg/private-keys-v1.d/*
./etc/pacman.d/gnupg/pubring.gpg~
./etc/pacman.d/gnupg/S.*
./root/*
./tmp/*
./var/cache/pacman/pkg/*
./var/lib/pacman/sync/*
./var/tmp/*

View File

@ -2,3 +2,9 @@ sed
gzip
pacman
systemd
gawk
file
grep
tar
procps-ng
licenses

91
pacman.conf Normal file
View File

@ -0,0 +1,91 @@
#
# /etc/pacman.conf
#
# See the pacman.conf(5) manpage for option and repository directives
#
# GENERAL OPTIONS
#
[options]
# The following paths are commented out with their default values listed.
# If you wish to use different paths, uncomment and update the paths.
#RootDir = /
#DBPath = /var/lib/pacman/
#CacheDir = /var/cache/pacman/pkg/
#LogFile = /var/log/pacman.log
#GPGDir = /etc/pacman.d/gnupg/
#HookDir = /etc/pacman.d/hooks/
#HoldPkg = pacman glibc
#XferCommand = /usr/bin/curl -C - -f %u > %o
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
#UseDelta = 0.7
Architecture = auto
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
#IgnorePkg =
#IgnoreGroup =
#NoUpgrade =
#NoExtract =
# Misc options
#UseSyslog
#Color
#TotalDownload
CheckSpace
#VerbosePkgLists
# By default, pacman accepts packages signed by keys that its local keyring
# trusts (see pacman-key and its man page), as well as unsigned packages.
SigLevel = Required DatabaseOptional
LocalFileSigLevel = Optional
#RemoteFileSigLevel = Required
# NOTE: You must run `pacman-key --init` before first using pacman; the local
# keyring can then be populated with the keys of all official Arch Linux
# packagers with `pacman-key --populate archlinux`.
#
# REPOSITORIES
# - can be defined here or included from another file
# - pacman will search repositories in the order defined here
# - local/custom mirrors can be added here or in separate files
# - repositories listed first will take precedence when packages
# have identical names, regardless of version number
# - URLs will have $repo replaced by the name of the current repo
# - URLs will have $arch replaced by the name of the architecture
#
# Repository entries are of the format:
# [repo-name]
# Server = ServerName
# Include = IncludePath
#
# The header [repo-name] is crucial - it must be present and
# uncommented to enable the repo.
#
# The testing repositories are disabled by default. To enable, uncomment the
# repo name header and Include lines. You can add preferred servers immediately
# after the header, and they will be used before the default mirrors.
[core]
Include = rootfs/etc/pacman.d/mirrorlist
[extra]
Include = rootfs/etc/pacman.d/mirrorlist
[community]
Include = rootfs/etc/pacman.d/mirrorlist
# If you want to run 32 bit applications on your x86_64 system,
# enable the multilib repositories as required here.
#[multilib]
#Include = /etc/pacman.d/mirrorlist
#
# An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories.
#[custom]
#SigLevel = Optional TrustAll
#Server = file:///home/custompkgs

View File

@ -1,11 +0,0 @@
[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = *
[Action]
Description = Cleaning up package cache...
Depends = coreutils
When = PostTransaction
Exec = /usr/bin/find /var/cache/pacman/pkg/ -type f -delete