Skip to content

Commit 4ccd771

Browse files
authored
Merge pull request kata-containers#30 from harche/image_size
scripts: Add an "auto-size" feature
2 parents 0532e91 + 5fe3f4a commit 4ccd771

File tree

1 file changed

+122
-45
lines changed

1 file changed

+122
-45
lines changed

image-builder/image_builder.sh

Lines changed: 122 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,26 @@ info()
3636
echo "INFO: ${msg}"
3737
}
3838

39+
warning()
40+
{
41+
local msg="$*"
42+
echo "WARNING: ${msg}"
43+
}
44+
3945
usage()
4046
{
4147
error="${1:-0}"
4248
cat <<EOT
4349
Usage: ${SCRIPT_NAME} [options] <rootfs-dir>
44-
This script will create a Kata Containers image file based on the
45-
<rootfs-dir> directory.
50+
This script will create a Kata Containers image file of
51+
an adequate size based on the <rootfs-dir> directory.
52+
The size of the image can be also be specified manually
53+
by '-s' flag.
4654
4755
Options:
4856
-h Show this help
4957
-o path to generate image file ENV: IMAGE
50-
-s Image size in MB (default $IMG_SIZE) ENV: IMG_SIZE
58+
-s Image size in MB ENV: IMG_SIZE
5159
5260
Extra environment variables:
5361
AGENT_BIN: use it to change the expected agent binary name"
@@ -57,12 +65,32 @@ EOT
5765
exit "${error}"
5866
}
5967

60-
while getopts "ho:s:" opt
68+
# Maximum allowed size in MB for root disk
69+
MAX_IMG_SIZE_MB=2048
70+
71+
FS_TYPE=${FS_TYPE:-"ext4"}
72+
73+
# In order to support memory hotplug, image must be aligned to 128M
74+
MEM_BOUNDARY=128
75+
76+
# Maximum no of attempts to create a root disk before giving up
77+
MAX_ATTEMPTS=5
78+
79+
ATTEMPT_NUM=0
80+
while getopts "ho:s:f:" opt
6181
do
6282
case "$opt" in
6383
h) usage ;;
6484
o) IMAGE="${OPTARG}" ;;
65-
s) IMG_SIZE="${OPTARG}" ;;
85+
s) IMG_SIZE=${OPTARG}
86+
if [ ${IMG_SIZE} -lt 0 ]; then
87+
die "Image size has to be greater than 0 MB."
88+
fi
89+
if [ ${IMG_SIZE} -gt ${MAX_IMG_SIZE_MB} ]; then
90+
die "Image size should not be greater than ${MAX_IMG_SIZE_MB} MB."
91+
fi
92+
;;
93+
f) FS_TYPE="${OPTARG}" ;;
6694
esac
6795
done
6896

@@ -113,55 +141,104 @@ OK "init is installed"
113141
OK "Agent installed"
114142
[ "$(id -u)" -eq 0 ] || die "$0: must be run as root"
115143

144+
ROOTFS_SIZE=$(du -B 1MB -s "${ROOTFS}" | awk '{print $1}')
116145
BLOCK_SIZE=${BLOCK_SIZE:-4096}
117-
IMG_SIZE=${IMG_SIZE:-80}
118-
119-
info "Creating raw disk with size ${IMG_SIZE}M"
120-
qemu-img create -q -f raw "${IMAGE}" "${IMG_SIZE}M"
121-
OK "Image file created"
146+
OLD_IMG_SIZE=0
122147

123-
# Kata runtime expect an image with just one partition
124-
# The partition is the rootfs content
125-
126-
info "Creating partitions"
127-
parted "${IMAGE}" --script "mklabel gpt" \
128-
"mkpart ext4 1M -1M"
129-
OK "Partitions created"
130-
131-
# Get the loop device bound to the image file (requires /dev mounted in the
132-
# image build system and root privileges)
133-
DEVICE=$(losetup -P -f --show "${IMAGE}")
148+
align_memory()
149+
{
150+
remaining=$(($IMG_SIZE % $MEM_BOUNDARY))
151+
if [ "$remaining" != "0" ];then
152+
warning "image size '$IMG_SIZE' is not aligned to memory boundary '$MEM_BOUNDARY', aligning it"
153+
IMG_SIZE=$(($IMG_SIZE + $MEM_BOUNDARY - $remaining))
154+
fi
155+
}
134156

135-
#Refresh partition table
136-
partprobe "${DEVICE}"
157+
# Calculate image size based on the rootfs
158+
calculate_img_size()
159+
{
160+
IMG_SIZE=${IMG_SIZE:-$MEM_BOUNDARY}
161+
align_memory
162+
}
137163

