├── .gitignore ├── .dockerignore ├── Dockerfile ├── unit.d ├── bashrc │ ├── conf │ └── overlay │ │ └── etc │ │ └── skel │ │ └── .bashrc └── apt │ ├── overlay │ ├── etc │ │ └── apt │ │ │ └── apt.conf.d │ │ │ ├── 05recommends │ │ │ ├── docker-no-languages │ │ │ ├── docker-gzip-indexes │ │ │ └── docker-autoremove-suggests │ └── usr │ │ └── local │ │ └── sbin │ │ └── apt-clean │ └── conf ├── plan ├── base └── required ├── contrib ├── generate-aci-manifest └── generate-changelog ├── docs ├── build-docker.md └── release.md ├── CHANGELOG.md ├── README.md └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | releases 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !build/rootfs.tar.gz 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | ADD build/rootfs.tar.gz / 3 | -------------------------------------------------------------------------------- /unit.d/bashrc/conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | cp /etc/skel/.bashrc /root/ 4 | -------------------------------------------------------------------------------- /plan/base: -------------------------------------------------------------------------------- 1 | apt 2 | gpgv /* needed to verify apt signatures */ 3 | mawk /* needed to provide awk to base-files */ 4 | -------------------------------------------------------------------------------- /unit.d/apt/overlay/etc/apt/apt.conf.d/05recommends: -------------------------------------------------------------------------------- 1 | # Don't install recommends by default 2 | 3 | APT::Install-Recommends "false"; 4 | -------------------------------------------------------------------------------- /unit.d/apt/overlay/etc/apt/apt.conf.d/docker-no-languages: -------------------------------------------------------------------------------- 1 | # In Docker, we don't often need the "Translations" files, so we're just 2 | # wasting time and space by downloading them, and this inhibits that. For 3 | # users that do need them, it's a simple matter to delete this file and 4 | # "apt-get update". :) 5 | 6 | Acquire::Languages "none"; 7 | -------------------------------------------------------------------------------- /unit.d/apt/overlay/etc/apt/apt.conf.d/docker-gzip-indexes: -------------------------------------------------------------------------------- 1 | # Since Docker users using "RUN apt-get update && apt-get install -y ..." in 2 | # their Dockerfiles don't go delete the lists files afterwards, we want them 3 | # to be as small as possible on-disk, so we explicitly request "gz" versions 4 | # and tell Apt to keep them gzipped on-disk. 5 | 6 | # For comparison, an "apt-get update" layer without this on a pristine 7 | # "debian:wheezy" base image was "29.88 MB", where with this it was only 8 | # "8.273 MB". 9 | 10 | Acquire::GzipIndexes "true"; 11 | Acquire::CompressionTypes::Order:: "gz"; 12 | -------------------------------------------------------------------------------- /contrib/generate-aci-manifest: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | usage() { 4 | echo "Syntax: $0 name version arch" 5 | echo "Generate manifest to be included in aci" 6 | exit 1 7 | } 8 | 9 | [[ "$#" = "3" ]] || usage 10 | 11 | name=$1 12 | version=$2 13 | arch=$3 14 | 15 | cat< \ 6 | # && \ 7 | # && apt-get purge -y --auto-remove 8 | 9 | # By default, APT will actually _keep_ packages installed via Recommends or 10 | # Depends if another package Suggests them, even and including if the package 11 | # that originally caused them to be installed is removed. Setting this to 12 | # "false" ensures that APT is appropriately aggressive about removing the 13 | # packages it added. 14 | 15 | # https://aptitude.alioth.debian.org/doc/en/ch02s05s05.html#configApt-AutoRemove-SuggestsImportant 16 | 17 | Apt::AutoRemove::SuggestsImportant "false"; 18 | -------------------------------------------------------------------------------- /unit.d/bashrc/overlay/etc/skel/.bashrc: -------------------------------------------------------------------------------- 1 | # If not running interactively, don't do anything 2 | [ -z "$PS1" ] && return 3 | 4 | HISTSIZE=1000 5 | HISTFILESIZE=2000 6 | HISTCONTROL=ignoredups:ignorespace 7 | shopt -s histappend 8 | 9 | # max 2 level - best compromise of readability and usefulness 10 | function promptpath() { 11 | path="${PWD/#$HOME/\~}" 12 | if [ $(echo "${path:1}" | tr -d -c / | wc -c) -gt 1 ]; then 13 | path=$(echo "$path" | rev | cut -d/ -f-2 | rev) 14 | fi 15 | echo "$path" 16 | } 17 | 18 | if [ "$TERM" != "dumb" ]; then 19 | eval "`dircolors -b`" 20 | alias ls='ls --color=auto --group-directories-first' 21 | alias grep='grep --color=auto' 22 | PS1='\[\033[01;33m\]\u@\h \[\033[01;34m\]$(promptpath)\[\033[00m\]\$ ' 23 | else 24 | alias ls="ls -F --group-directories-first" 25 | PS1='\u@\h $(promptpath)\$ ' 26 | fi 27 | -------------------------------------------------------------------------------- /unit.d/apt/conf: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | CODENAME=$(cat /etc/debian_codename) 4 | 5 | cat >/etc/apt/sources.list.d/sources.list</etc/apt/sources.list.d/security.sources.list< /usr/sbin/policy-rc.d 21 | chmod +x /usr/sbin/policy-rc.d 22 | 23 | dpkg-divert --local --rename --add /sbin/initctl 24 | ln -sf /bin/true /sbin/initctl 25 | 26 | # aggresively clean apt related files 27 | /usr/local/sbin/apt-clean --aggressive 28 | 29 | -------------------------------------------------------------------------------- /docs/build-docker.md: -------------------------------------------------------------------------------- 1 | # build docker image from rootfs (to be done automatically via ci) 2 | 3 | ## import release signing key if needed 4 | 5 | ``` 6 | GPGKEY=A16EB94D 7 | if ! gpg --list-keys $GPGKEY 2>&1 >/dev/null; then 8 | gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 0x$GPGKEY 9 | fi 10 | ``` 11 | 12 | ## download and verify latest release 13 | 14 | ``` 15 | VERSION=$(git tag -l | head -1) 16 | GITHUB=https://github.com/tklx/base/releases/download/$VERSION 17 | mkdir -p releases/$VERSION && cd releases/$VERSION 18 | [ -e rootfs.tar.xz ] || wget $GITHUB/rootfs.tar.xz 19 | [ -e rootfs.tar.xz.asc ] || wget $GITHUB/rootfs.tar.xz.asc 20 | gpg --verify rootfs.tar.xz.asc 21 | ``` 22 | 23 | ## build docker image and push to docker hub 24 | 25 | ``` 26 | echo -e 'FROM scratch\nADD rootfs.tar.xz /' > Dockerfile 27 | echo -e '*\n!rootfs.tar.xz' > .dockerignore 28 | docker build -t tklx/base:$VERSION . 29 | docker run --rm tklx/base:$VERSION cat /etc/debian_version 30 | docker push tklx/base:$VERSION 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /plan/required: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | This file should only contain packages flagged as Essential and any 4 | extra dependencies they require. 5 | 6 | We resolve the dependencies of the included packages recursively to 7 | produce a list of packages which are passed to debootstrap to produce a 8 | bootstrap filesystem capable of installing additional packages via 9 | apt-get. 10 | 11 | Notes: 12 | 13 | * Do not rely on bringing in essential packages through dependencies. 14 | 15 | * Avoid including "essential" packages which are not really essential 16 | for satisfying our goal. 17 | 18 | */ 19 | 20 | base-files 21 | base-passwd 22 | bash 23 | bsdutils 24 | coreutils 25 | debianutils 26 | dash 27 | diffutils 28 | dpkg 29 | e2fsprogs 30 | findutils 31 | grep 32 | gzip 33 | hostname 34 | login 35 | mount 36 | perl-base 37 | tar 38 | util-linux 39 | sed 40 | libc-bin 41 | 42 | /* non-essential packages needed for bootstrapping */ 43 | mawk /* needed to provide awk to base-files */ 44 | sysv-rc /* needed by dpkg for update-rc.d */ 45 | -------------------------------------------------------------------------------- /unit.d/apt/overlay/usr/local/sbin/apt-clean: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | usage() { 4 | cat<&2; exit 1; } 4 | 5 | usage() { 6 | cat<\n" 48 | echo -e "#### New features\n" 49 | echo -e "#### Bugfixes\n" 50 | echo "${gitlog}" | grep fix && echo || true 51 | echo -e "#### Other changes\n" 52 | echo "${gitlog}" | grep -v fix && echo || true 53 | if [ "$package_list_diff" ]; then 54 | echo -e "#### Package updates\n" 55 | echo -e "\`\`\`\n${package_list_diff}\n\`\`\`\n" 56 | fi 57 | [ -e CHANGELOG.md ] && cat CHANGELOG.md 58 | 59 | exit 0 60 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | ## build and test 2 | 3 | ``` 4 | export RELEASE=debian/jessie 5 | builder/run chanko-upgrade 6 | builder/run make clean 7 | builder/run make all 8 | 9 | docker build -t tklx/base:latest . 10 | docker run -it --rm tklx/base:latest /bin/bash 11 | ``` 12 | 13 | ## update changelog, readme and create signed tag 14 | 15 | ``` 16 | contrib/generate-changelog > CHANGELOG.tmp 17 | mv CHANGELOG.tmp CHANGELOG.md 18 | $EDITOR CHANGELOG.md # verify version is correct and tweak 19 | VERSION=$(head -1 CHANGELOG.md | awk '{print $2}') 20 | OLD_VERSION=$(git tag -l |head -1) 21 | sed -i "s/$OLD_VERSION/$VERSION/g" README.md 22 | git add CHANGELOG.md README.md 23 | git commit -m "updated for $VERSION release" 24 | git tag -s -m "$VERSION release" $VERSION 25 | ``` 26 | 27 | ## generate release files 28 | 29 | ``` 30 | mkdir releases/$VERSION 31 | cp build/package.list releases/$VERSION/ 32 | cp build/rootfs.tar.xz releases/$VERSION/ 33 | gpg -u A16EB94D --armor --detach-sig releases/$VERSION/rootfs.tar.xz 34 | 35 | ARCH=$(dpkg --print-architecture) 36 | NAME=base-$VERSION-linux-$ARCH.aci 37 | contrib/generate-aci-manifest tklx.org/base $VERSION $ARCH > build/manifest 38 | cat build/manifest | python -m json.tool >/dev/null 39 | sudo chown root:root build/manifest 40 | sudo tar -C build --numeric-owner -Jcf releases/$VERSION/$NAME manifest rootfs 41 | sudo rm build/manifest 42 | sudo chown $USER:$USER releases/$VERSION/$NAME 43 | gpg -u A16EB94D --armor --detach-sig releases/$VERSION/$NAME 44 | ``` 45 | 46 | ## push to github 47 | 48 | ``` 49 | git push github 50 | git push github --tags 51 | ``` 52 | 53 | ## create new github release 54 | 55 | - https://github.com/tklx/base/releases/new 56 | - select $VERSION tag 57 | - set description as $VERSION 58 | - copy/paste entry from CHANGELOG.md and tweak 59 | - add release files from releases/$VERSION/ 60 | - mark pre-release if relevant 61 | - publish 62 | 63 | ## update docker hub 64 | 65 | ``` 66 | docker tag tklx/base:latest tklx/base:$VERSION 67 | docker push tklx/base:$VERSION 68 | ``` 69 | 70 | - https://hub.docker.com/r/tklx/base/ 71 | - update description based on README.md 72 | 73 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.1.1 2 | 3 | Package updates to Debian stable (Jessie) builds. 4 | 5 | Addition of base/builder - A build environment for building tklx/base from 6 | tklx/base. See the README for details. 7 | 8 | #### Bugfixes 9 | 10 | - unit.d/bashrc: escape tilde used for HOME representation. 11 | 12 | #### Other changes 13 | 14 | - codename: create and use /etc/debian_codename to determine version. 15 | - makefile: require RELEASE be set in environment. 16 | - makefile: correctly determine paths for debootstrap. 17 | - docker: added docker files for building image from build/rootfs.tar.gz 18 | - builder: tklx/base build environment supporting jessie, stretch, sid. 19 | 20 | #### Package updates 21 | 22 | ``` 23 | gnupg 1.4.18-7+deb8u1 | gnupg 1.4.18-7+deb8u2 24 | gpgv 1.4.18-7+deb8u1 | gpgv 1.4.18-7+deb8u2 25 | libgcrypt20 1.6.3-2+deb8u1 | libgcrypt20 1.6.3-2+deb8u2 26 | perl-base 5.20.2-3+deb8u5 | perl-base 5.20.2-3+deb8u6 27 | ``` 28 | 29 | ## 0.1.0 30 | 31 | Initial development release based on Debian stable (Jessie). 32 | 33 | #### Notes 34 | 35 | - Based off turnkeylinux/bootstrap and turnkeylinux/fab/share. 36 | - Imported files refactored, rewritten and tweaked (see git log). 37 | 38 | - APT configurations 39 | 40 | - Don't install recommends by default. 41 | - Don't download translation files. 42 | - Explicitly request gzipped indexes, keep compressed on-disk. 43 | - Ensure APT is aggressive about removing packages it added. 44 | - Prevent initscripts from running during install/update. 45 | - Use httpredir.debian.org for fastest geo-location updates. 46 | - Only main repo enabled (contrib, non-free commented out). 47 | 48 | - APT clean convenience script: apt-clean [--aggressive] 49 | 50 | - Cleans all APT related cached files. 51 | - Supports optional --aggressive option to clean docs, locales, 52 | manpages, info, groff, linda and lintian. Note that copyright 53 | files are *not* deleted. 54 | - Locale to exclude from aggressive clean is determined from 55 | environment variable LANG. If not set, ``en_*`` is assumed. 56 | 57 | - Bashrc 58 | 59 | - Set PS1 (promptpath) to max 2 levels (readability, usefulness). 60 | - Enable color support when possible. 61 | 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tklx/base 2 | 3 | A super slim root filesystem specifically designed to be used as a base 4 | image for application [container][container] images. 5 | 6 | Based on [Debian GNU/Linux][debian], the ``rootfs.tar.xz`` weighs in at 7 | only 12MB, and has access to largest GNU/Linux software repository with 8 | over [56,800 packages][debian_packages]. 9 | 10 | ## Features 11 | 12 | - Based on Debian GNU/Linux ([why debian?][why-debian]). 13 | - Runtime agnostic (use with [Docker][docker], [CoreOS rkt][rkt], etc.). 14 | - Built from scratch specifically for container usage. 15 | - Smallest Debian based image as far as we know. 16 | - Comfortable [interactive][bashrc] terminal (colorized, promptpath). 17 | - Convenience [apt-clean][apt-clean] script to clean cache and optionally docs/locales. 18 | 19 | ## Usage (Docker) 20 | 21 | ```console 22 | docker pull tklx/base:0.1.1 23 | docker run -it tklx/base:0.1.1 /bin/bash 24 | ``` 25 | 26 | ```dockerfile 27 | FROM tklx/base:0.1.1 28 | RUN apt-get update && apt-get -y install PACKAGES && apt-clean --aggressive 29 | ENTRYPOINT ["something"] 30 | ``` 31 | 32 | ## Usage (CoreOS rkt) 33 | 34 | ```console 35 | rkt trust --prefix=tklx.org/base 36 | rkt fetch tklx.org/base:0.1.1 37 | rkt run tklx.org/base:0.1.1 --interactive --exec /bin/bash 38 | ``` 39 | 40 | ```console 41 | acbuild begin 42 | acbuild set-name example.com/test 43 | acbuild dep add tklx.org/base:0.1.1 44 | acbuild run apt-get update && apt-get -y install PACKAGES && apt-clean --aggressive 45 | acbuild set-exec something 46 | acbuild write test-latest-linux-amd64.aci 47 | acbuild end 48 | ``` 49 | 50 | ## Status 51 | 52 | Currently on major version zero (0.y.z). Per [Semantic Versioning][semver], 53 | major version zero is for initial development, and should not be considered 54 | stable. Anything may change at any time. 55 | 56 | Release files are available [here][releases]. 57 | 58 | ## Versioning 59 | 60 | Releases are based on [Semantic Versioning][semver], and use the format 61 | of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented 62 | based on the following: 63 | 64 | - ``MAJOR``: incompatible and/or major changes, upgraded OS release 65 | - ``MINOR``: backwards-compatible new features and functionality 66 | - ``PATCH``: backwards-compatible bugfixes and package updates 67 | 68 | ## Issue Tracker 69 | 70 | TKLX uses a central [issue tracker][tracker] on GitHub for reporting and 71 | tracking of bugs, issues and feature requests. 72 | 73 | ## About 74 | 75 | In case you're interested, TKLX is pronounced _/tickle-ex/_. 76 | 77 | TKLX is a project by [TurnKey GNU/Linux][turnkeylinux]. TurnKey 78 | GNU/Linux is a Debian based library of system images that pre-integrates 79 | and polishes the best free software components into ready-to-use 80 | solutions. 81 | 82 | TurnKey was started in 2008 by [Alon Swartz][alonswartz] and [Liraz 83 | Siri][lirazsiri] who were inspired by a belief in the power of free 84 | software, like science, to promote the progress of a free & humane 85 | society. 86 | 87 | [container]: https://en.wikipedia.org/wiki/Operating-system-level_virtualization 88 | [docker]: https://www.docker.com/ 89 | [appc]: https://github.com/appc/spec/ 90 | [rkt]: https://coreos.com/rkt/ 91 | [debian]: http://www.debian.org 92 | [debian_packages]: https://packages.debian.org/stable/allpackages?format=txt.gz 93 | [why-debian]: https://www.turnkeylinux.org/faq/why-debian 94 | [bashrc]: https://github.com/tklx/base/blob/master/unit.d/bashrc/overlay/etc/skel/.bashrc 95 | [apt-clean]: https://github.com/tklx/base/blob/master/unit.d/apt/overlay/usr/local/sbin/apt-clean 96 | [semver]: http://semver.org/ 97 | [releases]: https://github.com/tklx/base/releases 98 | [tracker]: https://github.com/tklx/tracker/issues 99 | [turnkeylinux]: https://www.turnkeylinux.org 100 | [alonswartz]: http://www.alonswartz.org 101 | [lirazsiri]: http://www.liraz.org 102 | 103 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # Copyright (c) TurnKey GNU/Linux - http://www.turnkeylinux.org 3 | # 4 | # This file is part of Fab 5 | # 6 | # Fab is free software; you can redistribute it and/or modify it 7 | # under the terms of the GNU Affero General Public License as published by the 8 | # Free Software Foundation; either version 3 of the License, or (at your 9 | # option) any later version. 10 | 11 | ifndef FAB_PATH 12 | $(error FAB_PATH not defined - needed for default paths) 13 | endif 14 | 15 | ifndef RELEASE 16 | $(error RELEASE not defined - needed for default paths) 17 | endif 18 | 19 | CODENAME = $(shell basename $(RELEASE)) 20 | 21 | POOL ?= $(FAB_PATH)/pools/$(CODENAME) 22 | export FAB_POOL_PATH = $(POOL) 23 | 24 | FAB_ARCH = $(shell dpkg --print-architecture) 25 | DEBOOTSTRAP_SUITE ?= generic 26 | 27 | # build output path 28 | O ?= build 29 | 30 | default: $O/rootfs.tar.gz 31 | 32 | all: default $O/rootfs.tar.xz $O/package.list 33 | 34 | help: 35 | @echo '=== Configurable variables' 36 | @echo 'Resolution order:' 37 | @echo '1) command line (highest precedence)' 38 | @echo '2) environment variable' 39 | @echo '3) built-in default (lowest precedence)' 40 | @echo 41 | @echo '# Mandatory configuration variables' 42 | @echo ' FAB_PATH $(value FAB_PATH)' 43 | @echo 44 | @echo '# Build context variables' 45 | @echo ' RELEASE $(value RELEASE)' 46 | @echo ' POOL $(value POOL)' 47 | @echo ' FAB_ARCH $(value FAB_ARCH)' 48 | @echo ' DEBOOTSTRAP_SUITE $(value DEBOOTSTRAP_SUITE)' 49 | @echo 50 | @echo '# Product output variables' 51 | @echo ' O $(value O)' 52 | @echo 53 | @echo '=== Usage' 54 | @echo 'Build a target' 55 | @echo '$$ make [target] [O=path/to/build/dir]' 56 | @echo 57 | @echo ' all' 58 | @echo ' clean' 59 | @echo ' $(value O)/required.spec' 60 | @echo ' $(value O)/required.list' 61 | @echo ' $(value O)/base.spec' 62 | @echo ' $(value O)/base.list' 63 | @echo ' $(value O)/package.list' 64 | @echo ' $(value O)/repo' 65 | @echo ' $(value O)/rootfs' 66 | @echo ' $(value O)/rootfs.tar.xz' 67 | @echo ' $(value O)/rootfs.tar.gz (default)' 68 | 69 | clean: 70 | -rm -rf $O/*.spec $O/*.list $O/repo $O/rootfs $O/rootfs.tar.* 71 | 72 | $O/required.spec: plan/required 73 | fab-plan-resolve --output=$O/required.spec plan/required 74 | 75 | $O/base.spec: $O/required.spec plan/base 76 | fab-plan-resolve --output=$O/base.spec plan/base 77 | 78 | $O/required.list: $O/required.spec 79 | awk '{print $$1}' $O/required.spec |sort > $O/required.list 80 | 81 | $O/base.list: $O/required.list $O/base.spec 82 | awk '{print $$1}' $O/base.spec |sort > $O/base.list.tmp 83 | sdiff --suppress-common-lines $O/base.list.tmp $O/required.list | \ 84 | awk '{print $$1}' | grep -v '>' > $O/base.list 85 | rm $O/base.list.tmp 86 | 87 | $O/package.list: $O/required.list $O/base.list 88 | cat $O/required.list $O/base.list |sort |sed "s/=/ /" > $O/package.list 89 | 90 | $O/repo: $O/required.spec $O/base.spec 91 | mkdir -p $O/repo/pool/main 92 | cat $O/required.spec $O/base.spec | \ 93 | POOL_DIR=$(POOL) pool-get $O/repo/pool/main -s -t --input - 94 | repo-index $O/repo $(DEBOOTSTRAP_SUITE) main $(FAB_ARCH) 95 | repo-release `pwd`/$O/repo $(DEBOOTSTRAP_SUITE) 96 | 97 | $O/rootfs: $O/repo $O/required.list $O/base.list 98 | REQUIRED_PACKAGES="$(shell cat $O/required.list |sed 's/=.*//')" \ 99 | BASE_PACKAGES="$(shell cat $O/base.list |sed 's/=.*//')" \ 100 | debootstrap --arch $(FAB_ARCH) $(DEBOOTSTRAP_SUITE) \ 101 | $(shell realpath $O)/rootfs \ 102 | file://$(shell realpath $O)/repo 103 | 104 | mkdir -p $O/rootfs/dev/pts 105 | echo $(CODENAME) > $O/rootfs/etc/debian_codename 106 | $(foreach u,$(wildcard unit.d/*), \ 107 | [ -d $(u)/overlay ] && fab-apply-overlay $(u)/overlay $O/rootfs; \ 108 | [ -x $(u)/conf ] && fab-chroot $O/rootfs --script $(u)/conf; \ 109 | ) 110 | 111 | rm -f $O/rootfs/etc/hostname 112 | rm -f $O/rootfs/etc/resolv.conf 113 | rm -f $O/rootfs/etc/apt/sources.list 114 | rm -f $O/rootfs/var/log/bootstrap.log 115 | 116 | $O/rootfs.tar.gz: $O/rootfs 117 | tar -C $O/rootfs --numeric-owner -zcf $O/rootfs.tar.gz . 118 | 119 | $O/rootfs.tar.xz: $O/rootfs 120 | tar -C $O/rootfs --numeric-owner -Jcf $O/rootfs.tar.xz . 121 | 122 | .PHONY: all clean default help 123 | 124 | --------------------------------------------------------------------------------