Merge pull request #1 from jcvenegas/image-creation-support

Image creation support
This commit is contained in:
Peng Tao
2017-12-11 10:20:42 +08:00
committed by GitHub
19 changed files with 941 additions and 0 deletions

16
Makefile Normal file
View File

@@ -0,0 +1,16 @@
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
MK_DIR :=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
DISTRO ?= centos
DISTRO_ROOTFS := "$(PWD)/$(DISTRO)_rootfs"
IMG_SIZE=500
image:
@echo Creating rootfs based on "$(DISTRO)"
"$(MK_DIR)/rootfs-builder/rootfs.sh" -r "$(DISTRO_ROOTFS)" "$(DISTRO)"
@echo Creating image based on "$(DISTRO_ROOTFS)"
AGENT_BIN="$(AGENT_BIN)" "$(MK_DIR)/image-builder/image_builder.sh" -s "$(IMG_SIZE)" "$(DISTRO_ROOTFS)"

33
README.md Normal file
View File

@@ -0,0 +1,33 @@
# Overview #
`Kata Containers runtime` creates a Virtual Machine to isolate a set of
container workloads. The Virtual Machine requires a operating system
operating (`Guest OS`) to boot and create containers inside the guest
environment.
This repository contains tools to create a `Guest OS` for `Kata
Containers`.
## Terms ##
This section describe the terms used as along all this document.
- `Guest OS`
It is the collection of a `virtual disk` or `disk image` and `kernel`
that in conjunction work as an operating system and it is different than
the host operating system.
- `Virtual disk` or `Guest Image`
It is a virtual disk witch contains a `rootfs` that will be used to boot
a Virtual Machine by for the `Kata Containers runtime`.
- `rootfs`
The root filesystem or rootfs is the filesystem that is contained in the
guest root directory. It can be built from any Linux Distribution but
must provide at least the following components:
- Kata agent
- A `init` system (for example `systemd`) witch allow to start
Kata agent at boot time.

25
image-builder/README.md Normal file
View File

@@ -0,0 +1,25 @@
# Kata Containers image generation #
A Kata Containers image is generated by the script `image_builder.sh`
which uses a `rootfs` directory created by the script
`rootfs-builder/rootfs.sh`.
To create a guest OS image run:
```
$ ./image_builder.sh path/to/rootfs
```
Where `path/to/rootfs` is the directory pupulated by `rootfs.sh`. The
script will check for following required binaries:
- `/sbin/init` : The image must contain a `init` binary
- `/bin/kata-agent` : The image contain the Kata [agent]
More information about usage:
```
$ ./image_builder.sh -h
```
[agent]: https://github.com/kata-containers/agent "Kata agent"

130
image-builder/image_builder.sh Executable file
View File

