mirror of
https://github.com/p8952/bocker.git
synced 2025-11-08 20:43:59 +01:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
000633061c | ||
|
|
22dc3c5b19 | ||
|
|
b6653f6962 | ||
|
|
3740778537 | ||
|
|
7911226036 | ||
|
|
25029b4f07 | ||
|
|
abb635a24c | ||
|
|
747c8b251f | ||
|
|
4956a537b7 | ||
|
|
23fdb390a6 | ||
|
|
c4c748ded7 | ||
|
|
74c2b197c7 | ||
|
|
df8c4065c7 | ||
|
|
e7dd210844 | ||
|
|
f33b31b3d6 | ||
|
|
1f48b32c42 | ||
|
|
bc1b4719b5 | ||
|
|
11129aecc0 | ||
|
|
25efd9497d | ||
|
|
8505276c60 | ||
|
|
6f8e5e9cb9 | ||
|
|
baf937abdd | ||
|
|
afcbd1bd06 | ||
|
|
1b5f10b8ab | ||
|
|
7bd579c349 | ||
|
|
b240a47ac8 | ||
|
|
d5b38393c2 | ||
|
|
7c85abd1b4 | ||
|
|
c64c575abb | ||
|
|
5d48897ffa | ||
|
|
d4b9247f14 | ||
|
|
871a851ffc | ||
|
|
caf4a38b9a | ||
|
|
036d2b6ffc | ||
|
|
61f8ed7a49 | ||
|
|
0b5dc8b338 | ||
|
|
aa13b05e63 | ||
|
|
5d9c745eef | ||
|
|
5246b814a3 | ||
|
|
b6678d7a2b | ||
|
|
aad843d8d2 | ||
|
|
e84b1f768c | ||
|
|
6e6ee2d3b2 | ||
|
|
a9f3039c59 | ||
|
|
c3efade5c4 | ||
|
|
3eaea7e44c | ||
|
|
103182ad40 | ||
|
|
d229161326 | ||
|
|
3bf68db6a4 | ||
|
|
dbbeaf8732 | ||
|
|
7edff781c1 | ||
|
|
39ebf616c4 | ||
|
|
222b630588 | ||
|
|
5624b48038 | ||
|
|
2232bb67ae |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1 @@
|
||||
.vagrant/
|
||||
base-image/
|
||||
util-linux/
|
||||
|
||||
90
README.md
90
README.md
@ -1,5 +1,5 @@
|
||||
# Bocker
|
||||
Docker implemented in 100 lines of bash.
|
||||
Docker implemented in around 100 lines of bash.
|
||||
|
||||
* [Prerequisites](#prerequisites)
|
||||
* [Example Usage](#example-usage)
|
||||
@ -12,51 +12,56 @@ Docker implemented in 100 lines of bash.
|
||||
The following packages are needed to run bocker.
|
||||
|
||||
* btrfs-progs
|
||||
* curl
|
||||
* iproute2
|
||||
* iptables
|
||||
* libcgroup-tools
|
||||
* util-linux >= 2.25.2
|
||||
* coreutils >= 7.5
|
||||
|
||||
Because most distributions do not ship a new enough version of util-linux you will probably need grab the sources from [here](https://www.kernel.org/pub/linux/utils/util-linux/v2.25/) and compile it yourself.
|
||||
Because most distributions do not ship a new enough version of util-linux you will probably need to grab the sources from [here](https://www.kernel.org/pub/linux/utils/util-linux/v2.25/) and compile it yourself.
|
||||
|
||||
Additionally your system will need to be configured with the following.
|
||||
Additionally your system will need to be configured with the following:
|
||||
|
||||
* A btrfs filesystem mounted under `/var/bocker`
|
||||
* A network bridge called `bridge0` and an IP of 10.0.0.1/24
|
||||
* IP forwarding enabled in `/proc/sys/net/ipv4/ip_forward`
|
||||
* A firewall routing traffic from `bridge0` to a physical interface.
|
||||
* A `base-image` which contains the filesystem to seed your container with.
|
||||
|
||||
For ease of use a Vagrantfile is included which will build the needed environment.
|
||||
|
||||
Even if you meet the above prerequisites you probably still want to **run bocker in a virtual machine**. Bocker runs as root and among other things needs to make changes to your network interfaces, routing table, and firewall rules. **I can make no guarantees that it wont trash your system**.
|
||||
Even if you meet the above prerequisites you probably still want to **run bocker in a virtual machine**. Bocker runs as root and among other things needs to make changes to your network interfaces, routing table, and firewall rules. **I can make no guarantees that it won't trash your system**.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
$ bocker init base-image/
|
||||
Created: img_84632
|
||||
$ bocker pull centos 7
|
||||
######################################################################## 100.0%
|
||||
######################################################################## 100.0%
|
||||
######################################################################## 100.0%
|
||||
Created: img_42150
|
||||
|
||||
$ bocker images
|
||||
IMAGE_ID
|
||||
img_84632
|
||||
IMAGE_ID SOURCE
|
||||
img_42150 centos:7
|
||||
|
||||
$ bocker run img_84632 uname -sro
|
||||
Linux 3.10.0-123.20.1.el7.x86_64 GNU/Linux
|
||||
$ bocker run img_42150 cat /etc/centos-release
|
||||
CentOS Linux release 7.1.1503 (Core)
|
||||
|
||||
$ bocker ps
|
||||
CONTAINER_ID COMMAND
|
||||
ps_12277 uname -sro
|
||||
ps_42045 cat /etc/centos-release
|
||||
|
||||
$ bocker logs ps_12277
|
||||
Linux 3.10.0-123.20.1.el7.x86_64 GNU/Linux
|
||||
$ bocker logs ps_42045
|
||||
CentOS Linux release 7.1.1503 (Core)
|
||||
|
||||
$ bocker rm ps_12277
|
||||
Removed: ps_12277
|
||||
$ bocker rm ps_42045
|
||||
Removed: ps_42045
|
||||
|
||||
$ bocker run img_84632 which wget
|
||||
$ bocker run img_42150 which wget
|
||||
which: no wget in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
|
||||
|
||||
$ bocker run img_84632 yum install -y wget
|
||||
$ bocker run img_42150 yum install -y wget
|
||||
Installing : wget-1.14-10.el7_0.1.x86_64 1/1
|
||||
Verifying : wget-1.14-10.el7_0.1.x86_64 1/1
|
||||
Installed : wget.x86_64 0:1.14-10.el7_0.1
|
||||
@ -64,47 +69,62 @@ Complete!
|
||||
|
||||
$ bocker ps
|
||||
CONTAINER_ID COMMAND
|
||||
ps_14099 which wget
|
||||
ps_43377 yum install -y wget
|
||||
ps_42018 yum install -y wget
|
||||
ps_42182 which wget
|
||||
|
||||
$bocker commit ps_43377 img_84632
|
||||
Removed: img_84632
|
||||
Created: img_84632
|
||||
$ bocker commit ps_42018 img_42150
|
||||
Removed: img_42150
|
||||
Created: img_42150
|
||||
|
||||
$ bocker run img_84632 which wget
|
||||
$ bocker run img_42150 which wget
|
||||
/usr/bin/wget
|
||||
|
||||
$ bocker rm ps_14099
|
||||
Removed: ps_14099
|
||||
$ bocker run img_42150 cat /proc/1/cgroup
|
||||
...
|
||||
4:memory:/ps_42152
|
||||
3:cpuacct,cpu:/ps_42152
|
||||
|
||||
$ bocker rm ps_43377
|
||||
Removed: ps_43377
|
||||
$ cat /sys/fs/cgroup/cpu/ps_42152/cpu.shares
|
||||
512
|
||||
|
||||
$ bocker rm ps_95942
|
||||
Removed: ps_95942
|
||||
$ cat /sys/fs/cgroup/memory/ps_42152/memory.limit_in_bytes
|
||||
512000000
|
||||
|
||||
$ bocker rm img_84632
|
||||
Removed: img_84632
|
||||
$ BOCKER_CPU_SHARE=1024 \
|
||||
BOCKER_MEM_LIMIT=1024 \
|
||||
bocker run img_42150 cat /proc/1/cgroup
|
||||
...
|
||||
4:memory:/ps_42188
|
||||
3:cpuacct,cpu:/ps_42188
|
||||
|
||||
$ cat /sys/fs/cgroup/cpu/ps_42188/cpu.shares
|
||||
1024
|
||||
|
||||
$ cat /sys/fs/cgroup/memory/ps_42188/memory.limit_in_bytes
|
||||
1024000000
|
||||
```
|
||||
|
||||
## Functionality: Currently Implemented
|
||||
|
||||
* `docker build` †
|
||||
* `docker pull`
|
||||
* `docker images`
|
||||
* `docker ps`
|
||||
* `docker run`
|
||||
* `docker exec`
|
||||
* `docker logs`
|
||||
* `docker commit`
|
||||
* `docker rm` / `docker rmi`
|
||||
* Networking
|
||||
* Quota Support / CGroups
|
||||
|
||||
† `bocker init` provides a very limited implemetation of `docker build`
|
||||
† `bocker init` provides a very limited implementation of `docker build`
|
||||
|
||||
## Functionality: Not Yet Implemented
|
||||
|
||||
* Port Forwarding
|
||||
* Data Volumes
|
||||
* Data Volume Containers
|
||||
* Data Volumes
|
||||
* Port Forwarding
|
||||
|
||||
## License
|
||||
|
||||
|
||||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
@ -1,7 +1,7 @@
|
||||
$script = <<SCRIPT
|
||||
(
|
||||
rpm -i https://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
|
||||
yum install -y -q autoconf automake btrfs-progs docker gettext-devel git libtool python-pip
|
||||
yum install -y -q autoconf automake btrfs-progs docker gettext-devel git libcgroup-tools libtool python-pip
|
||||
|
||||
fallocate -l 10G ~/btrfs.img
|
||||
mkdir /var/bocker
|
||||
|
||||
187
bocker
187
bocker
@ -1,96 +1,119 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail; shopt -s nullglob
|
||||
btrfs_path='/var/bocker';
|
||||
function CHECK() {
|
||||
[[ "$1" == 'img' ]] && TYPE='image'
|
||||
[[ "$1" == 'ps' ]] && TYPE='container'
|
||||
[[ "$1" == '' ]] && TYPE='container or image'
|
||||
if [[ "$2" == "$1"* ]]; then
|
||||
if btrfs subvolume list "$btrfs_path" | grep -qw "$2"; then
|
||||
return 0
|
||||
btrfs_path='/var/bocker' && cgroups='cpu,cpuacct,memory';
|
||||
[[ $# -gt 0 ]] && while [ "${1:0:2}" == '--' ]; do OPTION=${1:2}; [[ $OPTION =~ = ]] && declare "BOCKER_${OPTION/=*/}=${OPTION/*=/}" || declare "BOCKER_${OPTION}=x"; shift; done
|
||||
|
||||
function bocker_check() {
|
||||
btrfs subvolume list "$btrfs_path" | grep -qw "$1" && echo 0 || echo 1
|
||||
}
|
||||
|
||||
function bocker_init() { #HELP Create an image from a directory:\nBOCKER init <directory>
|
||||
uuid="img_$(shuf -i 42002-42254 -n 1)"
|
||||
if [[ -d "$1" ]]; then
|
||||
[[ "$(bocker_check "$uuid")" == 0 ]] && bocker_run "$@"
|
||||
btrfs subvolume create "$btrfs_path/$uuid" > /dev/null
|
||||
cp -rf --reflink=auto "$1"/* "$btrfs_path/$uuid" > /dev/null
|
||||
[[ ! -f "$btrfs_path/$uuid"/img.source ]] && echo "$1" > "$btrfs_path/$uuid"/img.source
|
||||
echo "Created: $uuid"
|
||||
else
|
||||
echo "No directory named '$1' exists"
|
||||
fi
|
||||
fi
|
||||
echo "No $TYPE named '$2' exists" && exit 1
|
||||
}
|
||||
function INIT() {
|
||||
if [[ -d "$1" ]]; then
|
||||
uuid="img_$(shuf -i 10000-99999 -n 1)"
|
||||
btrfs subvolume create "$btrfs_path/$uuid" > /dev/null
|
||||
cp -rf --reflink=auto "$1"/* "$btrfs_path/$uuid" > /dev/null
|
||||
echo "Created: $uuid"
|
||||
else
|
||||
echo "No directory named '$1' exists"
|
||||
fi
|
||||
|
||||
function bocker_pull() { #HELP Pull an image from Docker Hub:\nBOCKER pull <name> <tag>
|
||||
token="$(curl -sL -o /dev/null -D- -H 'X-Docker-Token: true' "https://index.docker.io/v1/repositories/$1/images" | tr -d '\r' | awk -F ': *' '$1 == "X-Docker-Token" { print $2 }')"
|
||||
registry='https://registry-1.docker.io/v1'
|
||||
id="$(curl -sL -H "Authorization: Token $token" "$registry/repositories/$1/tags/$2" | sed 's/"//g')"
|
||||
[[ "${#id}" -ne 64 ]] && echo "No image named '$1:$2' exists" && exit 1
|
||||
ancestry="$(curl -sL -H "Authorization: Token $token" "$registry/images/$id/ancestry")"
|
||||
IFS=',' && ancestry=(${ancestry//[\[\] \"]/}) && IFS=' \n\t'; tmp_uuid="$(uuidgen)" && mkdir /tmp/"$tmp_uuid"
|
||||
for id in "${ancestry[@]}"; do
|
||||
curl -#L -H "Authorization: Token $token" "$registry/images/$id/layer" -o /tmp/"$tmp_uuid"/layer.tar
|
||||
tar xf /tmp/"$tmp_uuid"/layer.tar -C /tmp/"$tmp_uuid" && rm /tmp/"$tmp_uuid"/layer.tar
|
||||
done
|
||||
echo "$1:$2" > /tmp/"$tmp_uuid"/img.source
|
||||
bocker_init /tmp/"$tmp_uuid" && rm -rf /tmp/"$tmp_uuid"
|
||||
}
|
||||
function RM() {
|
||||
CHECK '' "$1"
|
||||
btrfs subvolume delete "$btrfs_path/$1" > /dev/null
|
||||
echo "Removed: $1"
|
||||
|
||||
function bocker_rm() { #HELP Delete an image or container:\nBOCKER rm <image_id or container_id>
|
||||
[[ "$(bocker_check "$1")" == 1 ]] && echo "No container named '$1' exists" && exit 1
|
||||
btrfs subvolume delete "$btrfs_path/$1" > /dev/null
|
||||
cgdelete -g "$cgroups:/$1" &> /dev/null || true
|
||||
echo "Removed: $1"
|
||||
}
|
||||
function IMAGES() {
|
||||
echo -e "IMAGE_ID"
|
||||
for img in "$btrfs_path"/img_*; do
|
||||
basename "$img"
|
||||
done
|
||||
|
||||
function bocker_images() { #HELP List images:\nBOCKER images
|
||||
echo -e "IMAGE_ID\t\tSOURCE"
|
||||
for img in "$btrfs_path"/img_*; do
|
||||
img=$(basename "$img")
|
||||
echo -e "$img\t\t$(cat "$btrfs_path/$img/img.source")"
|
||||
done
|
||||
}
|
||||
function PS() {
|
||||
echo -e "CONTAINER_ID\t\tCOMMAND"
|
||||
for ps in "$btrfs_path"/ps_*; do
|
||||
ps=$(basename "$ps")
|
||||
echo -e "$ps\t\t$(cat "$btrfs_path/$ps/$ps.cmd")"
|
||||
done
|
||||
|
||||
function bocker_ps() { #HELP List containers:\nBOCKER ps
|
||||
echo -e "CONTAINER_ID\t\tCOMMAND"
|
||||
for ps in "$btrfs_path"/ps_*; do
|
||||
ps=$(basename "$ps")
|
||||
echo -e "$ps\t\t$(cat "$btrfs_path/$ps/$ps.cmd")"
|
||||
done
|
||||
}
|
||||
function RUN() {
|
||||
CHECK 'img' "$1"
|
||||
uuid="ps_$(shuf -i 10000-99999 -n 1)"
|
||||
ip link add dev veth0_"$uuid" type veth peer name veth1_"$uuid"
|
||||
ip link set dev veth0_"$uuid" up
|
||||
ip link set veth0_"$uuid" master bridge0
|
||||
ip netns add netns_"$uuid"
|
||||
ip link set veth1_"$uuid" netns netns_"$uuid"
|
||||
ip netns exec netns_"$uuid" ip link set dev lo up
|
||||
ip netns exec netns_"$uuid" ip addr add 10.0.0.2/24 dev veth1_"$uuid"
|
||||
ip netns exec netns_"$uuid" ip link set dev veth1_"$uuid" up
|
||||
ip netns exec netns_"$uuid" ip route add default via 10.0.0.1
|
||||
btrfs subvolume snapshot "$btrfs_path/$1" "$btrfs_path/$uuid" > /dev/null
|
||||
echo 'nameserver 8.8.8.8' > "$btrfs_path/$uuid"/etc/resolv.conf
|
||||
echo "$2" > "$btrfs_path/$uuid/$uuid.cmd"
|
||||
ip netns exec netns_"$uuid" "unshare" -fp --mount-proc "chroot" \
|
||||
"$btrfs_path/$uuid" /bin/sh -c "/bin/mount -t proc proc /proc && $2" \
|
||||
2>&1 | tee "$btrfs_path/$uuid/$uuid.log" || true
|
||||
ip link del dev veth0_"$uuid"
|
||||
ip netns del netns_"$uuid"
|
||||
|
||||
function bocker_run() { #HELP Create a container:\nBOCKER run <image_id> <command>
|
||||
uuid="ps_$(shuf -i 42002-42254 -n 1)"
|
||||
[[ "$(bocker_check "$1")" == 1 ]] && echo "No image named '$1' exists" && exit 1
|
||||
[[ "$(bocker_check "$uuid")" == 0 ]] && echo "UUID conflict, retrying..." && bocker_run "$@" && return
|
||||
cmd="${@:2}" && ip="$(echo "${uuid: -3}" | sed 's/0//g')" && mac="${uuid: -3:1}:${uuid: -2}"
|
||||
ip link add dev veth0_"$uuid" type veth peer name veth1_"$uuid"
|
||||
ip link set dev veth0_"$uuid" up
|
||||
ip link set veth0_"$uuid" master bridge0
|
||||
ip netns add netns_"$uuid"
|
||||
ip link set veth1_"$uuid" netns netns_"$uuid"
|
||||
ip netns exec netns_"$uuid" ip link set dev lo up
|
||||
ip netns exec netns_"$uuid" ip link set veth1_"$uuid" address 02:42:ac:11:00"$mac"
|
||||
ip netns exec netns_"$uuid" ip addr add 10.0.0."$ip"/24 dev veth1_"$uuid"
|
||||
ip netns exec netns_"$uuid" ip link set dev veth1_"$uuid" up
|
||||
ip netns exec netns_"$uuid" ip route add default via 10.0.0.1
|
||||
btrfs subvolume snapshot "$btrfs_path/$1" "$btrfs_path/$uuid" > /dev/null
|
||||
echo 'nameserver 8.8.8.8' > "$btrfs_path/$uuid"/etc/resolv.conf
|
||||
echo "$cmd" > "$btrfs_path/$uuid/$uuid.cmd"
|
||||
cgcreate -g "$cgroups:/$uuid"
|
||||
: "${BOCKER_CPU_SHARE:=512}" && cgset -r cpu.shares="$BOCKER_CPU_SHARE" "$uuid"
|
||||
: "${BOCKER_MEM_LIMIT:=512}" && cgset -r memory.limit_in_bytes="$((BOCKER_MEM_LIMIT * 1000000))" "$uuid"
|
||||
cgexec -g "$cgroups:$uuid" \
|
||||
ip netns exec netns_"$uuid" \
|
||||
unshare -fmuip --mount-proc \
|
||||
chroot "$btrfs_path/$uuid" \
|
||||
/bin/sh -c "/bin/mount -t proc proc /proc && $cmd" \
|
||||
2>&1 | tee "$btrfs_path/$uuid/$uuid.log" || true
|
||||
ip link del dev veth0_"$uuid"
|
||||
ip netns del netns_"$uuid"
|
||||
}
|
||||
function LOGS() {
|
||||
CHECK 'ps' "$1"
|
||||
cat "$btrfs_path/$1/$1.log"
|
||||
|
||||
function bocker_exec() { #HELP Execute a command in a running container:\nBOCKER exec <container_id> <command>
|
||||
[[ "$(bocker_check "$1")" == 1 ]] && echo "No container named '$1' exists" && exit 1
|
||||
cid="$(ps o ppid,pid | grep "^$(ps o pid,cmd | grep -E "^\ *[0-9]+ unshare.*$1" | awk '{print $1}')" | awk '{print $2}')"
|
||||
[[ ! "$cid" =~ ^\ *[0-9]+$ ]] && echo "Container '$1' exists but is not running" && exit 1
|
||||
nsenter -t "$cid" -m -u -i -n -p chroot "$btrfs_path/$1" "${@:2}"
|
||||
}
|
||||
function COMMIT() {
|
||||
CHECK 'ps' "$1" && CHECK 'img' "$2" && RM "$2"
|
||||
btrfs subvolume snapshot "$btrfs_path/$1" "$btrfs_path/$2" > /dev/null
|
||||
echo "Created: $2"
|
||||
|
||||
function bocker_logs() { #HELP View logs from a container:\nBOCKER logs <container_id>
|
||||
[[ "$(bocker_check "$1")" == 1 ]] && echo "No container named '$1' exists" && exit 1
|
||||
cat "$btrfs_path/$1/$1.log"
|
||||
}
|
||||
function HELP() {
|
||||
echo -e "Create an image: \n\t./bocker init <image_directory>\n"
|
||||
echo -e "List images: \n\t./bocker images\n"
|
||||
echo -e "Create a container: \n\t./bocker run <image_id> <command>\n"
|
||||
echo -e "List containers: \n\t./bocker ps\n"
|
||||
echo -e "View logs from a container: \n\t./bocker logs <container_id>\n"
|
||||
echo -e "Delete an image or container: \n\t./bocker rm <image_or_container_id>"
|
||||
exit 0
|
||||
|
||||
function bocker_commit() { #HELP Commit a container to an image:\nBOCKER commit <container_id> <image_id>
|
||||
[[ "$(bocker_check "$1")" == 1 ]] && echo "No container named '$1' exists" && exit 1
|
||||
[[ "$(bocker_check "$2")" == 1 ]] && echo "No image named '$2' exists" && exit 1
|
||||
bocker_rm "$2" && btrfs subvolume snapshot "$btrfs_path/$1" "$btrfs_path/$2" > /dev/null
|
||||
echo "Created: $2"
|
||||
}
|
||||
[[ -z "${1-}" ]] && HELP
|
||||
|
||||
function bocker_help() { #HELP Display this message:\nBOCKER help
|
||||
sed -n "s/^.*#HELP\\s//p;" < "$1" | sed "s/\\\\n/\n\t/g;s/$/\n/;s!BOCKER!${1/!/\\!}!g"
|
||||
}
|
||||
|
||||
[[ -z "${1-}" ]] && bocker_help "$0"
|
||||
case $1 in
|
||||
init) INIT "$2" ;;
|
||||
rm) RM "$2" ;;
|
||||
images) IMAGES ;;
|
||||
ps) PS ;;
|
||||
run)
|
||||
IMAGE="$2"
|
||||
shift && shift
|
||||
RUN "$IMAGE" "$*"
|
||||
;;
|
||||
logs) LOGS "$2" ;;
|
||||
commit) COMMIT "$2" "$3" ;;
|
||||
*) HELP ;;
|
||||
pull|init|rm|images|ps|run|exec|logs|commit) bocker_"$1" "${@:2}" ;;
|
||||
*) bocker_help "$0" ;;
|
||||
esac
|
||||
|
||||
15
test
Executable file
15
test
Executable file
@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
exit_code=0
|
||||
for t in tests/test_*; do
|
||||
bash tests/teardown > /dev/null 2>&1
|
||||
bash "$t" > /dev/null 2>&1
|
||||
if [[ $? == 0 ]]; then
|
||||
echo -e "\e[1;32mPASSED\e[0m : $t"
|
||||
else
|
||||
echo -e "\e[1;31mFAILED\e[0m : $t"
|
||||
exit_code=1
|
||||
fi
|
||||
bash tests/teardown > /dev/null 2>&1
|
||||
done
|
||||
exit "$exit_code"
|
||||
10
tests/teardown
Normal file
10
tests/teardown
Normal file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
for img in $(./bocker images | grep 'img' | awk '{print $1}'); do
|
||||
./bocker rm "$img"
|
||||
done
|
||||
|
||||
for ps in $(./bocker ps | grep 'ps' | awk '{print $1}'); do
|
||||
./bocker rm "$ps"
|
||||
done
|
||||
21
tests/test_commit
Normal file
21
tests/test_commit
Normal file
@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
img="$(./bocker init ~/base-image | awk '{print $2}')"
|
||||
./bocker images | grep -qw "$img"
|
||||
[[ "$?" == 0 ]]
|
||||
|
||||
./bocker run "$img" which wget
|
||||
ps="$(./bocker ps | grep 'which wget' | awk '{print $1}')"
|
||||
logs="$(./bocker logs "$ps")"
|
||||
./bocker rm "$ps"
|
||||
[[ "$logs" == "which: no wget in"* ]]
|
||||
|
||||
./bocker run "$img" yum install -y wget
|
||||
ps="$(./bocker ps | grep 'yum install -y wget' | awk '{print $1}')"
|
||||
./bocker commit "$ps" "$img"
|
||||
|
||||
./bocker run "$img" which wget
|
||||
ps="$(./bocker ps | grep 'which wget' | awk '{print $1}')"
|
||||
logs="$(./bocker logs "$ps")"
|
||||
[[ "$logs" == '/usr/bin/wget' ]]
|
||||
23
tests/test_exec
Normal file
23
tests/test_exec
Normal file
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
img="$(./bocker init ~/base-image | awk '{print $2}')"
|
||||
./bocker images | grep -qw "$img"
|
||||
[[ "$?" == 0 ]]
|
||||
|
||||
# ▼ ▼ ▼ Race condition waiting to happen ▼ ▼ ▼
|
||||
./bocker run "$img" "sleep 5 && ps aux" &
|
||||
sleep 2
|
||||
ps="$(./bocker ps | grep 'sleep 5' | awk '{print $1}')"
|
||||
exec="$(./bocker exec "$ps" ps aux | wc -l)"
|
||||
[[ "$exec" == "4" ]]
|
||||
sleep 3
|
||||
# ▲ ▲ ▲ Race condition waiting to happen ▲ ▲ ▲
|
||||
|
||||
./bocker run "$img" ps aux
|
||||
ps="$(./bocker ps | grep 'ps aux' | awk '{print $1}')"
|
||||
exec="$(./bocker exec "$ps" ps aux)" || true
|
||||
[[ "$exec" == "Container '$ps' exists but is not running" ]]
|
||||
|
||||
exec="$(./bocker exec foo ps aux)" || true
|
||||
[[ "$exec" == "No container named 'foo' exists" ]]
|
||||
4
tests/test_images
Normal file
4
tests/test_images
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
[[ "$(./bocker images | head -n 1)" == 'IMAGE_ID SOURCE' ]]
|
||||
4
tests/test_init
Normal file
4
tests/test_init
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
[[ "$(./bocker init ~/base-image)" == 'Created: img_'* ]]
|
||||
4
tests/test_ps
Normal file
4
tests/test_ps
Normal file
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
[[ "$(./bocker ps | head -n 1)" == 'CONTAINER_ID COMMAND' ]]
|
||||
16
tests/test_pull
Normal file
16
tests/test_pull
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
centos_img="$(./bocker pull centos 7 2> /dev/null | awk '{print $2}')"
|
||||
./bocker run "$centos_img" cat /etc/redhat-release
|
||||
ps="$(./bocker ps | grep 'cat /etc/redhat-release' | awk '{print $1}')"
|
||||
logs="$(./bocker logs "$ps")"
|
||||
./bocker rm "$ps"
|
||||
[[ "$logs" == "CentOS Linux release 7"* ]]
|
||||
|
||||
ubuntu_img="$(./bocker pull ubuntu 14.04 2> /dev/null | awk '{print $2}')"
|
||||
./bocker run "$ubuntu_img" tail -n1 /etc/lsb-release
|
||||
ps="$(./bocker ps | grep 'tail -n1 /etc/lsb-release' | awk '{print $1}')"
|
||||
logs="$(./bocker logs "$ps")"
|
||||
./bocker rm "$ps"
|
||||
[[ "$logs" == *"Ubuntu 14.04"* ]]
|
||||
16
tests/test_rm
Normal file
16
tests/test_rm
Normal file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
img="$(./bocker init ~/base-image | awk '{print $2}')"
|
||||
cmd="echo $RANDOM"
|
||||
./bocker run "$img" "$cmd"
|
||||
ps="$(./bocker ps | grep "$cmd" | awk '{print $1}')"
|
||||
|
||||
[[ "$(./bocker images | grep -c "$img")" == 1 ]]
|
||||
[[ "$(./bocker ps | grep -c "$cmd")" == 1 ]]
|
||||
|
||||
./bocker rm "$img"
|
||||
./bocker rm "$ps"
|
||||
|
||||
[[ "$(./bocker images | grep -c "$img")" == 0 ]]
|
||||
[[ "$(./bocker ps | grep -c "$cmd")" == 0 ]]
|
||||
24
tests/test_run
Normal file
24
tests/test_run
Normal file
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o errexit -o nounset -o pipefail
|
||||
|
||||
function bocker_run_test() {
|
||||
./bocker run "$1" "$2" > /dev/null
|
||||
ps="$(./bocker ps | grep "$2" | awk '{print $1}')"
|
||||
logs="$(./bocker logs "$ps")"
|
||||
if [[ "$logs" == *"$3"* ]]; then
|
||||
echo 0
|
||||
else
|
||||
echo 1
|
||||
fi
|
||||
}
|
||||
|
||||
img="$(./bocker init ~/base-image | awk '{print $2}')"
|
||||
./bocker images | grep -qw "$img"
|
||||
[[ "$?" == 0 ]]
|
||||
|
||||
[[ "$(bocker_run_test "$img" 'echo foo' 'foo')" == 0 ]]
|
||||
[[ "$(bocker_run_test "$img" 'uname' 'Linux')" == 0 ]]
|
||||
[[ "$(bocker_run_test "$img" 'cat /proc/self/stat' '3 (cat)')" == 0 ]]
|
||||
[[ "$(bocker_run_test "$img" 'ip addr' 'veth1_ps_')" == 0 ]]
|
||||
[[ "$(bocker_run_test "$img" 'ping -c 1 8.8.8.8' '0% packet loss')" == 0 ]]
|
||||
[[ "$(bocker_run_test "$img" 'ping -c 1 google.com' '0% packet loss')" == 0 ]]
|
||||
Loading…
x
Reference in New Issue
Block a user