138-
MOUNT_DIR=$(mktemp -d osbuilder-mount-dir.XXXX)
139-
info "Formating Image using ext4 format"
140-
mkfs.ext4 -q -F -b "${BLOCK_SIZE}" "${DEVICE}p1"
141-
OK "Image formated"
164+
# Cleanup
165+
cleanup()
166+
{
167+
sync
168+
umount -l ${MOUNT_DIR}
169+
rmdir ${MOUNT_DIR}
170+
fsck -D -y "${DEVICE}p1"
171+
losetup -d "${DEVICE}"
172+
}
142173

143-
info "Mounting root paratition"
144-
mount "${DEVICE}p1" "${MOUNT_DIR}"
145-
OK "root paratition mounted"
174+
create_rootfs_disk()
175+
{
176+
ATTEMPT_NUM=$(($ATTEMPT_NUM+1))
177+
info "Create root disk image. Attempt ${ATTEMPT_NUM} out of ${MAX_ATTEMPTS}."
178+
if [ ${ATTEMPT_NUM} -gt ${MAX_ATTEMPTS} ]; then
179+
die "Unable to create root disk image."
180+
fi
181+
182+
calculate_img_size
183+
if [ ${OLD_IMG_SIZE} -ne 0 ]; then
184+
info "Image size ${OLD_IMG_SIZE}MB too small, trying again with size ${IMG_SIZE}MB"
185+
fi
186+
187+
info "Creating raw disk with size ${IMG_SIZE}M"
188+
qemu-img create -q -f raw "${IMAGE}" "${IMG_SIZE}M"
189+
OK "Image file created"
190+
191+
# Kata runtime expect an image with just one partition
192+
# The partition is the rootfs content
193+
194+
info "Creating partitions"
195+
parted "${IMAGE}" --script "mklabel gpt" \
196+
"mkpart ${FS_TYPE} 1M -1M"
197+
OK "Partitions created"
198+
199+
# Get the loop device bound to the image file (requires /dev mounted in the
200+
# image build system and root privileges)
201+
DEVICE=$(losetup -P -f --show "${IMAGE}")
202+
203+
#Refresh partition table
204+
partprobe "${DEVICE}"
205+
206+
MOUNT_DIR=$(mktemp -d osbuilder-mount-dir.XXXX)
207+
info "Formating Image using ext4 format"
208+
mkfs.ext4 -q -F -b "${BLOCK_SIZE}" "${DEVICE}p1"
209+
OK "Image formated"
210+
211+
info "Mounting root paratition"
212+
mount "${DEVICE}p1" "${MOUNT_DIR}"
213+
OK "root paratition mounted"
214+
RESERVED_BLOCKS_PERCENTAGE=3
215+
info "Set filesystem reserved blocks percentage to ${RESERVED_BLOCKS_PERCENTAGE}%"
216+
tune2fs -m "${RESERVED_BLOCKS_PERCENTAGE}" "${DEVICE}p1"
217+
218+
AVAIL_DISK=$(df -B M --output=avail "${DEVICE}p1" | tail -1)
219+
AVAIL_DISK=${AVAIL_DISK/M}
220+
info "Free space root partition ${AVAIL_DISK} MB"
221+
222+
# if the available disk space is less than rootfs size, repeat the process
223+
# of disk creation by adding 5% in the inital assumed value $ROOTFS_SIZE
224+
if [ $ROOTFS_SIZE -gt $AVAIL_DISK ]; then
225+
# Increase the size but remain aligned to 128
226+
MEM_BOUNDARY=$(($MEM_BOUNDARY+128))
227+
rm -f ${IMAGE}
228+
OLD_IMG_SIZE=${IMG_SIZE}
229+
unset IMG_SIZE
230+
cleanup
231+
create_rootfs_disk
232+
fi
233+
}
146234

147-
RESERVED_BLOCKS_PERCENTAGE=3
148-
info "Set filesystem reserved blocks percentage to ${RESERVED_BLOCKS_PERCENTAGE}%"
149-
tune2fs -m "${RESERVED_BLOCKS_PERCENTAGE}" "${DEVICE}p1"
235+
create_rootfs_disk
150236

151-
#TODO: Calculate disk size based on rootfs
152-
#FIXME: https://github.com/kata-containers/osbuilder/issues/2
153-
ROOTFS_SIZE=$(du -B 1MB -s "${ROOTFS}" | awk '{print $1}')
154-
AVAIL_DISK=$(df -B M --output=avail "${DEVICE}p1" | tail -1)
155-
AVAIL_DISK=${AVAIL_DISK/M}
156-
info "Free space root partition ${AVAIL_DISK} MB"
157237
info "rootfs size ${ROOTFS_SIZE} MB"
158238
info "Copying content from rootfs to root partition"
159239
cp -a "${ROOTFS}"/* ${MOUNT_DIR}
160240
OK "rootfs copied"
161241

162-
# Cleanup
163-
sync
164-
umount -l ${MOUNT_DIR}
165-
fsck -D -y "${DEVICE}p1"
166-
losetup -d "${DEVICE}"
167-
info "Image created"
242+
cleanup
243+
244+
info "Image created. Size: ${IMG_SIZE}MB."

0 commit comments

Comments
 (0)