@@ -0,0 +1,130 @@
#!/bin/bash
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
set -e
if [ -n "$DEBUG" ] ; then
set -x
fi
SCRIPT_NAME="${0##*/}"
IMAGE="${IMAGE:-kata-containers.img}"
AGENT_BIN=${AGENT_BIN:-kata-agent}
die()
{
local msg="$*"
echo "ERROR: ${msg}" >&2
exit 1
}
OK()
{
local msg="$*"
echo "[OK] ${msg}" >&2
}
info()
{
local msg="$*"
echo "INFO: ${msg}"
}
usage()
{
error="${1:-0}"
cat <<EOT
Usage: ${SCRIPT_NAME} [options] <rootfs-dir>
This script will create a Kata Containers image file based on the
<rootfs-dir> directory.
Options:
-h Show this help
-o path to generate image file ENV: IMAGE
-s Image size in MB (default $IMG_SIZE) ENV: IMG_SIZE
Extra environment variables:
AGENT_BIN: use it to change the expected agent binary name"
EOT
exit "${error}"
}
while getopts "ho:s:" opt
do
case "$opt" in
h) usage ;;
o) IMAGE="${OPTARG}" ;;
s) IMG_SIZE="${OPTARG}" ;;
esac
done
shift $(( $OPTIND - 1 ))
ROOTFS="$1"
[ -n "${ROOTFS}" ] || usage
[ -d "${ROOTFS}" ] || die "${ROOTFS} is not a directory"
# The kata rootfs image expect init and kata-agent to be installed
init="${ROOTFS_DIR}/sbin/init"
[ -x "${init}" ] || [ -L ${init} ] || die "/sbin/init is not installed in ${ROOTFS_DIR}"
OK "init is installed"
[ -x "${ROOTFS}/bin/${AGENT_BIN}" ] || \
die "/bin/${AGENT_BIN} is not installed in ${ROOTFS_DIR}
use AGENT_BIN env variable to change the expected agent binary name"
OK "Agent installed"
[ "$(id -u)" -eq 0 ] || die "$0: must be run as root"
BLOCK_SIZE=${BLOCK_SIZE:-4096}
IMG_SIZE=${IMG_SIZE:-80}
info "Creating raw disk with size ${IMG_SIZE}M"
qemu-img create -q -f raw "${IMAGE}" "${IMG_SIZE}M"
OK "Image file created"
# Kata runtime expect an image with just one partition
# The partition is the rootfs content
info "Creating partitions"
parted "${IMAGE}" --script "mklabel gpt" \
"mkpart ext4 1M -1M"
OK "Partitions created"
# Get the loop device bound to the image file (requires /dev mounted in the
# image build system and root privileges)
DEVICE=$(losetup -P -f --show "${IMAGE}")
#Refresh partition table
partprobe "${DEVICE}"
MOUNT_DIR=$(mktemp -d osbuilder-mount-dir.XXXX)
info "Formating Image using ext4 format"
mkfs.ext4 -q -F -b "${BLOCK_SIZE}" "${DEVICE}p1"
OK "Image formated"
info "Mounting root paratition"
mount "${DEVICE}p1" "${MOUNT_DIR}"
OK "root paratition mounted"
RESERVED_BLOCKS_PERCENTAGE=3
info "Set filesystem reserved blocks percentage to ${RESERVED_BLOCKS_PERCENTAGE}%"
tune2fs -m "${RESERVED_BLOCKS_PERCENTAGE}" "${DEVICE}p1"
#TODO: Calculate disk size based on rootfs
#FIXME: https://github.com/kata-containers/osbuilder/issues/2
ROOTFS_SIZE=$(du -B 1MB -s "${ROOTFS}" | awk '{print $1}')
AVAIL_DISK=$(df -B M --output=avail "${DEVICE}p1" | tail -1)
AVAIL_DISK=${AVAIL_DISK/M}
info "Free space root partition ${AVAIL_DISK} MB"
info "rootfs size ${ROOTFS_SIZE} MB"
info "Copying content from rootfs to root partition"
cp -a "${ROOTFS}"/* ${MOUNT_DIR}
OK "rootfs copied"
# Cleanup
sync
umount -l ${MOUNT_DIR}
fsck -D -y "${DEVICE}p1"
losetup -d "${DEVICE}"
info "Image created"

126
rootfs-builder/README.md Normal file
View File

@@ -0,0 +1,126 @@
# Building a rootfs for Kata Containers Guest OS #
The Kata Containers `rootfs` is created using `rootfs.sh`.
## Supported base OSs ##
The `rootfs.sh` script builds a `rootfs` based on a particular Linux\*
distribution. To build a `rootfs`for your chosen distribution, run:
```
$./rootfs.sh <distro>
```
To check the supported `rootfs` based OS run `$rootfs-builder/rootfs.sh
-h`, it will show the supported values of `<distro>`
## Adding support for new base OS ##
The script `rootfs.sh` will it check for immediate sub-directories
containing the following expected files structure:
- A `bash(1)` script called `rootfs_lib.sh`
This file must contain a function called `build_rootfs()` this function
must receive as first argument the path where the `rootfs` will be
populated. Path: `rootfs-builder/<distro>/rootfs_lib.sh`.
- A `bash(1)` file `config.sh`
This represents the specific configuration for `<distro>`. It must
provide configuration specific variables for user to modify as needed.
The `config.sh` file will be loaded before executing `build_rootfs()` to
provide all the needed configuration to the function. Path:
`rootfs-builder/<distro>/config.sh`.
To create a directory with the expected file structure run:
```
make -f template/Makefile ROOTFS_BASE_NAME=my_new_awesome_rootfs
```
After run the command above, a new directory will be created in
`rootfs-builder/my_new_awesome_rootfs/`. To verify it is one of the
options to build a `rootfs` run `./rootfs.sh -h`, it will show
`my_new_awesome` as one of the options to use it for:
```
./rootfs.sh <distro>
```
Now that a new directory structure was created is need to:
- If needed, add configuration variables to `rootfs-builder/my_new_awesome_rootfs/config.sh`
- Implement the stub `build_rootfs()` function from `rootfs-builder/my_new_awesome_rootfs/rootfs_lib.sh`
### Expected `rootfs` directory content ###
After the function `build_rootfs` is called, the script expects the
`rootfs` directory to contain /sbin/init and /sbin/kata-agent binaries.
### (optional) Customise the `rootfs` ###
For development uses cases, developers may want to modify the guest OS.
To do that it is possible to use following methods:
- Use the environment variable `EXTRA_PKG` to provide a list of space
separated packages to be installed.
*Note: The package names may vary among Linux* distributions, the extra
package names must exist in the base OS flavor you use to build the
`rootfs`*
Example:
```
EXTRA_PKG="vim emacs" ./rootfs-builder/rootfs.sh \
-r ${PWD}/myrootfs fedora
```
- In `rootfs-builder/<distro>/config.sh` modify the variable `PACKAGES`.
This are the minimal set of packages needed. The configuration file must
use the package names from the distro was created for.
- It is possible to customise the `rootfs` directory before create an
image based in on it.
## Build `rootfs` using Docker* ##
Depending on the base OS to build the `rootfs` guest OS, it is required some
specific programs that probably are not available or installed in the system
that will build the guest image. For this case `rootfs.sh` can use
a Docker\* container to build the `rootfs`. The following requirements
must be met:
1. Docker 1.12+ installed
2. `runc` is configured as the default runtime
To check if `runc` is the default runtime:
```
$ docker info | grep 'Default Runtime: runc'
```
Note:
This requirement is specifically when using Clear Containers runtime
see [issue](https://github.com/clearcontainers/runtime/issues/828) for
more information.
3. Export `USE_DOCKER` variable
```
$ export USE_DOCKER=true
```
4. Use `rootfs.sh:
Example:
```
$ export USE_DOCKER=true
$ # build guest O/S rootfs based on fedora
$ ./rootfs-builder/rootfs.sh -r "${PWD}/fedora_rootfs" fedora
$ # build image based rootfs created above
$ ./image-builder/image_builder.sh "${PWD}/fedora_rootfs"
```

View File

@@ -0,0 +1 @@
FROM centos:7

View File

@@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (GNU/Linux)
mQINBFOn/0sBEADLDyZ+DQHkcTHDQSE0a0B2iYAEXwpPvs67cJ4tmhe/iMOyVMh9
Yw/vBIF8scm6T/vPN5fopsKiW9UsAhGKg0epC6y5ed+NAUHTEa6pSOdo7CyFDwtn
4HF61Esyb4gzPT6QiSr0zvdTtgYBRZjAEPFVu3Dio0oZ5UQZ7fzdZfeixMQ8VMTQ
4y4x5vik9B+cqmGiq9AW71ixlDYVWasgR093fXiD9NLT4DTtK+KLGYNjJ8eMRqfZ
Ws7g7C+9aEGHfsGZ/SxLOumx/GfiTloal0dnq8TC7XQ/JuNdB9qjoXzRF+faDUsj
WuvNSQEqUXW1dzJjBvroEvgTdfCJfRpIgOrc256qvDMp1SxchMFltPlo5mbSMKu1
x1p4UkAzx543meMlRXOgx2/hnBm6H6L0FsSyDS6P224yF+30eeODD4Ju4BCyQ0jO
IpUxmUnApo/m0eRelI6TRl7jK6aGqSYUNhFBuFxSPKgKYBpFhVzRM63Jsvib82rY
438q3sIOUdxZY6pvMOWRkdUVoz7WBExTdx5NtGX4kdW5QtcQHM+2kht6sBnJsvcB
JYcYIwAUeA5vdRfwLKuZn6SgAUKdgeOtuf+cPR3/E68LZr784SlokiHLtQkfk98j
NXm6fJjXwJvwiM2IiFyg8aUwEEDX5U+QOCA0wYrgUQ/h8iathvBJKSc9jQARAQAB
tEJDZW50T1MtNyBLZXkgKENlbnRPUyA3IE9mZmljaWFsIFNpZ25pbmcgS2V5KSA8
c2VjdXJpdHlAY2VudG9zLm9yZz6JAjUEEwECAB8FAlOn/0sCGwMGCwkIBwMCBBUC
CAMDFgIBAh4BAheAAAoJECTGqKf0qA61TN0P/2730Th8cM+d1pEON7n0F1YiyxqG
QzwpC2Fhr2UIsXpi/lWTXIG6AlRvrajjFhw9HktYjlF4oMG032SnI0XPdmrN29lL
F+ee1ANdyvtkw4mMu2yQweVxU7Ku4oATPBvWRv+6pCQPTOMe5xPG0ZPjPGNiJ0xw
4Ns+f5Q6Gqm927oHXpylUQEmuHKsCp3dK/kZaxJOXsmq6syY1gbrLj2Anq0iWWP4
Tq8WMktUrTcc+zQ2pFR7ovEihK0Rvhmk6/N4+4JwAGijfhejxwNX8T6PCuYs5Jiv
hQvsI9FdIIlTP4XhFZ4N9ndnEwA4AH7tNBsmB3HEbLqUSmu2Rr8hGiT2Plc4Y9AO
aliW1kOMsZFYrX39krfRk2n2NXvieQJ/lw318gSGR67uckkz2ZekbCEpj/0mnHWD
3R6V7m95R6UYqjcw++Q5CtZ2tzmxomZTf42IGIKBbSVmIS75WY+cBULUx3PcZYHD
ZqAbB0Dl4MbdEH61kOI8EbN/TLl1i077r+9LXR1mOnlC3GLD03+XfY8eEBQf7137
YSMiW5r/5xwQk7xEcKlbZdmUJp3ZDTQBXT06vavvp3jlkqqH9QOE8ViZZ6aKQLqv
pL+4bs52jzuGwTMT7gOR5MzD+vT0fVS7Xm8MjOxvZgbHsAgzyFGlI1ggUQmU7lu3
uPNL0eRx4S1G4Jn5
=OGYX
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -0,0 +1,15 @@
# This is a configuration file add extra variables to
# be used by build_rootfs() from rootfs_lib.sh the variables will be
# loaded just before call the function.
# Here there are a couple of variables you may need.
# Remove them or add more
# Centos Version
OS_VERSION=${OS_VERSION:-7}
#Mandatory Packages that must be installed
# systemd: An init system that will start kata-agent
# iptables: Need by Kata agent
# udevlib.so: Need by Kata agent
PACKAGES="systemd iptables"

View File

@@ -0,0 +1,134 @@
#!/bin/bash
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
check_program(){
type "$1" >/dev/null 2>&1
}
check_root()
{
if [ "$(id -u)" != "0" ]; then
echo "Root is needed"
exit 1
fi
}
generate_dnf_config()
{
cat > "${DNF_CONF}" << EOF
[main]
cachedir=/var/cache/centos-osbuilder
keepcache=0
debuglevel=2
logfile=/var/log/yum-centos.log
exactarch=1
obsoletes=1
gpgcheck=0
plugins=0
installonly_limit=3
#Dont use the default dnf reposdir
#this will prevent to use host repositories
reposdir=/root/mash
[base]
name=CentOS-7 - Base
mirrorlist=http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&container=container
#baseurl=${REPO_URL}/os/x86_64/
gpgcheck=1
gpgkey=file://${CONFIG_DIR}/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-7 - Updates
mirrorlist=http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=updates&container=container
#baseurl=${REPO_URL}/updates/x86_64/
gpgcheck=1
gpgkey=file://${CONFIG_DIR}/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-7 - Extras
mirrorlist=http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=extras&container=container
#baseurl=${REPO_URL}/extras/x86_64/
gpgcheck=1
gpgkey=file://${CONFIG_DIR}/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-7 - Plus
mirrorlist=http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=centosplus&container=container
#baseurl=${REPO_URL}/centosplus/x86_64/
gpgcheck=1
enabled=0
gpgkey=file://${CONFIG_DIR}/RPM-GPG-KEY-CentOS-7
EOF
}
# - Arguments
# rootfs_dir=$1
#
# - Optional environment variables
#
# EXTRA_PKGS: Variable to add extra PKGS provided by the user
#
# BIN_AGENT: Name of the Kata-Agent binary
#
# REPO_URL: URL to distribution repository ( should be configured in
# config.sh file)
#
# Any other configuration variable for a specific distro must be added
# and documented on its own config.sh
#
# - Expected result
#
# rootfs_dir populated with rootfs pkgs
# It must provide a binary in /sbin/init
build_rootfs() {
# Mandatory
local ROOTFS_DIR=$1
#Name of the Kata-Agent binary
local BIN_AGENT=${BIN_AGENT}
# In case of support EXTRA packages, use it to allow
# users add more packages to the base rootfs
local EXTRA_PKGS=${EXTRA_PKGS:-}
#In case rootfs is created usign repositories allow user to modify
# the default URL
local REPO_URL=${REPO_URL:-http://mirror.centos.org/centos/7}
#PATH where files this script is placed
#Use it to refer to files in the same directory
#Exmaple: ${CONFIG_DIR}/foo
local CONFIG_DIR=${CONFIG_DIR}
# Populate ROOTFS_DIR
# Must provide /sbin/init and /bin/${BIN_AGENT}
check_root
if [ ! -f "${DNF_CONF}" ]; then
DNF_CONF="./kata-centos-dnf.conf"
generate_dnf_config
fi
mkdir -p "${ROOTFS_DIR}"
if [ -n "${PKG_MANAGER}" ]; then
info "DNF path provided by user: ${PKG_MANAGER}"
elif check_program "dnf"; then
PKG_MANAGER="dnf"
elif check_program "yum" ; then
PKG_MANAGER="yum"
else
die "neither yum nor dnf is installed"
fi
info "Using : ${PKG_MANAGER} to pull packages from ${REPO_URL}"
DNF="${PKG_MANAGER} --config=$DNF_CONF -y --installroot=${ROOTFS_DIR} --noplugins"
$DNF install ${EXTRA_PKGS} ${PACKAGES}
[ -n "${ROOTFS_DIR}" ] && rm -r "${ROOTFS_DIR}/var/cache/centos-osbuilder"
}

View File

@@ -0,0 +1,3 @@
From fedora:27
RUN dnf -y update && dnf install -y git golang systemd pkgconfig

View File

@@ -0,0 +1,8 @@
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#Use "latest" to always pull the last Clear Linux Release
OS_VERSION=${OS_VERSION:-latest}
PACKAGES="systemd iptables-bin libudev0-shim"

View File

@@ -0,0 +1,93 @@
#!/bin/bash
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
set -e
check_program(){
type "$1" >/dev/null 2>&1
}
generate_dnf_config()
{
echo "WARNING: using not signed packages"
cat > "${DNF_CONF}" << EOF
[main]
cachedir=/var/cache/dnf-clear
keepcache=0
debuglevel=2
logfile=/var/log/dnf.log
exactarch=1
obsoletes=1
gpgcheck=0
plugins=0
installonly_limit=3
#Dont use the default dnf reposdir
#this will prevent to use host repositories
reposdir=/root/mash
[clear]
name=Clear
failovermethod=priority
baseurl=${REPO_URL}
enabled=1
#Clear Linux based packages security limitations
#Although the Clear Linux rootfs is constructed from rpm packages, Clear Linux
#itself is not an rpm-based Linux distribution (the software installed on a
#Clear Linux system is not managed using rpm). The rpm packages used to
#generate the rootfs are not signed, so there is no way to ensure that
#downloaded packages are trustworthy.
gpgcheck=0
EOF
}
build_rootfs()
{
# Mandatory
local ROOTFS_DIR=$1
#In case rootfs is created usig repositories allow user to modify
# the default URL
local REPO_URL=${REPO_URL:-https://download.clearlinux.org/current/x86_64/os/}
# In case of support EXTRA packages, use it to allow
# users add more packages to the base rootfs
local EXTRA_PKGS=${EXTRA_PKGS:-}
#PATH where files this script is placed
#Use it to refer to files in the same directory
#Exmaple: ${CONFIG_DIR}/foo
#local CONFIG_DIR=${CONFIG_DIR}
check_root
if [ ! -f "${DNF_CONF}" ]; then
DNF_CONF="./clear-dnf.conf"
generate_dnf_config
fi
mkdir -p "${ROOTFS_DIR}"
if [ -n "${PKG_MANAGER}" ]; then
info "DNF path provided by user: ${PKG_MANAGER}"
elif check_program "dnf"; then
PKG_MANAGER="dnf"
elif check_program "yum" ; then
PKG_MANAGER="yum"
else
die "neither yum nor dnf is installed"
fi
info "Using : ${PKG_MANAGER} to pull packages from ${REPO_URL}"
DNF="${PKG_MANAGER} --config=$DNF_CONF -y --installroot=${ROOTFS_DIR} --noplugins"
$DNF install ${EXTRA_PKGS} ${PACKAGES}
[ -n "${ROOTFS_DIR}" ] && rm -r "${ROOTFS_DIR}/var/cache/dnf-clear"
}
check_root()
{
if [ "$(id -u)" != "0" ]; then
echo "Root is needed"
exit 1
fi
}

View File

@@ -0,0 +1,3 @@
From fedora:27
RUN dnf -y update && dnf install -y git golang systemd pkgconfig

View File

@@ -0,0 +1,8 @@
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#Fedora version to use
OS_VERSION=${OS_VERSION:-27}
PACKAGES="systemd iptables"

View File

@@ -0,0 +1,88 @@
#!/bin/bash
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
set -e
check_program(){
type "$1" >/dev/null 2>&1
}
generate_dnf_config()
{
cat > "${DNF_CONF}" << EOF
[main]
cachedir=/var/cache/dnf/kata/
keepcache=0
debuglevel=2
logfile=/var/log/dnf.log
exactarch=1
obsoletes=1
gpgcheck=0
plugins=0
installonly_limit=3
#Dont use the default dnf reposdir
#this will prevent to use host repositories
reposdir=/root/mash
[kata]
name=fedora
failovermethod=priority
baseurl=${REPO_URL}
enabled=1
gpgcheck=0
EOF
}
build_rootfs()
{
# Mandatory
local ROOTFS_DIR=$1
#In case rootfs is created usig repositories allow user to modify
# the default URL
local REPO_URL=${REPO_URL:-http://mirror.math.princeton.edu/pub/fedora/linux/releases/$OS_VERSION/Everything/x86_64/os/}
# In case of support EXTRA packages, use it to allow
# users add more packages to the base rootfs
local EXTRA_PKGS=${EXTRA_PKGS:-""}
#PATH where files this script is placed
#Use it to refer to files in the same directory
#Exmaple: ${CONFIG_DIR}/foo
#local CONFIG_DIR=${CONFIG_DIR}
check_root
if [ ! -f "${DNF_CONF}" ]; then
DNF_CONF="./kata-fedora-dnf.conf"
generate_dnf_config
fi
mkdir -p "${ROOTFS_DIR}"
if [ -n "${PKG_MANAGER}" ]; then
info "DNF path provided by user: ${PKG_MANAGER}"
elif check_program "dnf"; then
PKG_MANAGER="dnf"
elif check_program "yum" ; then
PKG_MANAGER="yum"
else
die "neither yum nor dnf is installed"
fi
info "Using : ${PKG_MANAGER} to pull packages from ${REPO_URL}"
DNF="${PKG_MANAGER} --config=$DNF_CONF -y --installroot=${ROOTFS_DIR} --noplugins"
$DNF install ${EXTRA_PKGS} ${PACKAGES}
[ -n "${ROOTFS_DIR}" ] && rm -r "${ROOTFS_DIR}/var/cache/dnf"
}
check_root()
{
if [ "$(id -u)" != "0" ]; then
echo "Root is needed"
exit 1
fi
}

155
rootfs-builder/rootfs.sh Executable file
View File

@@ -0,0 +1,155 @@
#!/bin/bash
#
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
set -e
script_name="${0##*/}"
script_dir="$(dirname $(realpath -s $0))"
ROOTFS_DIR=${ROOTFS_DIR:-${PWD}/rootfs}
AGENT_VERSION=${AGENT_VERSION:-master}
GO_AGENT_PKG=${GO_AGENT_PKG:-github.com/kata-containers/agent}
AGENT_BIN=${AGENT_BIN:-kata-agent}
# Name of file that will implement build_rootfs
typeset -r LIB_SH="rootfs_lib.sh"
if [ -n "$DEBUG" ] ; then
set -x
fi
#$1: Error code if want to exit differnt to 0
usage(){
error="${1:-0}"
cat <<EOT
USAGE: Build a Guest OS rootfs for Kata Containers image
${script_name} [options] <distro_name>
<distro_name> : Linux distribution to use as base OS.
Supported Linux distributions:
$(get_distros)
Options:
-a : agent version DEFAULT: ${AGENT_VERSION} ENV: AGENT_VERSION
-h : Show this help message
-r : rootfs directory DEFAULT: ${ROOTFS_DIR} ENV: ROOTFS_DIR
ENV VARIABLES:
GO_AGENT_PKG: Change the golang package url to get the agent source code
DEFAULT: ${GO_AGENT_PKG}
AGENT_BIN : Name of the agent binary (needed to check if agent is installed)
USE_DOCKER: If set will build rootfs in a Docker Container (requries docker)
DEFAULT: not set
EOT
exit "${error}"
}
die()
{
msg="$*"
echo "ERROR: ${msg}" >&2
exit 1
}
info()
{
msg="$*"
echo "INFO: ${msg}" >&2
}
OK()
{
msg="$*"
echo "INFO: [OK] ${msg}" >&2
}
get_distros() {
cdirs=$(find "${script_dir}" -maxdepth 1 -type d)
find ${cdirs} -maxdepth 1 -name "${LIB_SH}" -printf '%H\n' | while read dir; do
basename "${dir}"
done
}
check_function_exist() {
function_name="$1"
[ "$(type -t ${function_name})" == "function" ] || die "${function_name} function was not defined"
}
while getopts c:hr: opt
do
case $opt in
a) AGENT_VERSION="${OPTARG}" ;;
h) usage ;;
r) ROOTFS_DIR="${OPTARG}" ;;
esac
done
shift $(($OPTIND - 1))
distro="$1"
[ -n "${distro}" ] || usage 1
distro_config_dir="${script_dir}/${distro}"
[ -d "${distro_config_dir}" ] || die "Not found configuration directory ${distro_config_dir}"
rootfs_lib="${distro_config_dir}/${LIB_SH}"
source "${rootfs_lib}"
rootfs_config="${distro_config_dir}/config.sh"
source "${rootfs_config}"
CONFIG_DIR=${distro_config_dir}
check_function_exist "build_rootfs"
if [ -n "${USE_DOCKER}" ] ; then
image_name="${distro}-rootfs-osbuilder"
docker build \
--build-arg http_proxy="${http_proxy}" \
--build-arg https_proxy="${https_proxy}" \
-t "${image_name}" "${distro_config_dir}"
#Make sure we use a compatible runtime to build rootfs
# In case Clear Containers Runtime is installed we dont want to hit issue:
#https://github.com/clearcontainers/runtime/issues/828
docker run \
--runtime runc \
--env https_proxy="${https_proxy}" \
--env http_proxy="${http_proxy}" \
--env AGENT_VERSION="${AGENT_VERSION}" \
--env ROOTFS_DIR="/rootfs" \
--env GO_AGENT_PKG="${GO_AGENT_PKG}" \
--env AGENT_BIN="${AGENT_BIN}" \
--env GOPATH="${GOPATH}" \
-v "${script_dir}":"/osbuilder" \
-v "${ROOTFS_DIR}":"/rootfs" \
-v "${GOPATH}":"${GOPATH}" \
${image_name} \
bash /osbuilder/rootfs.sh "${distro}"
exit $?
fi
mkdir -p ${ROOTFS_DIR}
build_rootfs ${ROOTFS_DIR}
info "Check init is installed"
init="${ROOTFS_DIR}/sbin/init"
[ -x "${init}" ] || [ -L ${init} ] || die "/sbin/init is not installed in ${ROOTFS_DIR}"
OK "init is installed"
info "Pull Agent source code"
go get -d "${GO_AGENT_PKG}" || true
OK "Pull Agent source code"
info "Build agent"
pushd "${GOPATH}/src/${GO_AGENT_PKG}"
make INIT=no
make install DESTDIR="${ROOTFS_DIR}" INIT=no
popd
[ -x "${ROOTFS_DIR}/bin/${AGENT_BIN}" ] || die "/bin/${AGENT_BIN} is not installed in ${ROOTFS_DIR}"
OK "Agent installed"

