Removed ubuntu image build scripts
We moved this piece of functionality to fuel agent, so we don't need these scripts here. Partially implements: blueprint ibp-build-ubuntu-images Change-Id: I4a0036959cfbdff7df4ce98373c09c0acf216b08
This commit is contained in:
parent
533d172201
commit
843b2b62b3
|
@ -52,7 +52,6 @@ CENTOS_REPO_ART_NAME?=centos-repo.tar
|
|||
UBUNTU_REPO_ART_NAME?=ubuntu-repo.tar
|
||||
PUPPET_ART_NAME?=puppet.tgz
|
||||
OPENSTACK_YAML_ART_NAME?=openstack.yaml
|
||||
TARGET_UBUNTU_IMG_ART_NAME?=ubuntu_target_images.tar
|
||||
TARGET_CENTOS_IMG_ART_NAME?=centos_target_images.tar
|
||||
|
||||
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import subprocess
|
||||
import sys
|
||||
import urlparse
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
TRUSTY_PACKAGES = [
|
||||
"bash-completion",
|
||||
"curl",
|
||||
"daemonize",
|
||||
"build-essential",
|
||||
"gdisk",
|
||||
"grub-pc",
|
||||
"linux-firmware",
|
||||
"linux-firmware-nonfree",
|
||||
"linux-image-generic-lts-trusty",
|
||||
"linux-headers-generic-lts-trusty",
|
||||
"lvm2",
|
||||
"mdadm",
|
||||
"nailgun-agent",
|
||||
"nailgun-mcagents",
|
||||
"nailgun-net-check",
|
||||
"ntp",
|
||||
"openssh-client",
|
||||
"openssh-server",
|
||||
"telnet",
|
||||
"ubuntu-minimal",
|
||||
"ubuntu-standard",
|
||||
"virt-what",
|
||||
"acl",
|
||||
"anacron",
|
||||
"bridge-utils",
|
||||
"bsdmainutils",
|
||||
"cloud-init",
|
||||
"debconf-utils",
|
||||
"ruby-augeas",
|
||||
"ruby-shadow",
|
||||
"ruby-json",
|
||||
"mcollective",
|
||||
"puppet",
|
||||
"python-amqp",
|
||||
"ruby-ipaddress",
|
||||
"ruby-netaddr",
|
||||
"ruby-openstack",
|
||||
"ruby-stomp",
|
||||
"vim",
|
||||
"vlan",
|
||||
"uuid-runtime",
|
||||
]
|
||||
|
||||
LOG = logging.getLogger()
|
||||
LOG.setLevel(logging.INFO)
|
||||
LOG.addHandler(logging.StreamHandler(sys.stderr))
|
||||
|
||||
|
||||
def execute(*cmd, **kwargs):
|
||||
command = ' '.join(cmd)
|
||||
LOG.debug('Trying to execute command: %s', command)
|
||||
commands = [c.strip() for c in re.split(ur'\|', command)]
|
||||
check_exit_code = kwargs.pop('check_exit_code', [0])
|
||||
ignore_exit_code = False
|
||||
to_filename = kwargs.get('to_filename')
|
||||
cwd = kwargs.get('cwd')
|
||||
|
||||
if isinstance(check_exit_code, bool):
|
||||
ignore_exit_code = not check_exit_code
|
||||
check_exit_code = [0]
|
||||
elif isinstance(check_exit_code, int):
|
||||
check_exit_code = [check_exit_code]
|
||||
|
||||
to_file = None
|
||||
if to_filename:
|
||||
to_file = open(to_filename, 'wb')
|
||||
|
||||
process = []
|
||||
for c in commands:
|
||||
try:
|
||||
# NOTE(eli): Python's shlex implementation doesn't like unicode.
|
||||
# We have to convert to ascii before shlex'ing the command.
|
||||
# http://bugs.python.org/issue6988
|
||||
encoded_command = c.encode('ascii')
|
||||
|
||||
process.append(subprocess.Popen(
|
||||
shlex.split(encoded_command),
|
||||
stdin=(process[-1].stdout if process else None),
|
||||
stdout=(to_file
|
||||
if (len(process) == len(commands) - 1) and to_file
|
||||
else subprocess.PIPE),
|
||||
stderr=(subprocess.PIPE),
|
||||
cwd=cwd
|
||||
))
|
||||
except OSError as e:
|
||||
raise Exception("Couldn't execute cmd=%s, err=%s" % (command, e))
|
||||
if len(process) >= 2:
|
||||
process[-2].stdout.close()
|
||||
stdout, stderr = process[-1].communicate()
|
||||
return (stdout, stderr, process[-1].returncode)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("json_data", help='JSON encoded string')
|
||||
return parser
|
||||
|
||||
|
||||
def expose_env_params(json_data=None):
|
||||
if not json_data:
|
||||
json_data = {}
|
||||
os.environ["UBUNTU_MAJOR"] = json_data.get('ubuntu_major', '12')
|
||||
os.environ["UBUNTU_MINOR"] = json_data.get('ubuntu_minor', '04')
|
||||
os.environ["UBUNTU_ARCH"] = json_data.get('ubuntu_arch', 'amd64')
|
||||
os.environ["UBUNTU_RELEASE"] = json_data.get('codename', 'precise')
|
||||
os.environ["UBUNTU_KERNEL_FLAVOR"] = json_data.get('ubuntu_kernel_flavor',
|
||||
'lts-trusty')
|
||||
os.environ["DST_DIR"] = json_data.get('output', '/tmp/image')
|
||||
if 'image_data' in json_data:
|
||||
os.environ["SEPARATE_FS_IMAGES"] = " ".join(
|
||||
["%s,%s" % (k, v['format'])
|
||||
for k, v in json_data['image_data'].items()])
|
||||
os.environ["SEPARATE_FS_IMAGES_NAMES"] = " ".join(
|
||||
["%s,%s" % (k, os.path.basename(urlparse.urlsplit(v['uri'])[2]))
|
||||
for k, v in json_data['image_data'].items()])
|
||||
else:
|
||||
raise Exception("Couldn't find any information about images")
|
||||
|
||||
if 'repos' in json_data:
|
||||
os.environ["UBUNTU_MIRRORS"] = ",".join([
|
||||
"%s|%s|%s|%s" % (
|
||||
repo['suite'], repo.get('section', ''), repo['priority'], repo['uri'])
|
||||
for repo in json_data['repos']])
|
||||
else:
|
||||
raise Exception("Couldn't find any information about repos")
|
||||
|
||||
if 'repos' in json_data:
|
||||
os.environ["UBUNTU_BASE_MIRROR"] = ",".join([
|
||||
"%s|%s|%s|%s" % (
|
||||
repo['suite'], repo.get('section', ''), repo['priority'], repo['uri'])
|
||||
for repo in json_data['repos'][:1]])
|
||||
else:
|
||||
raise Exception("Couldn't find any information about repos")
|
||||
#FIXME(agordeev): get rid of hardcoded ubuntu release name
|
||||
if os.environ['UBUNTU_RELEASE'] == 'trusty':
|
||||
os.environ["INSTALL_PACKAGES"] = " ".join(TRUSTY_PACKAGES)
|
||||
if 'packages' in json_data:
|
||||
os.environ["INSTALL_PACKAGES"] = " ".join(json_data['packages'])
|
||||
|
||||
|
||||
def create_yaml_profile(json_data):
|
||||
data = []
|
||||
filename = None
|
||||
if 'image_data' in json_data:
|
||||
for k, v in json_data['image_data'].items():
|
||||
filename = os.path.basename(urlparse.urlsplit(v['uri'])[2])
|
||||
abs_path = os.path.join(json_data['output'], filename)
|
||||
stdout = execute('gunzip', '-ql', abs_path)[0]
|
||||
try:
|
||||
size = int(stdout.split()[1])
|
||||
except (ValueError, KeyError) as e:
|
||||
size = None
|
||||
stdout = execute('gunzip', '-qc', abs_path, '|', 'md5sum')[0]
|
||||
try:
|
||||
md5 = stdout.split()[0]
|
||||
except (ValueError, KeyError) as e:
|
||||
md5 = None
|
||||
if not md5 or not size:
|
||||
raise Exception("Either md5 or size of %s couldn't be "
|
||||
"calculated" % abs_path)
|
||||
data.append({k: {
|
||||
'md5': md5,
|
||||
'size': size,
|
||||
'filename': filename,
|
||||
'container': v['container'],
|
||||
'format': v['format']}})
|
||||
data.append({'repos': json_data['repos']})
|
||||
else:
|
||||
raise Exception("Couldn't find any information about images")
|
||||
filename = os.path.basename(
|
||||
urlparse.urlsplit(json_data['image_data']
|
||||
['/']['uri'])[2]).split('.')[0]
|
||||
with open(os.path.join(json_data['output'], filename + '.yaml'), 'w') as f:
|
||||
f.write(yaml.dump(data))
|
||||
|
||||
|
||||
def check_images_do_not_exist(json_data):
|
||||
if 'image_data' in json_data:
|
||||
for k, v in json_data['image_data'].items():
|
||||
filename = os.path.basename(
|
||||
urlparse.urlsplit(v['uri'])[2])
|
||||
if not os.path.exists(os.path.join(json_data['output'], filename)):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main():
|
||||
parser = parse_args()
|
||||
params, other_params = parser.parse_known_args()
|
||||
try:
|
||||
json_data = json.loads(params.json_data)
|
||||
except ValueError as exc:
|
||||
print "Can't decode json data"
|
||||
#FIXME: do logging
|
||||
sys.exit(-1)
|
||||
else:
|
||||
expose_env_params(json_data)
|
||||
if check_images_do_not_exist(json_data):
|
||||
(stdout, stderr, ret_code) = execute('bash', '-x',
|
||||
'create_separate_images.sh')
|
||||
if ret_code == 0:
|
||||
create_yaml_profile(json_data)
|
||||
#FIXME: do logging
|
||||
print stdout
|
||||
print stderr
|
||||
sys.exit(ret_code)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
|
@ -1,488 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
#NOTE: seems like XFS support won't be implemented due to:
|
||||
# 1) built-in aggressive pre-allocation which's consuming free space and
|
||||
# making impossible to determine the correct size of file system image
|
||||
# 2) missing fs shrinking method, so only re-creation is possible
|
||||
# 3) xfsdump/xfsrestore sometimes fails, due to 1) making 2) to fail too
|
||||
|
||||
function die_ret { echo "$@" 1>&2 ; return 1; }
|
||||
function die { echo "$@" 1>&2 ; exit 1; }
|
||||
|
||||
SEPARATE_FS_IMAGES=${SEPARATE_FS_IMAGES:-"/boot,ext2 /,ext4"}
|
||||
|
||||
declare -A MOUNT_DICT
|
||||
declare -a LOOP_DEVICES_LIST
|
||||
for ent in $(echo "$SEPARATE_FS_IMAGES"| tr ' ' '\n'); do
|
||||
# expecting '<mountpoint>,<fs_type>'
|
||||
arrEnt=(${ent//,/ })
|
||||
MOUNT_DICT[${arrEnt[0]}]=${arrEnt[1]}
|
||||
done
|
||||
|
||||
declare -A IMAGES_NAMES_DICT
|
||||
|
||||
for ent in $(echo "$SEPARATE_FS_IMAGES_NAMES"| tr ' ' '\n'); do
|
||||
# expecting '<mountpoint>,<image_name>'
|
||||
arrEnt=(${ent//,/ })
|
||||
IMAGES_NAMES_DICT[${arrEnt[0]}]=${arrEnt[1]}
|
||||
done
|
||||
|
||||
# sort by mount points, eg. / -> /boot -> /var -> /var/lib
|
||||
MOUNTPOINTS=( $(
|
||||
for el in "${!MOUNT_DICT[@]}"
|
||||
do
|
||||
echo "$el"
|
||||
done | sort) )
|
||||
|
||||
# create additional loop_devices
|
||||
FUEL_DEVICE_PREFIX=loop
|
||||
MAX_DOWNLOAD_ATTEMPTS=${MAX_DOWNLOAD_ATTEMPTS:-10}
|
||||
UBUNTU_MAJOR=${UBUNTU_MAJOR:-12}
|
||||
UBUNTU_MINOR=${UBUNTU_MINOR:-04}
|
||||
UBUNTU_ARCH=${UBUNTU_ARCH:-amd64}
|
||||
UBUNTU_RELEASE=${UBUNTU_RELEASE:-precise}
|
||||
TMP_BUILD_DIR=`mktemp -d`
|
||||
echo "${TMP_BUILD_DIR} is used as temprorary directory for building images"
|
||||
TMP_BUILD_IMG_DIR=${TMP_BUILD_IMG_DIR:-$TMP_BUILD_DIR/imgs}
|
||||
TMP_CHROOT_DIR=${TMP_CHROOT_DIR:-$TMP_BUILD_DIR/chroot}
|
||||
BASE_MIRROR_URL=$(echo "$UBUNTU_BASE_MIRROR" | cut -d '|' -f4-)
|
||||
DST_DIR=${DST_DIR:-/var/www/nailgun}
|
||||
SPARSE_FILE_INITIAL_SIZE=2G
|
||||
SPARSE_IMG_FILE_SUFFIX=sparse_img
|
||||
IMG_ENDING=img
|
||||
IMG_PREFIX=${IMG_PREFIX:-ubuntu}
|
||||
if [ -z "$IMG_SUFFIX" ]; then
|
||||
IMG_SUFFIX="${UBUNTU_MAJOR}${UBUNTU_MINOR}_${UBUNTU_ARCH}"
|
||||
fi
|
||||
LOOP_DEVICES_MAJOR=7
|
||||
LOOP_DEVICES_MINOR_INITIAL=10
|
||||
DEBOOTSTRAP_PARAMS=${DEBOOTSTRAP_PARAMS:-"--no-check-gpg --arch=$UBUNTU_ARCH $UBUNTU_RELEASE $TMP_CHROOT_DIR"}
|
||||
UBUNTU_KERNEL_FLAVOR=${UBUNTU_KERNEL_FLAVOR:-lts-trusty}
|
||||
INSTALL_PACKAGES=${INSTALL_PACKAGES:-"
|
||||
bash-completion
|
||||
curl
|
||||
daemonize
|
||||
build-essential
|
||||
gdisk
|
||||
grub-pc
|
||||
linux-firmware
|
||||
linux-firmware-nonfree
|
||||
linux-image-generic-$UBUNTU_KERNEL_FLAVOR
|
||||
linux-headers-generic-$UBUNTU_KERNEL_FLAVOR
|
||||
lvm2
|
||||
mdadm
|
||||
nailgun-agent
|
||||
nailgun-mcagents
|
||||
nailgun-net-check
|
||||
ntp
|
||||
openssh-client
|
||||
openssh-server
|
||||
telnet
|
||||
ubuntu-minimal
|
||||
ubuntu-standard
|
||||
virt-what
|
||||
acl
|
||||
anacron
|
||||
bridge-utils
|
||||
bsdmainutils
|
||||
cloud-init
|
||||
debconf-utils
|
||||
libaugeas-ruby
|
||||
libstomp-ruby1.8
|
||||
libshadow-ruby1.8
|
||||
libjson-ruby1.8
|
||||
mcollective
|
||||
puppet
|
||||
python-amqp
|
||||
ruby-ipaddress
|
||||
ruby-netaddr
|
||||
ruby-openstack
|
||||
ruby-stomp
|
||||
vim
|
||||
vlan
|
||||
uuid-runtime"}
|
||||
|
||||
|
||||
function make_dirs {
|
||||
if [ ! -d "$TMP_BUILD_DIR" ]; then
|
||||
mkdir -p "$TMP_BUILD_DIR" || die_ret "Couldn't create directory"
|
||||
fi
|
||||
|
||||
if [ ! -d "$TMP_BUILD_IMG_DIR" ]; then
|
||||
mkdir -p "$TMP_BUILD_IMG_DIR" || die_ret "Couldn't create directory"
|
||||
fi
|
||||
|
||||
if [ ! -d "$TMP_CHROOT_DIR" ]; then
|
||||
mkdir -p "$TMP_CHROOT_DIR" || die_ret "Couldn't create directory"
|
||||
fi
|
||||
|
||||
if [ ! -d "$DST_DIR" ]; then
|
||||
mkdir -p "$DST_DIR" || die_ret "Couldn't create directory"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function delete_dirs {
|
||||
if [ -d "$TMP_CHROOT_DIR" ]; then
|
||||
rm -fr "$TMP_CHROOT_DIR" || die_ret "Couldn't delete directory"
|
||||
fi
|
||||
|
||||
if [ -d "$TMP_BUILD_IMG_DIR" ]; then
|
||||
rm -fr "$TMP_BUILD_IMG_DIR" || die_ret "Couldn't delete directory"
|
||||
fi
|
||||
|
||||
if [ -d "$TMP_BUILD_DIR" ]; then
|
||||
rm -fr "$TMP_BUILD_DIR" || die_ret "Couldn't delete directory"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
function cleanup {
|
||||
clean_chroot
|
||||
if mountpoint -q ${TMP_CHROOT_DIR}/proc; then
|
||||
umount -l ${TMP_CHROOT_DIR}/proc || true
|
||||
fi
|
||||
|
||||
for idx in $(seq $((${#MOUNTPOINTS[@]} - 1)) -1 0); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
if [ ${#LOOP_DEVICES_LIST[@]} -gt 0 ]; then
|
||||
LOOP_DEV=${LOOP_DEVICES_LIST[$idx]}
|
||||
if ! umount_try_harder "${TMP_CHROOT_DIR}${MOUNT_POINT}"; then
|
||||
umount -l "${TMP_CHROOT_DIR}${MOUNT_POINT}" || die_ret "Failed to umount $LOOP_DEV (${TMP_CHROOT_DIR}${MOUNT_POINT})"
|
||||
fi
|
||||
if ! losetup -d "$LOOP_DEV"; then
|
||||
echo "Warning: unable to detach loop device $LOOP_DEV"
|
||||
fi
|
||||
fi
|
||||
if [ -e "$SPARSE_FILE_NAME" ]; then
|
||||
rm -f ${SPARSE_FILE_NAME} || die_ret "Couldn't remove old sparce image"
|
||||
fi
|
||||
done
|
||||
delete_dirs || die_ret "Couldn't remove dirs"
|
||||
return 0
|
||||
}
|
||||
|
||||
function precreate_loop_devices {
|
||||
for x in $(seq 0 7); do
|
||||
local loop_dev=/dev/${FUEL_DEVICE_PREFIX}${x}
|
||||
if [ ! -e "$loop_dev" ]; then
|
||||
mknod -m 660 ${loop_dev} b ${LOOP_DEVICES_MAJOR} ${x} || die_ret "Couldn't create loop-device file"
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function allocate_loop_device {
|
||||
local sparse_file="$1"
|
||||
local loop_count=8
|
||||
local max_loop_count=255
|
||||
local loop_dev=''
|
||||
while [ -z "$loop_dev" ]; do
|
||||
for minor in `seq 0 $loop_count`; do
|
||||
local cur_loop="/dev/${FUEL_DEVICE_PREFIX}${minor}"
|
||||
[ -b "$cur_loop" ] || mknod -m 660 "$cur_loop" b $LOOP_DEVICES_MAJOR $minor
|
||||
done
|
||||
[ $loop_count -ge $max_loop_count ] && die_ret "too many loopback devices"
|
||||
loop_count=$((loop_count*2))
|
||||
loop_dev=`losetup --find`
|
||||
done
|
||||
LOOP_DEVICES_LIST+=(${loop_dev})
|
||||
losetup ${loop_dev} ${sparse_file} || die_ret "Couldn't associate loop-device file"
|
||||
return 0
|
||||
}
|
||||
|
||||
function create_loop_device_and_makefs {
|
||||
for idx in $(seq 0 $((${#MOUNTPOINTS[@]} - 1)) ); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
|
||||
truncate -s ${SPARSE_FILE_INITIAL_SIZE} ${SPARSE_FILE_NAME} || die_ret "Couldn't create sparse file"
|
||||
|
||||
allocate_loop_device ${SPARSE_FILE_NAME} || die_ret "Couldn't allocate loop-device file"
|
||||
|
||||
LOOP_DEV=${LOOP_DEVICES_LIST[$idx]}
|
||||
|
||||
FS_TYPE=${MOUNT_DICT[$MOUNT_POINT]}
|
||||
if [ "$FS_TYPE" == "ext2" ]; then
|
||||
mkfs.ext2 -F ${LOOP_DEV} || die_ret "Couldn't create filesystem"
|
||||
elif [ "$FS_TYPE" == "ext3" ]; then
|
||||
mkfs.ext3 -F ${LOOP_DEV} || die_ret "Couldn't create filesystem"
|
||||
elif [ "$FS_TYPE" == "ext4" ]; then
|
||||
mkfs.ext4 -F ${LOOP_DEV} || die_ret "Couldn't create filesystem"
|
||||
else
|
||||
echo "Unsupported fs type $FS_TYPE. Exitting now!"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function do_mounts {
|
||||
for idx in $(seq 0 $((${#MOUNTPOINTS[@]} - 1)) ); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
LOOP_DEV=${LOOP_DEVICES_LIST[$idx]}
|
||||
mkdir -p ${TMP_CHROOT_DIR}${MOUNT_POINT} || die_ret "Could create directory"
|
||||
mount ${LOOP_DEV} ${TMP_CHROOT_DIR}${MOUNT_POINT} || die_ret "Couldn't mount mountpoint"
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function debootstap_download_packages_try_harder {
|
||||
local attempt=0
|
||||
local max_attempts=$MAX_DOWNLOAD_ATTEMPTS
|
||||
|
||||
while true; do
|
||||
if [ $attempt -ge $max_attempts ]; then
|
||||
return 1
|
||||
fi
|
||||
debootstrap --download-only --verbose $DEBOOTSTRAP_PARAMS $BASE_MIRROR_URL
|
||||
if [ $? -ne 0 ]; then
|
||||
sleep 1
|
||||
attempt=$((attempt+1))
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function suppress_udev_start {
|
||||
# inhibit service startup in the chroot
|
||||
# do this *before* running deboostrap to suppress udev start
|
||||
# (by its postinst script)
|
||||
mkdir -p ${TMP_CHROOT_DIR}/usr/sbin
|
||||
cat > policy-rc.d << EOF
|
||||
#!/bin/sh
|
||||
# prevent any service from being started
|
||||
exit 101
|
||||
EOF
|
||||
chmod 755 policy-rc.d
|
||||
cp policy-rc.d ${TMP_CHROOT_DIR}/usr/sbin
|
||||
}
|
||||
|
||||
function install_base_system {
|
||||
debootstap_download_packages_try_harder || die_ret "Couldn't retreive packages for debootstrap"
|
||||
|
||||
#FIXME(agordeev): deboostrap will fetch mirror info despite the fact
|
||||
# that all needed packages were downloaded earlier
|
||||
debootstrap $DEBOOTSTRAP_PARAMS $BASE_MIRROR_URL || die_ret "Couldn't finish debootstrap successfully"
|
||||
}
|
||||
|
||||
function apt_get_download_try_harder {
|
||||
local attempt=0
|
||||
local max_attempts=$MAX_DOWNLOAD_ATTEMPTS
|
||||
|
||||
while true; do
|
||||
if [ $attempt -ge $max_attempts ]; then
|
||||
return 1
|
||||
fi
|
||||
chroot ${TMP_CHROOT_DIR} \
|
||||
env DEBIAN_FRONTEND=noninteractive \
|
||||
DEBCONF_NONINTERACTIVE_SEEN=true \
|
||||
LC_ALL=C LANG=C LANGUAGE=C \
|
||||
apt-get -y -d install ${INSTALL_PACKAGES}
|
||||
if [ $? -ne 0 ]; then
|
||||
sleep 1
|
||||
attempt=$((attempt+1))
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function setup_apt_mirrors {
|
||||
rm -f ${TMP_CHROOT_DIR}/etc/apt/sources.list
|
||||
rm -f ${TMP_CHROOT_DIR}/etc/apt/preferences
|
||||
IFS=','
|
||||
set -- $UBUNTU_MIRRORS
|
||||
unset IFS
|
||||
for ent; do
|
||||
# expecting 'suite|section|priority|uri'
|
||||
IFS='|'
|
||||
set -- $ent
|
||||
unset IFS
|
||||
local suite="$1"
|
||||
local section="$2"
|
||||
local priority="$3"
|
||||
shift; shift; shift
|
||||
local uri="$@"
|
||||
if [ -n "$section" ]; then
|
||||
echo "deb ${uri} ${suite} ${section}" >> "${TMP_CHROOT_DIR}/etc/apt/sources.list"
|
||||
if [ "$priority" != "None" ]; then
|
||||
for sec in $section; do
|
||||
cat >> ${TMP_CHROOT_DIR}/etc/apt/preferences <<-EOF
|
||||
Package: *
|
||||
Pin: release a=${suite},c=${sec}
|
||||
Pin-Priority: ${priority}
|
||||
|
||||
EOF
|
||||
done
|
||||
fi
|
||||
else
|
||||
echo "deb ${uri} ${suite}" >> "${TMP_CHROOT_DIR}/etc/apt/sources.list"
|
||||
if [ "$priority" != "None" ]; then
|
||||
cat >> ${TMP_CHROOT_DIR}/etc/apt/preferences <<-EOF
|
||||
Package: *
|
||||
Pin: release a=${suite}
|
||||
Pin-Priority: ${priority}
|
||||
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function install_by_apt {
|
||||
echo 'APT::Get::AllowUnauthenticated 1;' | tee ${TMP_CHROOT_DIR}/etc/apt/apt.conf.d/02mirantis-unauthenticated
|
||||
|
||||
setup_apt_mirrors || die_ret "Couldn't set up ubuntu mirrors"
|
||||
|
||||
#FIXME:do retry for apt-get update?
|
||||
chroot ${TMP_CHROOT_DIR} apt-get update || die_ret "Couldn't update packages list from sources"
|
||||
if ! mountpoint -q ${TMP_CHROOT_DIR}/proc; then
|
||||
mount -t proc proc ${TMP_CHROOT_DIR}/proc
|
||||
fi
|
||||
apt_get_download_try_harder || die_ret "Couldn't retreive packages for apt-get install"
|
||||
|
||||
chroot ${TMP_CHROOT_DIR} \
|
||||
env DEBIAN_FRONTEND=noninteractive \
|
||||
DEBCONF_NONINTERACTIVE_SEEN=true \
|
||||
LC_ALL=C LANG=C LANGUAGE=C \
|
||||
apt-get -y install ${INSTALL_PACKAGES} || die_ret "Couldn't install the rest of packages successfully"
|
||||
}
|
||||
|
||||
function do_post_inst {
|
||||
#inject hardcoded root password `r00tme`
|
||||
sed -i 's%root:[\*,\!]%root:$6$IInX3Cqo$5xytL1VZbZTusOewFnG6couuF0Ia61yS3rbC6P5YbZP2TYclwHqMq9e3Tg8rvQxhxSlBXP1DZhdUamxdOBXK0.%' ${TMP_CHROOT_DIR}/etc/shadow
|
||||
|
||||
#cloud-init reconfigure to use NoCloud data source
|
||||
echo "cloud-init cloud-init/datasources multiselect NoCloud, None" | chroot ${TMP_CHROOT_DIR} debconf-set-selections -v
|
||||
chroot ${TMP_CHROOT_DIR} dpkg-reconfigure -f noninteractive cloud-init
|
||||
|
||||
# re-enable services
|
||||
rm -f ${TMP_CHROOT_DIR}/usr/sbin/policy-rc.d
|
||||
# clean apt settings
|
||||
rm -f ${TMP_CHROOT_DIR}/etc/apt/sources.list
|
||||
rm -f ${TMP_CHROOT_DIR}/etc/apt/preferences
|
||||
}
|
||||
|
||||
# kill any stray process in chroot (just in a case some sloppy postinst
|
||||
# script still hanging around)
|
||||
signal_chrooted_processes() {
|
||||
local chroot_dir="$1"
|
||||
local signal="$2"
|
||||
local proc_root
|
||||
for p in `fuser -v "$chroot_dir" 2>/dev/null`; do
|
||||
proc_root="`readlink -f /proc/$p/root || true`"
|
||||
if [ "$proc_root" = "$chroot_dir" ]; then
|
||||
kill -s "$signal" $p
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function clean_chroot {
|
||||
signal_chrooted_processes $TMP_CHROOT_DIR TERM
|
||||
sleep 1
|
||||
signal_chrooted_processes $TMP_CHROOT_DIR KILL
|
||||
|
||||
if mountpoint -q ${TMP_CHROOT_DIR}/proc; then
|
||||
umount -l ${TMP_CHROOT_DIR}/proc || true
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
umount_try_harder () {
|
||||
local abs_mount_point="$1"
|
||||
local umount_attempt=0
|
||||
local max_umount_attempts=10
|
||||
|
||||
while mountpoint -q "$abs_mount_point" && ! umount "$abs_mount_point"; do
|
||||
if [ $umount_attempt -ge $max_umount_attempts ]; then
|
||||
return 1
|
||||
fi
|
||||
signal_chrooted_processes "$abs_mount_point" KILL
|
||||
sleep 1
|
||||
umount_attempt=$((umount_attempt+1))
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
function umount_resize_images {
|
||||
for idx in $(seq $((${#MOUNTPOINTS[@]} - 1)) -1 0); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
LOOP_DEV=${LOOP_DEVICES_LIST[$idx]}
|
||||
FS_TYPE=${MOUNT_DICT[$MOUNT_POINT]}
|
||||
FINAL_IMAGE_NAME=${IMAGES_NAMES_DICT[$MOUNT_POINT]}
|
||||
if ! umount_try_harder "${TMP_CHROOT_DIR}${MOUNT_POINT}"; then
|
||||
umount -l "${TMP_CHROOT_DIR}${MOUNT_POINT}" || die_ret "Failed to umount $LOOP_DEV (${TMP_CHROOT_DIR}${MOUNT_POINT})"
|
||||
fi
|
||||
|
||||
if [ "$FS_TYPE" == "ext2" ] || [ "$FS_TYPE" == "ext3" ] || [ "$FS_TYPE" == "ext4" ]; then
|
||||
e2fsck -yf ${LOOP_DEV} || die_ret "Couldn't check filesystem"
|
||||
resize2fs -F -M ${LOOP_DEV} || die_ret "Couldn't resize filesystem"
|
||||
# calculate fs size precisely
|
||||
BLOCK_COUNT=$(dumpe2fs -h ${LOOP_DEV} | grep 'Block count' | awk '{print $3}')
|
||||
BLOCK_SIZE=$(dumpe2fs -h ${LOOP_DEV} | grep 'Block size' | awk '{print $3}')
|
||||
BLOCK_K_SIZE=$(( $BLOCK_SIZE / 1024 ))
|
||||
BLOCK_K_COUNT=$(( 1 + $BLOCK_COUNT / 1024 ))
|
||||
EXPECTED_M_SIZE=$(( $BLOCK_K_COUNT * $BLOCK_K_SIZE ))
|
||||
dd if=${LOOP_DEV} of=${IMG_FILE_NAME} bs=1M count=${EXPECTED_M_SIZE} || die_ret "Couldn't copy image"
|
||||
else
|
||||
echo "Unsupported fs type $FS_TYPE. Exitting now!"
|
||||
exit 1
|
||||
fi
|
||||
chmod a+r ${IMG_FILE_NAME} || die_ret "Couldn't grant reading access to image file"
|
||||
gzip -f ${IMG_FILE_NAME}
|
||||
mv ${IMG_FILE_NAME}.gz ${DST_DIR}/${FINAL_IMAGE_NAME}
|
||||
rm -f ${SPARSE_FILE_NAME} || die_ret "Couldn't remove sparse image file"
|
||||
done
|
||||
}
|
||||
|
||||
cleanup || die "Couldn't perform cleanup"
|
||||
|
||||
function build_images {
|
||||
make_dirs || return 1
|
||||
precreate_loop_devices || return 1
|
||||
create_loop_device_and_makefs || return 1
|
||||
do_mounts || return 1
|
||||
suppress_udev_start || return 1
|
||||
install_base_system || return 1
|
||||
#FIXME(agordeev): policy-rc.d will disappear after bootstrap exits
|
||||
suppress_udev_start || return 1
|
||||
install_by_apt || return 1
|
||||
do_post_inst || return 1
|
||||
clean_chroot || return 1
|
||||
umount_resize_images || return 1
|
||||
}
|
||||
|
||||
build_images
|
||||
if [ $? -ne 0 ]; then
|
||||
echo 'Building of images failed'
|
||||
cleanup || die_ret "Couldn't perform cleanup"
|
||||
exit 1
|
||||
else
|
||||
echo 'Building of images finished successfuly'
|
||||
cleanup || die_ret "Couldn't perform cleanup"
|
||||
exit 0
|
||||
fi
|
|
@ -1,254 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
|
||||
#NOTE: seems like XFS support won't be implemented due to:
|
||||
# 1) built-in aggressive pre-allocation which's consuming free space and
|
||||
# making impossible to determine the correct size of file system image
|
||||
# 2) missing fs shrinking method, so only re-creation is possible
|
||||
# 3) xfsdump/xfsrestore sometimes fails, due to 1) making 2) to fail too
|
||||
|
||||
function die { echo "$@" 1>&2 ; exit 1; }
|
||||
|
||||
SEPARATE_FS_IMAGES=${SEPARATE_FS_IMAGES:-"/boot,ext2 /,ext4"}
|
||||
|
||||
declare -A MOUNT_DICT
|
||||
|
||||
for ent in $(echo "$SEPARATE_FS_IMAGES"| tr ' ' '\n'); do
|
||||
# expecting '<mountpoint>,<fs_type>'
|
||||
arrEnt=(${ent//,/ })
|
||||
MOUNT_DICT[${arrEnt[0]}]=${arrEnt[1]}
|
||||
done
|
||||
|
||||
# sort by mount points, eg. / -> /boot -> /var -> /var/lib
|
||||
MOUNTPOINTS=( $(
|
||||
for el in "${!MOUNT_DICT[@]}"
|
||||
do
|
||||
echo "$el"
|
||||
done | sort) )
|
||||
|
||||
# create additional loop_devices
|
||||
FUEL_DEVICE_PREFIX=loop_devices_fuel_build
|
||||
TMP_BUILD_DIR=${TMP_BUILD_DIR:-/tmp/fuel_img}
|
||||
TMP_BUILD_IMG_DIR=${TMP_BUILD_IMG_DIR:-$TMP_BUILD_DIR/imgs}
|
||||
TMP_CHROOT_DIR=${TMP_CHROOT_DIR:-$TMP_BUILD_DIR/chroot}
|
||||
SPARSE_FILE_INITIAL_SIZE=2G
|
||||
SPARSE_IMG_FILE_SUFFIX=sparse_img
|
||||
IMG_ENDING=img
|
||||
IMG_PREFIX=${IMG_PREFIX:-ubuntu}
|
||||
if [ -z "$IMG_SUFFIX" ]; then
|
||||
IMG_SUFFIX="${UBUNTU_MAJOR}${UBUNTU_MINOR}_${UBUNTU_ARCH}"
|
||||
fi
|
||||
LOOP_DEVICES_MAJOR=7
|
||||
LOOP_DEVICES_MINOR_INITIAL=10
|
||||
LOCAL_MIRROR=${LOCAL_MIRROR:-'/tmp/mirror'}
|
||||
DEBOOTSTRAP_PARAMS=${DEBOOTSTRAP_PARAMS:-''}
|
||||
INSTALL_PACKAGES=${INSTALL_PACKAGES:-''}
|
||||
|
||||
if [ ! -d "$TMP_BUILD_DIR" ]; then
|
||||
mkdir -p "$TMP_BUILD_DIR" || die "Couldn't create directory"
|
||||
fi
|
||||
|
||||
if [ ! -d "$TMP_BUILD_IMG_DIR" ]; then
|
||||
mkdir -p "$TMP_BUILD_IMG_DIR" || die "Couldn't create directory"
|
||||
fi
|
||||
|
||||
if [ ! -d "$TMP_CHROOT_DIR" ]; then
|
||||
mkdir -p "$TMP_CHROOT_DIR" || die "Couldn't create directory"
|
||||
fi
|
||||
|
||||
# try to remove stale files and mount points
|
||||
if mount | grep -q "${TMP_CHROOT_DIR}/tmp/mirror"; then
|
||||
sudo umount ${TMP_CHROOT_DIR}/tmp/mirror
|
||||
fi
|
||||
for idx in $(seq $((${#MOUNTPOINTS[@]} - 1)) -1 0); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
LOOP_DEV=/dev/${FUEL_DEVICE_PREFIX}${idx}
|
||||
if mount | grep -q "${TMP_CHROOT_DIR}${MOUNT_POINT}"; then
|
||||
sudo umount ${TMP_CHROOT_DIR}${MOUNT_POINT}
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Couldn't umnount old loop-device file, trying to perform lazy umnount"
|
||||
sudo umount -l ${TMP_CHROOT_DIR}${MOUNT_POINT} || echo "Couldn't unmount old loop-device file"
|
||||
fi
|
||||
fi
|
||||
if [ -e "$LOOP_DEV" ]; then
|
||||
# try to remove if it exists, just dissociate first, ignore the errors.
|
||||
sudo losetup -d $LOOP_DEV
|
||||
sudo rm -f $LOOP_DEV || die "Couldn't remove old loop-device file"
|
||||
sudo rm -f ${SPARSE_FILE_NAME} || die "Could remove old sparce image"
|
||||
fi
|
||||
done
|
||||
|
||||
for idx in $(seq 0 $((${#MOUNTPOINTS[@]} - 1)) ); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
LOOP_DEV=/dev/${FUEL_DEVICE_PREFIX}${idx}
|
||||
|
||||
truncate -s ${SPARSE_FILE_INITIAL_SIZE} ${SPARSE_FILE_NAME} || die "Couldn't create sparse file"
|
||||
|
||||
# create loop device
|
||||
sudo mknod -m 660 ${LOOP_DEV} b ${LOOP_DEVICES_MAJOR} $(( $LOOP_DEVICES_MINOR_INITIAL + $idx )) || die "Couldn't create loop-device file"
|
||||
sudo losetup ${LOOP_DEV} ${SPARSE_FILE_NAME} || die "Couldn't associate loop-device file"
|
||||
|
||||
FS_TYPE=${MOUNT_DICT[$MOUNT_POINT]}
|
||||
if [ "$FS_TYPE" == "ext2" ]; then
|
||||
sudo mkfs.ext2 -F ${LOOP_DEV} || die "Couldn't create filesystem"
|
||||
elif [ "$FS_TYPE" == "ext3" ]; then
|
||||
sudo mkfs.ext3 -F ${LOOP_DEV} || die "Couldn't create filesystem"
|
||||
elif [ "$FS_TYPE" == "ext4" ]; then
|
||||
sudo mkfs.ext4 -F ${LOOP_DEV} || die "Couldn't create filesystem"
|
||||
sudo tune2fs -O ^has_journal "${LOOP_DEV}" || die "Failed to configure filesystem"
|
||||
else
|
||||
echo "Unsupported fs type $FS_TYPE. Exitting now!"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
for idx in $(seq 0 $((${#MOUNTPOINTS[@]} - 1)) ); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
LOOP_DEV=/dev/${FUEL_DEVICE_PREFIX}${idx}
|
||||
sudo mkdir -p ${TMP_CHROOT_DIR}${MOUNT_POINT} || die "Could create directory"
|
||||
sudo mount ${LOOP_DEV} ${TMP_CHROOT_DIR}${MOUNT_POINT} || die "Couldn't mount mountpoint"
|
||||
done
|
||||
|
||||
|
||||
# inhibit service startup in the chroot
|
||||
# do this *before* running deboostrap to suppress udev start
|
||||
# (by its postinst script)
|
||||
sudo mkdir -p ${TMP_CHROOT_DIR}/usr/sbin
|
||||
cat > policy-rc.d << EOF
|
||||
#!/bin/sh
|
||||
# prevent any service from being started
|
||||
exit 101
|
||||
EOF
|
||||
chmod 755 policy-rc.d
|
||||
sudo cp policy-rc.d ${TMP_CHROOT_DIR}/usr/sbin
|
||||
|
||||
# install base system
|
||||
sudo debootstrap $DEBOOTSTRAP_PARAMS || die "Couldn't finish debootstrap successfully"
|
||||
|
||||
#inject hardcoded root password `r00tme`
|
||||
sudo sed -i 's%root:[\*,\!]%root:$6$IInX3Cqo$5xytL1VZbZTusOewFnG6couuF0Ia61yS3rbC6P5YbZP2TYclwHqMq9e3Tg8rvQxhxSlBXP1DZhdUamxdOBXK0.%' ${TMP_CHROOT_DIR}/etc/shadow
|
||||
|
||||
echo 'APT::Get::AllowUnauthenticated 1;' | sudo tee ${TMP_CHROOT_DIR}/etc/apt/apt.conf.d/02mirantis-unauthenticated
|
||||
|
||||
#local mirror
|
||||
sudo mkdir -p ${TMP_CHROOT_DIR}/tmp/mirror
|
||||
sudo mount --bind ${LOCAL_MIRROR} ${TMP_CHROOT_DIR}/tmp/mirror
|
||||
sudo /bin/sh -c "echo deb file:///tmp/mirror/ubuntu ${UBUNTU_RELEASE} main > ${TMP_CHROOT_DIR}/etc/apt/sources.list"
|
||||
sudo chroot ${TMP_CHROOT_DIR} apt-get update || die "Couldn't update packages list from sources"
|
||||
if ! mountpoint -q ${TMP_CHROOT_DIR}/proc; then
|
||||
sudo mount -t proc proc ${TMP_CHROOT_DIR}/proc
|
||||
fi
|
||||
sudo chroot ${TMP_CHROOT_DIR} \
|
||||
env DEBIAN_FRONTEND=noninteractive \
|
||||
DEBCONF_NONINTERACTIVE_SEEN=true \
|
||||
LC_ALL=C LANG=C LANGUAGE=C \
|
||||
apt-get -y install ${INSTALL_PACKAGES} || die "Couldn't install the rest of packages successfully"
|
||||
sudo umount ${TMP_CHROOT_DIR}/tmp/mirror
|
||||
|
||||
#cloud-init reconfigure to use NoCloud data source
|
||||
echo "cloud-init cloud-init/datasources multiselect NoCloud, None" | sudo chroot ${TMP_CHROOT_DIR} debconf-set-selections -v
|
||||
sudo chroot ${TMP_CHROOT_DIR} dpkg-reconfigure -f noninteractive cloud-init
|
||||
|
||||
# puppet agents get automatically started in recent Ubuntu versions.
|
||||
# This confuses astute so it aborts the deployment (see
|
||||
# https://bugs.launchpad.net/mos/+bug/1385079)
|
||||
sudo chroot ${TMP_CHROOT_DIR} update-rc.d puppet disable
|
||||
|
||||
# re-enable services
|
||||
sudo rm ${TMP_CHROOT_DIR}/usr/sbin/policy-rc.d
|
||||
|
||||
# kill any stray process in chroot (just in a case some sloppy postinst
|
||||
# script still hanging around)
|
||||
signal_chrooted_processes() {
|
||||
local chroot_dir="$1"
|
||||
local signal="$2"
|
||||
local proc_root
|
||||
for p in `sudo fuser -v "$chroot_dir" 2>/dev/null`; do
|
||||
proc_root="`sudo readlink -f /proc/$p/root || true`"
|
||||
if [ "$proc_root" = "$chroot_dir" ]; then
|
||||
sudo kill -s "$signal" $p
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
signal_chrooted_processes $TMP_CHROOT_DIR TERM
|
||||
sleep 1
|
||||
signal_chrooted_processes $TMP_CHROOT_DIR KILL
|
||||
|
||||
if mountpoint -q ${TMP_CHROOT_DIR}/proc; then
|
||||
sudo umount -l ${TMP_CHROOT_DIR}/proc || true
|
||||
fi
|
||||
|
||||
umount_try_harder () {
|
||||
local abs_mount_point="$1"
|
||||
local umount_attempt=0
|
||||
local max_umount_attempts=10
|
||||
|
||||
while sudo mountpoint -q "$abs_mount_point" && ! sudo umount "$abs_mount_point"; do
|
||||
if [ $umount_attempt -ge $max_umount_attempts ]; then
|
||||
return 1
|
||||
fi
|
||||
signal_chrooted_processes "$abs_mount_point" KILL
|
||||
sleep 1
|
||||
umount_attempt=$((umount_attempt+1))
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
for idx in $(seq $((${#MOUNTPOINTS[@]} - 1)) -1 0); do
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
if [ "$MOUNT_POINT" == "/" ]; then
|
||||
MOUNT_POINT=""
|
||||
fi
|
||||
IMG_FILE_NAME=${TMP_BUILD_IMG_DIR}/${IMG_PREFIX}_${IMG_SUFFIX}$(echo $MOUNT_POINT | tr '/' '-').${IMG_ENDING}
|
||||
MOUNT_POINT=${MOUNTPOINTS[$idx]}
|
||||
SPARSE_FILE_NAME=${IMG_FILE_NAME}.${SPARSE_IMG_FILE_SUFFIX}
|
||||
LOOP_DEV=/dev/${FUEL_DEVICE_PREFIX}${idx}
|
||||
FS_TYPE=${MOUNT_DICT[$MOUNT_POINT]}
|
||||
|
||||
if ! umount_try_harder "${TMP_CHROOT_DIR}${MOUNT_POINT}"; then
|
||||
die "Failed to umount $LOOP_DEV (${TMP_CHROOT_DIR}${MOUNT_POINT})"
|
||||
fi
|
||||
|
||||
if [ "$FS_TYPE" == "ext2" ] || [ "$FS_TYPE" == "ext3" ] || [ "$FS_TYPE" == "ext4" ]; then
|
||||
sudo e2fsck -yf ${LOOP_DEV} || die "Couldn't check filesystem"
|
||||
case "$FS_TYPE" in
|
||||
ext4)
|
||||
if ! sudo tune2fs -O has_journal "${LOOP_DEV}"; then
|
||||
die "Re-adding journal for ext4 filesystem on ${LOOP_DEV}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
sudo resize2fs -M ${LOOP_DEV} || die "Couldn't resize filesystem"
|
||||
# calculate fs size precisely
|
||||
BLOCK_COUNT=$(sudo dumpe2fs -h ${LOOP_DEV} | grep 'Block count' | awk '{print $3}')
|
||||
BLOCK_SIZE=$(sudo dumpe2fs -h ${LOOP_DEV} | grep 'Block size' | awk '{print $3}')
|
||||
BLOCK_K_SIZE=$(( $BLOCK_SIZE / 1024 ))
|
||||
BLOCK_K_COUNT=$(( 1 + $BLOCK_COUNT / 1024 ))
|
||||
EXPECTED_M_SIZE=$(( $BLOCK_K_COUNT * $BLOCK_K_SIZE ))
|
||||
sudo dd if=${LOOP_DEV} of=${IMG_FILE_NAME} bs=1M count=${EXPECTED_M_SIZE} || die "Couldn't copy image"
|
||||
else
|
||||
echo "Unsupported fs type $FS_TYPE. Exitting now!"
|
||||
exit 1
|
||||
fi
|
||||
sudo chmod a+r ${IMG_FILE_NAME} || die "Couldn't grant reading access to image file"
|
||||
python ./image/ubuntu/add_image_to_profile.py --filename $(basename $IMG_FILE_NAME).gz --format ${FS_TYPE} --container gzip --mountpoint ${MOUNT_POINT} -O ${TMP_BUILD_IMG_DIR}/profile.yaml
|
||||
sudo losetup -d ${LOOP_DEV} || die "Couldn't dissociate loop-device file"
|
||||
sudo rm -f ${LOOP_DEV} || die "Couldn't remove loop-device file"
|
||||
rm ${SPARSE_FILE_NAME} || die "Couldn't remove sparse image file"
|
||||
done
|
|
@ -1,108 +0,0 @@
|
|||
.PHONY: target_ubuntu_image clean_ubuntu_image clean
|
||||
|
||||
target_ubuntu_image: $(ARTS_DIR)/$(TARGET_UBUNTU_IMG_ART_NAME)
|
||||
|
||||
clean: clean_ubuntu_image
|
||||
|
||||
clean_ubuntu_image:
|
||||
-for p in `sudo fuser -v $(TMP_CHROOT) 2>/dev/null`; do \
|
||||
if [ "`sudo readlink -f /proc/$$p/root`" = "$(TMP_CHROOT)" ]; then \
|
||||
sudo kill -s KILL $$p; \
|
||||
fi; \
|
||||
done
|
||||
-sudo umount $(TMP_CHROOT)/tmp/mirror
|
||||
-sudo umount $(TMP_CHROOT)/proc
|
||||
-sudo umount $(TMP_CHROOT)/dev
|
||||
-sudo umount $(TMP_CHROOT)/sys
|
||||
-sudo umount $(TMP_CHROOT)/boot
|
||||
-sudo umount $(TMP_CHROOT)
|
||||
sudo rm -rf $(TMP_CHROOT)
|
||||
sudo rm -rf $(BUILD_DIR)/image/ubuntu
|
||||
sudo rm -f $(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME)
|
||||
sudo rm -f $(ARTS_DIR)/$(TARGET_UBUNTU_IMG_ART_NAME)
|
||||
|
||||
$(ARTS_DIR)/$(TARGET_UBUNTU_IMG_ART_NAME): $(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME)
|
||||
$(ACTION.COPY)
|
||||
|
||||
TARGET_UBUNTU_DEP_FILE:=$(call find-files,$(DEPS_DIR_CURRENT)/$(TARGET_UBUNTU_IMG_ART_NAME))
|
||||
|
||||
#NOTE: ubuntu-minimal package depends on: adduser apt apt-utils bzip2 console-setup
|
||||
# debconf debconf-i18n eject gnupg ifupdown initramfs-tools iproute iputils-ping
|
||||
# isc-dhcp-client kbd less locales lsb-release makedev mawk module-init-tools
|
||||
# net-tools netbase netcat-openbsd ntpdate passwd procps python resolvconf
|
||||
# rsyslog sudo tzdata ubuntu-keyring udev upstart ureadahead vim-tiny whiptail
|
||||
|
||||
comma:=,
|
||||
space:=
|
||||
space+=
|
||||
|
||||
PKGS_APTGET:=\
|
||||
bash-completion\
|
||||
curl\
|
||||
daemonize\
|
||||
build-essential\
|
||||
gdisk\
|
||||
grub-pc\
|
||||
linux-firmware\
|
||||
linux-firmware-nonfree\
|
||||
linux-image-generic-$(UBUNTU_KERNEL_FLAVOR)\
|
||||
linux-headers-generic-$(UBUNTU_KERNEL_FLAVOR)\
|
||||
lvm2\
|
||||
mdadm\
|
||||
nailgun-agent\
|
||||
nailgun-mcagents\
|
||||
nailgun-net-check\
|
||||
ntp\
|
||||
openssh-client\
|
||||
openssh-server\
|
||||
telnet\
|
||||
ubuntu-minimal\
|
||||
ubuntu-standard\
|
||||
virt-what\
|
||||
acl\
|
||||
anacron\
|
||||
bridge-utils\
|
||||
bsdmainutils\
|
||||
cloud-init\
|
||||
debconf-utils\
|
||||
mcollective\
|
||||
puppet\
|
||||
python-amqp\
|
||||
ruby-ipaddress\
|
||||
ruby-json\
|
||||
ruby-netaddr\
|
||||
ruby-openstack\
|
||||
ruby-shadow\
|
||||
ruby-stomp\
|
||||
vim\
|
||||
vlan\
|
||||
uuid-runtime
|
||||
|
||||
TMP_CHROOT:=$(BUILD_DIR)/image/tmp/ubuntu_chroot
|
||||
|
||||
ifdef TARGET_UBUNTU_DEP_FILE
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): $(TARGET_UBUNTU_DEP_FILE)
|
||||
$(ACTION.COPY)
|
||||
else
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): $(BUILD_DIR)/mirror/ubuntu/build.done
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): $(BUILD_DIR)/packages/deb/build.done
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export SEPARATE_FS_IMAGES=$(SEPARATE_IMAGES)
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export TMP_BUILD_DIR=$(BUILD_DIR)/image/tmp
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export TMP_BUILD_IMG_DIR=$(BUILD_DIR)/image/ubuntu
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export TMP_CHROOT_DIR=$(TMP_CHROOT)
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export IMG_SUFFIX=$(UBUNTU_IMAGE_RELEASE)_$(UBUNTU_ARCH)
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export DEBOOTSTRAP_PARAMS=--no-check-gpg --arch=$(UBUNTU_ARCH) $(UBUNTU_RELEASE) $(TMP_CHROOT) file://$(LOCAL_MIRROR)/ubuntu
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME): export INSTALL_PACKAGES=$(PKGS_APTGET)
|
||||
$(BUILD_DIR)/images/$(TARGET_UBUNTU_IMG_ART_NAME):
|
||||
@mkdir -p $(@D)
|
||||
mkdir -p $(BUILD_DIR)/image/ubuntu
|
||||
touch $(BUILD_DIR)/image/ubuntu/profile.yaml
|
||||
env LOCAL_MIRROR=$(LOCAL_MIRROR) \
|
||||
UBUNTU_MAJOR=$(UBUNTU_MAJOR) \
|
||||
UBUNTU_MINOR=$(UBUNTU_MINOR) \
|
||||
UBUNTU_ARCH=$(UBUNTU_ARCH) \
|
||||
UBUNTU_RELEASE=$(UBUNTU_RELEASE) \
|
||||
$(SOURCE_DIR)/image/ubuntu/create_separate_images.sh
|
||||
find $(BUILD_DIR)/image/ubuntu -name '*img' -exec gzip -f {} \;
|
||||
tar cf $@ -C $(BUILD_DIR)/image/ubuntu .
|
||||
endif
|
|
@ -1,62 +1,13 @@
|
|||
#TEMP fixme
|
||||
%define repo_name fuel-main
|
||||
|
||||
%define name fuel-image
|
||||
%define name fuel
|
||||
%{!?version: %define version 7.0.0}
|
||||
%{!?release: %define release 1}
|
||||
|
||||
Summary: Fuel-image package
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
URL: http://mirantis.com
|
||||
Source0: %{repo_name}-%{version}.tar.gz
|
||||
License: Apache
|
||||
Group: Development/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
|
||||
Prefix: %{_prefix}
|
||||
BuildRequires: python-setuptools
|
||||
BuildRequires: python-pbr
|
||||
BuildArch: noarch
|
||||
|
||||
Requires: python
|
||||
Requires: PyYAML
|
||||
Requires: python-argparse
|
||||
Requires: gzip
|
||||
Requires: bzip2
|
||||
Requires: debootstrap
|
||||
Requires: e2fsprogs
|
||||
Requires: util-linux-ng
|
||||
Requires: coreutils
|
||||
Requires: xz
|
||||
|
||||
%description
|
||||
Fuel-image package
|
||||
|
||||
%prep
|
||||
%setup -cq -n %{name}-%{version}
|
||||
%build
|
||||
|
||||
%install
|
||||
install -p -D -m 755 %{_builddir}/%{name}-%{version}/image/ubuntu/build_on_masternode/build_ubuntu_image.py %{buildroot}%{_bindir}/build_ubuntu_image.py
|
||||
install -p -D -m 755 %{_builddir}/%{name}-%{version}/image/ubuntu/build_on_masternode/create_separate_images.sh %{buildroot}%{_bindir}/create_separate_images.sh
|
||||
|
||||
%post
|
||||
ln -s %{_bindir}/build_ubuntu_image.py %{_bindir}/fuel-image
|
||||
|
||||
%postun
|
||||
rm -f %{_bindir}/fuel-image
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/build_ubuntu_image.py
|
||||
%{_bindir}/create_separate_images.sh
|
||||
|
||||
%package -n fuel
|
||||
Summary: Fuel for OpenStack
|
||||
URL: http://mirantis.com
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
License: Apache
|
||||
|
@ -75,9 +26,9 @@ Requires: nailgun-net-check >= %{version}
|
|||
Requires: python-fuelclient >= %{version}
|
||||
Requires: yum
|
||||
|
||||
%description -n fuel
|
||||
Fuel for OpenStack is a lifecycle management utility for
|
||||
%description
|
||||
Fuel for OpenStack is a lifecycle management utility for
|
||||
managing OpenStack.
|
||||
|
||||
%files -n fuel
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
|
|
Loading…
Reference in New Issue