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:
Vladimir Kozhukalov 2015-07-15 17:07:34 +03:00
parent 533d172201
commit 843b2b62b3
6 changed files with 5 additions and 1144 deletions

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)