View File

@@ -0,0 +1,15 @@
# Copyright (c) 2017 Intel Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
#
MK_DIR :=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
## Default destdir is one level up where is rootfs.sh script
DESTDIR ?= "$(realpath $(MK_DIR)/../)/$(ROOTFS_BASE_NAME)"
all:
ifndef ROOTFS_BASE_NAME
$(error ROOTFS_BASE_NAME is not set, use $ make ROOTFS_BASE_NAME=new_supported_os)
endif
mkdir -p $(DESTDIR)
cp "$(MK_DIR)/rootfs_lib_template.sh" "$(DESTDIR)/rootfs_lib.sh"
cp "$(MK_DIR)/config_template.sh" "$(DESTDIR)/config.sh"

View File

@@ -0,0 +1,15 @@
# This is a configuration file add extra variables to
# be used by build_rootfs() from rootfs_lib.sh the variables will be
# loaded just before call the function.
# Here there are a couple of variables you may need.
# Remove them or add more
#Use it rootfs is based in a system has different versions
OS_VERSION=${OS_VERSION:-DEFAULT_VERSION}
#Mandatory Packages that must be installed
# systemd: An init system that will start kata-agent
# iptables: Need by Kata agent
# udevlib.so: Need by Kata agent
PACKAGES="systemd iptables udevlib.so"

