Skip to content

Commit

Permalink
Merge pull request kata-containers#1 from jcvenegas/image-creation-su…
Browse files Browse the repository at this point in the history
…pport

Image creation support
  • Loading branch information
bergwolf authored Dec 11, 2017
2 parents d2f31df + 4882042 commit 8f0d7f6
Show file tree
Hide file tree
Showing 19 changed files with 941 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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 changes: 33 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions image-builder/README.md
Original file line number Diff line number Diff line change
@@ -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 changes: 130 additions & 0 deletions image-builder/image_builder.sh
Original file line number Diff line number Diff line change
@@ -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 changes: 126 additions & 0 deletions rootfs-builder/README.md
Original file line number Diff line number Diff line change
@@ -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"
```
1 change: 1 addition & 0 deletions rootfs-builder/centos/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM centos:7
30 changes: 30 additions & 0 deletions rootfs-builder/centos/RPM-GPG-KEY-CentOS-7
Original file line number Diff line number Diff line change
@@ -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-----
15 changes: 15 additions & 0 deletions rootfs-builder/centos/config.sh
Original file line number Diff line number Diff line change
@@ -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"
Loading

0 comments on commit 8f0d7f6

Please sign in to comment.