View File

@@ -0,0 +1,43 @@
# - Arguments
# rootfs_dir=$1
#
# - Optional environment variables
#
# EXTRA_PKGS: Variable to add extra PKGS provided by the user
#
# BIN_AGENT: Name of the Kata-Agent binary
#
# REPO_URL: URL to distribution repository ( should be configured in
# config.sh file)
#
# Any other configuration variable for a specific distro must be added
# and documented on its own config.sh
#
# - Expected result
#
# rootfs_dir populated with rootfs pkgs
# It must provide a binary in /sbin/init
build_rootfs() {
# Mandatory
local ROOTFS_DIR=$1
#Name of the Kata-Agent binary
local BIN_AGENT=${BIN_AGENT}
# In case of support EXTRA packages, use it to allow
# users add more packages to the base rootfs
local EXTRA_PKGS=${EXTRA_PKGS:-}
#In case rootfs is created usign repositories allow user to modify
# the default URL
local REPO_URL=${REPO_URL:-YOUR_REPO}
#PATH where files this script is placed
#Use it to refer to files in the same directory
#Exmaple: ${CONFIG_DIR}/foo
local CONFIG_DIR=${CONFIG_DIR}
# Populate ROOTFS_DIR
# Must provide /sbin/init and /bin/${BIN_AGENT}
}