diff options
author | Jonas Bjurel <jonas.bjurel@ericsson.com> | 2015-11-25 11:32:57 +0100 |
---|---|---|
committer | Jonas Bjurel <jonas.bjurel@ericsson.com> | 2015-11-27 10:24:23 +0100 |
commit | 24a95306d2564b272b5320e9149d9aea70b4061c (patch) | |
tree | 8c1a2c9f7acbfed41f8ebc56a8ae1f7d316f7cff /build | |
parent | 7077376d6e0ff0dec77080fa21b75911b811475d (diff) |
Restructcture of the directory layout
Restructure of the directory layout due to move of Fuel into it's own repo
JIRA: FUEL-85
Change-Id: I3647e1992a508f29dce06a5d6c790725c527f6f5
Signed-off-by: Jonas Bjurel <jonas.bjurel@ericsson.com>
Diffstat (limited to 'build')
61 files changed, 4436 insertions, 0 deletions
diff --git a/build/Makefile b/build/Makefile new file mode 100644 index 000000000..6e7041dc0 --- /dev/null +++ b/build/Makefile @@ -0,0 +1,197 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +SHELL = /bin/bash + +# This file will be created if needed by runcontext to contain proxy +# settings. +-include environment.mk + +############################################################################ +# BEGIN of variables to customize +# +#Input args +export ISOSRC = file:$(shell pwd)/fuel-7.0.iso +export ISOCACHE = $(shell pwd)/$(shell basename $(ISOSRC)) +export PRODNO = "OPNFV_BGS" +export REVSTATE = "P0000" +export NEWISO = $(shell pwd)/release/opnfv-${REVSTATE}.iso + +# Note! Invoke with "make REVSTATE=RXXXX all" to make release build! +# Invoke with ICOCACHE=/full/path/to/iso if cached ISO is in non-standard location. + +# Build variables +export BUILD_BASE := $(shell pwd) +export DEB_DEST := $(BUILD_BASE)/release/packages/ubuntu/pool/main +export UDEB_DEST := $(BUILD_BASE)/release/packages/ubuntu/pool/debian-installer +export PUPPET_DEST := $(BUILD_BASE)/release/puppet/modules +export VERSION_FILE := $(BUILD_BASE)/.versions +export DOCKERIMG = opnfv.org/ubuntu-builder:14.04 +export TOPDIR := $(shell pwd) +export REPOINFO := $(BUILD_BASE)/repo_info.sh + +#Build subclasses + +SUBDIRS := f_isoroot + +# f_example is only an example of how to generate a .deb package and +# should not be enabled in official builds. +#SUBDIRS += f_example + +ORIGDIR := $(TOPDIR)/origiso +# +# END of variables to customize +############################################################################# + +SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) + +.PHONY: all +all: + @docker version >/dev/null 2>&1 || (echo 'No Docker installation available'; exit 1) + @make -C docker + @docker/runcontext $(DOCKERIMG) $(MAKE) $(MAKEFLAGS) iso + + +############################################################################ +# BEGIN of Include definitions +# +include config.mk +include cache.mk +# +# END Include definitions +############################################################################# + +$(ISOCACHE): + # Clone Fuel to non-persistent location and build + if [ ! -d /tmp/fuel-main ]; then \ + cd /tmp && git clone $(FUEL_MAIN_REPO); \ + fi + cd /tmp/fuel-main && git checkout $(FUEL_MAIN_TAG) + @echo "fuel" `git -C /tmp/fuel-main show | grep commit | head -1 | cut -d " " -f2` >> $(VERSION_FILE) + # Setup cgroups for docker-in-docker + sudo /root/enable_dockerx2 + # Patch for adding dosfstools, as Fuel 6.1 is running mkfs.vfat + cd /tmp/fuel-main && patch -p0 < $(TOPDIR)/fuel-main_5.patch + # Patch for changing the second layer Docker --bip address + cd /tmp/fuel-main && patch -p0 < $(TOPDIR)/fuel-main_6.patch + # Remove Docker optimizations, otherwise multistrap will fail during + # Fuel build. + sudo rm -f /etc/apt/apt.conf.d/docker* + # + cd /tmp/fuel-main && ./prepare-build-env.sh + cd /tmp/fuel-main && make repos + $(REPOINFO) -r /tmp/fuel-main > gitinfo_fuel.txt + # + cd /tmp/fuel-main && sudo make iso + cp /tmp/fuel-main/build/artifacts/fuel*.iso . + +.PHONY: mount-origiso umount-origiso +mount-origiso: $(ISOCACHE) + @echo "Mounting original ISO in $(ORIGDIR)" + @mkdir -p $(ORIGDIR) + @fuseiso $(ISOCACHE) $(ORIGDIR) + +umount-origiso: + @echo "Unmounting original ISO from $(ORIGDIR)" + @fusermount -u $(ORIGDIR) + @rmdir $(ORIGDIR) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + @mkdir -p release/packages/ubuntu/pool/main release/packages/ubuntu/pool/debian-installer release/puppet/modules release/isoroot + $(MAKE) -C $@ -f Makefile release + +.PHONY: patch-packages +patch-packages: + ORIGISO=$(ISOCACHE) REVSTATE=$(REVSTATE) $(MAKE) -C $@ -f Makefile release + +.PHONY: clean $(SUBCLEAN) +clean: $(SUBCLEAN) + $(MAKE) -C patch-packages -f Makefile clean + @rm -f *.iso + @rm -Rf release + @rm -Rf newiso + @rm -Rf .versions + @rm -f $(NEWISO) + @rm -f $(BUILD_BASE)/gitinfo_*.txt + +.PHONY: deepclean +deepclean: clean clean-cache + make -C docker clean + docker rmi opnfv.org/ubuntu-builder:14.04 &>/dev/null || exit 0 + docker rmi opnfv.org/ubuntu-builder:latest &>/dev/null || exit 0 + docker rmi ubuntu:14.04 &>/dev/null || exit 0 + @if docker images | grep -q "ubuntu *14.04"; then \ + echo "Error: ubuntu:14.04 still present!"; \ + exit 1; \ + fi + @if docker images | grep -q "opnfv.org/ubuntu-builder"; then \ + echo "Error: opnfv.org/ubuntu-builder still present!"; \ + exit 1; \ + fi + +$(SUBCLEAN): %.clean: + $(MAKE) -C $* -f Makefile clean + +.PHONY: setup-env +setup-env: + @if [ -f environment.mk ]; then \ + sudo bash -c "cat environment.mk >> /etc/environment"; \ + fi + +# Todo: Make things smarter - we shouldn't need to clean everything +# betwen make invocations. +.PHONY: iso +iso: setup-env $(ISOCACHE) $(SUBDIRS) patch-packages + $(REPOINFO) . > gitinfo_main.txt + install/install.sh iso $(ISOCACHE) $(NEWISO) $(PRODNO) $(REVSTATE) + @printf "\n\nProduct ISO is $(NEWISO)\n\n" + +# Start a bash shell in docker for Makefile debugging +.PHONY: debug +debug: + @docker version >/dev/null 2>&1 || (echo 'No Docker installation available'; exit 1) + @make -C docker + docker/runcontext $(DOCKERIMG) debug + +############################################################################# +# Cache operations - only used when building through ci/build.sh +############################################################################# + +# Create a unique hash to be used for getting and putting cache, based on: +# - The commit ID of the full Fuel repo structre +# - The contents of all local Fuel patches +.cacheid: + cd /tmp && git clone $(FUEL_MAIN_REPO) + cd /tmp/fuel-main && git checkout $(FUEL_MAIN_TAG) + cd /tmp/fuel-main && make repos + $(REPOINFO) -r /tmp/fuel-main > .cachedata + sha1sum fuel-main*.patch >> .cachedata + cat .cachedata | $(CACHETOOL) getid > .cacheid + # Not removing fuel-main as it is re-used in build + +# Clean local data related to caching - called prior to ordinary build +.PHONY: clean-cache +clean-cache: $(SUBCLEANCACHE) + rm -f .cachedata .cacheid + +# Try to download cache - called prior to ordinary build +.PHONY: get-cache +get-cache: .cacheid + @if $(CACHETOOL) check $(shell cat .cacheid); then \ + $(CACHETOOL) get $(shell cat .cacheid) | tar xf -;\ + else \ + exit 0;\ + fi + +# Store cache if not already stored - called after ordinary build +.PHONY: put-cache +put-cache: .cacheid + @tar cf - fuel*.iso gitinfo_fuel.txt | $(CACHETOOL) put $(shell cat .cacheid) diff --git a/build/README b/build/README new file mode 100644 index 000000000..a6e15694c --- /dev/null +++ b/build/README @@ -0,0 +1,22 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This purpose of this framework is to: + +1) Build fuel baseline from upstream OpenStack Fuel repos (builds in a docker container to isolate dependencies from host + and full re-producability) +2) Apply arbitrary changes to the fuel baseline, consistent and non volatile: + - Add arbitrary packages with puppet modules for install and config. to be applied on controllers as well as computes. + - Change any stack-, or other pack config. using puppet + - Apply patches to the baseline. + - Etc. +3) Re factor/rebuild the .iso image for deployment (also builds in a container, for the same reason as mentioned above) + +For detailed instructions on how to add content, configuration, build and deply - please see: DOC/ diff --git a/build/add_opnfv_packages b/build/add_opnfv_packages new file mode 100644 index 000000000..44af92ea7 --- /dev/null +++ b/build/add_opnfv_packages @@ -0,0 +1,23 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Format of this file: +# +#TEXT>old package>url for replacement package +# +# Note! No spaces! +# The TEXT can be anything it is just for information display. +# Iff the packages is new, i.e. not replacing an existing package +# the old package should be specified as NONE. +# Note! For new packages a puppet manifest must actually install it. +# Easiest is to just add it to add_packages.pp. (The same might +# of course be true for an exising package if it isn't already +# is being installed). +# diff --git a/build/apply_patches b/build/apply_patches new file mode 100644 index 000000000..6925ff6b7 --- /dev/null +++ b/build/apply_patches @@ -0,0 +1,18 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Format of this file: +# +#TR>old package>url for replacement package +# +# Note! No spaces! +# Example: +#FIX>foo_0.0.1.deb>https://example.org/foo_0.0.2.deb + diff --git a/build/cache.mk b/build/cache.mk new file mode 100644 index 000000000..f6db01797 --- /dev/null +++ b/build/cache.mk @@ -0,0 +1,55 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +############################################################################# +# Cache operations - only used when building through ci/build.sh +# +# This is the global cache implementation, providing the main target "cache" +# which is called from ci/build.sh, and recursively calling the cache +# operations clean-cache, get-cache and put-cache on all $(SUBDIRS). +############################################################################# + + +export CACHETOOL := $(BUILD_BASE)/cache.sh + +# Call sub caches +SUBGETCACHE = $(addsuffix .getcache,$(SUBDIRS)) +$(SUBGETCACHE): %.getcache: + $(MAKE) -C $* -f Makefile get-cache + +SUBPUTCACHE = $(addsuffix .putcache,$(SUBDIRS)) +$(SUBPUTCACHE): %.putcache: + $(MAKE) -C $* -f Makefile put-cache + +SUBCLEANCACHE = $(addsuffix .cleancache,$(SUBDIRS)) +$(SUBCLEANCACHE): %.cleancache: + $(MAKE) -C $* -f Makefile clean-cache + +# Overlay implementation: +# - clean +# - clean cache identities +# - get caches +# - build iso +# - store caches +.PHONY: cached-all +cached-all: clean clean-cache $(SUBCLEANCACHE) get-cache $(SUBGETCACHE) iso put-cache $(SUBPUTCACHE) + @echo "Cached build is complete" + + +# cache: The target for ci/build.sh +.PHONY: cache +cache: + @if [ -z "${CACHEBASE}" ]; then \ + echo "CACHEBASE not set, are you really building through build.sh?"; \ + exit 1; \ + fi + @docker version >/dev/null 2>&1 || (echo 'No Docker installation available'; exit 1) + @make -C docker + docker/runcontext $(DOCKERIMG) $(MAKE) $(MAKEFLAGS) cached-all diff --git a/build/cache.sh b/build/cache.sh new file mode 100755 index 000000000..c8cd1b03d --- /dev/null +++ b/build/cache.sh @@ -0,0 +1,112 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +CACHETRANSPORT=${CACHETRANSPORT:-"curl --silent"} +CACHEBASE=${CACHEBASE:-"file://${HOME}/cache"} +CACHEMAXAGE=${CACHEMAXAGE:-$[14*24*3600]} +CACHEDEBUG=${CACHEDEBUG:-1} + +debugmsg () { + if [ "$CACHEDEBUG" -eq 1 ]; then + echo "$@" >&2 + fi +} + +errormsg () { + echo "$@" >&2 +} + +# Get a SHA1 based on what's piped into the cache command +getid() { + debugmsg "Generating sha1sum" + sha1sum | sed 's/ .*//' +} + + +# Put in cache +put() { + if check $1; then + debugmsg "SHA1 $1 already in cache, skipping storage" + else + debugmsg "Storing SHA1 $1 in cache" + ${CACHETRANSPORT} -T - ${CACHEBASE}/$1.blob + echo "Expires: $[`date +"%s"` + $CACHEMAXAGE]" | ${CACHETRANSPORT} -T - ${CACHEBASE}/$1.meta + fi + exit 0 +} + +# Get from cache +get() { + local rc + + ${CACHETRANSPORT} -o - ${CACHEBASE}/$1.blob 2>/dev/null + rc=$? + + if [ $rc -eq 0 ]; then + echo "Got SHA1 $1 from cache" 2>/dev/null + else + echo "Tried to get SHA1 $1 from cache but failed" 2>/dev/null + fi + + return $? +} + +# Check if in cache +check() { + local rc + + ${CACHETRANSPORT} ${CACHEBASE}/$1.meta &>/dev/null + rc=$? + + if [ $rc -eq 0 ]; then + debugmsg "Checking for SHA1 $1 in cache and found it, rc = $rc" + else + debugmsg "Checking for SHA1 $1 in cache and failed, rc = $rc" + fi + + return $rc +} + +# Verify that SHA1 seems to be a SHA1... +validSHA1() { + if [ $(echo $1 | wc -c) -ne 41 ]; then + return 1 + else + return 0 + fi +} + +case $1 in + getid) + if [ $# -ne 1 ]; then + errormsg "No arguments can be given to getid!" + exit 1 + fi + getid + ;; + get|check|put) + if [ $# -ne 2 ]; then + errormsg "Only one argument, the SHA1 sum, can be given to getid!" + exit 1 + else + if ! validSHA1 $2; then + errormsg "Invalid SHA1 format!" + exit 1 + fi + fi + + $1 $2 + exit $rc + ;; + *) + errormsg "I only know about getid, check, get and put!" + exit 1 +esac diff --git a/build/check_dependencies.sh b/build/check_dependencies.sh new file mode 100755 index 000000000..cbcb98ab3 --- /dev/null +++ b/build/check_dependencies.sh @@ -0,0 +1,41 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Given a file as input, this script verifies that all URIs in the file can +# be fetched. + +if [ $# -ne 1 ]; then + echo "Usage: $(basename $0) <filename>" + exit 1 +fi + +if [ ! -e $1 ]; then + echo "Could not open $1" + exit 1 +fi + +echo "Checking dependencies in $1" +rc=0 +for uri in `cat $1` +do + if ! curl -sfr 0-100 $uri > /dev/null; then + echo "Failed fetching $uri" >&2 + rc=1 + fi +done + +if [ $rc -ne 0 ]; then + echo "ERROR checking dependencies in $1" +else + echo "Dependencies OK" +fi + +exit $rc diff --git a/build/config.mk b/build/config.mk new file mode 100644 index 000000000..fad4c765c --- /dev/null +++ b/build/config.mk @@ -0,0 +1,20 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +FUEL_MAIN_REPO := https://github.com/openstack/fuel-main +FUEL_MAIN_TAG = stable/7.0 + +DOCKER_REPO := http://get.docker.com/builds/Linux/x86_64 +DOCKER_TAG := docker-latest + +.PHONY: get-fuel-repo +get-fuel-repo: + @echo $(FUEL_MAIN_REPO) $(FUEL_MAIN_TAG) + diff --git a/build/docker/Dockerfile b/build/docker/Dockerfile new file mode 100644 index 000000000..f3d122db9 --- /dev/null +++ b/build/docker/Dockerfile @@ -0,0 +1,37 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +FROM ubuntu:14.04 +ENV http_proxy INSERT_HTTP_PROXY +ENV https_proxy INSERT_HTTPS_PROXY +ENV no_proxy INSERT_NO_PROXY + +RUN apt-get update +RUN apt-get install -y software-properties-common python-software-properties \ + make python-setuptools python-all dpkg-dev debhelper \ + fuseiso git genisoimage bind9-host wget curl lintian tmux lxc iptables \ + ca-certificates sudo apt-utils lsb-release dosfstools debmirror + +RUN echo "ALL ALL=NOPASSWD: ALL" > /etc/sudoers.d/open-sudo +RUN echo "Defaults env_keep += \"ftp_proxy http_proxy https_proxy no_proxy RSYNC_PROXY RSYNC_CONNECT_PROG npm_config_registry\"" > /etc/sudoers.d/keep-proxies +# Keeping PWD is needed to build as root +RUN echo "Defaults env_keep += \"PWD\"" > /etc/sudoers.d/keep-pwd +RUN chmod 0440 /etc/sudoers.d/open-sudo +RUN chmod 0440 /etc/sudoers.d/keep-proxies +RUN chmod 0440 /etc/sudoers.d/keep-pwd +RUN chmod 4755 /bin/fusermount + +ADD ./setcontext /root/setcontext +RUN chmod +x /root/setcontext +ADD ./enable_dockerx2 /root/enable_dockerx2 +RUN chmod +x /root/enable_dockerx2 + +VOLUME /var/lib/docker diff --git a/build/docker/Makefile b/build/docker/Makefile new file mode 100644 index 000000000..a2434447a --- /dev/null +++ b/build/docker/Makefile @@ -0,0 +1,33 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +SHELL = /bin/bash +FILES = $(wildcard ubuntu-builder/*) runcontext + +.PHONY: all +all: .docker + +.docker: $(FILES) + cp Dockerfile ubuntu-builder/Dockerfile + # Only add proxy ENVs where set in host - needed to pull the base Ubuntu image + test -n "${http_proxy}" && sed -i "s;INSERT_HTTP_PROXY;${http_proxy};" ubuntu-builder/Dockerfile || exit 0 + test -n "${https_proxy}" && sed -i "s;INSERT_HTTPS_PROXY;${https_proxy};" ubuntu-builder/Dockerfile || exit 0 + test -n "${no_proxy}" && sed -i "s;INSERT_NO_PROXY;${no_proxy};" ubuntu-builder/Dockerfile || exit 0 + test -n "${HTTP_PROXY}" && sed -i "s;INSERT_HTTP_PROXY;${HTTP_PROXY};" ubuntu-builder/Dockerfile || exit 0 + test -n "${HTTPS_PROXY}" && sed -i "s;INSERT_HTTPS_PROXY;${HTTPS_PROXY};" ubuntu-builder/Dockerfile || exit 0 + test -n "${NO_PROXY}" && sed -i "s;INSERT_NO_PROXY;${NO_PROXY};" ubuntu-builder/Dockerfile || exit 0 + sed -i '/INSERT_/d' ubuntu-builder/Dockerfile + /usr/bin/docker build --rm=true --no-cache=true -t opnfv.org/ubuntu-builder:14.04 ubuntu-builder + /usr/bin/docker tag -f opnfv.org/ubuntu-builder:14.04 opnfv.org/ubuntu-builder + touch .docker + +.PHONY: clean +clean: + rm -f .docker ubuntu-builder/Dockerfile diff --git a/build/docker/README b/build/docker/README new file mode 100644 index 000000000..e5ccdfab6 --- /dev/null +++ b/build/docker/README @@ -0,0 +1,25 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +The makefile on this level is used for *creating* the Docker image +used for building in Ubuntu 12.04 context. + +There are two requirements before running make on this level: + +1. You need to have Docker installed on your system + +2. If in a corporate network, make sure to have a valid DNS config in + your /etc/default/docker, e.g: + + DOCKER_OPTS=" --dns=8.8.8.8 --dns=8.8.8.4" + +The top level makefile will refer to the "runcontext" file in order to +run the build process as the current user with the current working +directory available to the container. diff --git a/build/docker/runcontext b/build/docker/runcontext new file mode 100755 index 000000000..f9065a01f --- /dev/null +++ b/build/docker/runcontext @@ -0,0 +1,124 @@ +#!/bin/bash +set -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +# + +############################################################################ +# BEGIN of Exit handlers +# + +do_exit () { + CID=`cat $CID_FILE </dev/null` + rm -f $CID_FILE + rm -rf $CONTEXT_DIR + set +e + docker kill $CID > /dev/null 2>&1 + docker rm -f $CID > /dev/null 2>&1 + docker rmi -f $IID > /dev/null 2>&1 + set -e +} + +# +# End of Exit handlers +############################################################################ + +trap do_exit SIGINT SIGTERM EXIT + +context=$1 +shift +USER_ID=`id -u` +USER=`whoami` +GROUP_ID=`id -g` + +GITROOT=`git rev-parse --show-toplevel` +CID_FILE=`mktemp -u -t runcontext.XXXXXXXXXX` +CONTEXT_DIR=`mktemp -d ${GITROOT}/.docker_contextXXXXXX` + +# If RSYNC_CONNECT_PROG is used, we need to copy all of +# the SSH structure, should one of the keys need to be +# used. +if [ -n "$RSYNC_CONNECT_PROG" -a -x $HOME/.ssh ]; then + cp -rp $HOME/.ssh $CONTEXT_DIR + rm -f $CONTEXT_DIR/.ssh/known_hosts +else + mkdir $CONTEXT_DIR/.ssh +fi + +# Disable verification of unknown keys +cat >> $CONTEXT_DIR/.ssh/config <<EOF +StrictHostKeyChecking=no +EOF + +cat > $CONTEXT_DIR/Dockerfile <<EOF +FROM $context +$(env | egrep -i 'proxy|rsync' | sed 's/^/ENV /' | sed 's/=/ /') +RUN date || date +COPY .ssh $HOME/.ssh +RUN chown -R $USER_ID:$GROUP_ID $HOME/.ssh +RUN chown -R $USER_ID:$GROUP_ID $HOME +RUN chmod 700 $HOME/.ssh +RUN /root/setcontext $USER $USER_ID $GROUP_ID $HOME +EOF + +res=`docker build -q --force-rm $CONTEXT_DIR` +IID=`echo $res | sed 's/.* //'` + +# Handle proxy settings passed to the context +if env | grep -iq .*proxy; then + envfile="$(readlink -f $(dirname $0)/..)/environment.mk" + + test -n "$HTTP_PROXY" && my_http_proxy=$HTTP_PROXY + test -n "$http_proxy" && my_http_proxy=$http_proxy + + test -n "$HTTPS_PROXY" && my_https_proxy=$HTTPS_PROXY + test -n "$https_proxy" && my_https_proxy=$https_proxy + + test -n "$NO_PROXY" && my_no_proxy=$NO_PROXY + test -n "$no_proxy" && my_no_proxy=$no_proxy + + # Make sure to add the Docker socket in no_proxy + if [ -n "$my_no_proxy" ]; then + my_no_proxy+=",/var/run/docker.sock" + else + my_no_proxy="/var/run/docker.sock" + fi + + echo "Creating $envfile" + echo "# This file is automatically generated by runcontext, do not edit!" > $envfile + test -n "$my_http_proxy" && echo "export http_proxy=$my_http_proxy" >> $envfile + test -n "$my_https_proxy" && echo "export https_proxy=$my_https_proxy" >> $envfile + test -n "$my_no_proxy" && echo "export no_proxy=$my_no_proxy" >> $envfile + test -n "$RSYNC_PROXY" && echo "export RSYNC_PROXY=$RSYNC_PROXY" >> $envfile + test -n "$RSYNC_CONNECT_PROG" && echo "export RSYNC_CONNECT_PROG=$RSYNC_CONNECT_PROG" >> $envfile + echo "export npm_config_registry=http://registry.npmjs.org/" >> $envfile +else + echo "No need to generate environment.mk" + rm -f $envfile +fi + +# Evaluate the need for bind mounting the cache directory +if [ -n "$CACHEBASE" ]; then + if echo $CACHEBASE | grep -q '^file://'; then + CACHEMOUNT="-v $(echo $CACHEBASE | sed 's;file://;;'):$(echo $CACHEBASE | sed 's;file://;;')" + fi +fi + +RUN_CONTEXT_OPT="--cidfile $CID_FILE --privileged=true --rm -e HOME=$HOME -e CACHEDEBUG -e CACHETRANSPORT -e CACHEMAXAGE -e CACHEBASE -u $USER_ID:$GROUP_ID -w $PWD -v $GITROOT:$GITROOT $CACHEMOUNT" + +# Passing "debug" puts up an interactive bash shell +if [ "$1" == "debug" ]; then + echo command: docker run ${RUN_CONTEXT_OPT} $IID bash + docker run -i -t ${RUN_CONTEXT_OPT} $IID bash +else + echo command: docker run ${RUN_CONTEXT_OPT} $IID $@ + docker run -t ${RUN_CONTEXT_OPT} $IID $@ +fi + diff --git a/build/docker/ubuntu-builder/enable_dockerx2 b/build/docker/ubuntu-builder/enable_dockerx2 new file mode 100644 index 000000000..1511c70ea --- /dev/null +++ b/build/docker/ubuntu-builder/enable_dockerx2 @@ -0,0 +1,20 @@ +#!/bin/sh +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +# +# Needed to expose underlying cgroups to container +echo "running x2" > /x2 +mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup /sys/fs/cgroup +mount -t securityfs none /sys/kernel/security + +for mnt in $(cut -d: -f2 /proc/1/cgroup); do + mkdir /sys/fs/cgroup/$mnt + mount -n -t cgroup -o $mnt cgroup /sys/fs/cgroup/$mnt +done diff --git a/build/docker/ubuntu-builder/setcontext b/build/docker/ubuntu-builder/setcontext new file mode 100755 index 000000000..bc28994a9 --- /dev/null +++ b/build/docker/ubuntu-builder/setcontext @@ -0,0 +1,20 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +# +SETUSER=$1 +SETUID=$2 +SETGID=$3 +SETHOME=$4 + +getent group $SETUSER || /usr/sbin/groupadd --gid $SETGID $SETUSER +getent passwd $SETUSER || /usr/sbin/adduser --system --uid=$SETUID --gid=$SETGID --home $SETHOME --shell /bin/bash $SETUSER +/usr/sbin/usermod -a -G fuse $SETUSER +exit 0 diff --git a/build/f_example_control_bond/Makefile b/build/f_example_control_bond/Makefile new file mode 100644 index 000000000..0949737bc --- /dev/null +++ b/build/f_example_control_bond/Makefile @@ -0,0 +1,28 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) + +.PHONY: all +all: + +.PHONY: clean +clean: + @rm -rf tmp + @rm -rf release + +.PHONY: validate-cache +validate-cache: + @echo "No cache validation schema available for $(shell pwd)" + @echo "Continuing ..." + +.PHONY: release +release: + @cp -Rvp puppet/modules/* $(PUPPET_DEST) diff --git a/build/f_example_control_bond/README b/build/f_example_control_bond/README new file mode 100644 index 000000000..4449b2ff2 --- /dev/null +++ b/build/f_example_control_bond/README @@ -0,0 +1,56 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This is an example of a modification of the bridge and bonding of interfaces. +Rationale: Fuel currently don't support bonding of the "Admin" network, which +becomes a problem if you want to co-locate the single "Admin" and the redundant +bonded "Management" network on one and the same physical network in order to minimize +number of NICs, switches and cables. +This example show how you can modify the bridge and bonding settings and scripts to +achieve co-location. Of course the FUEL GUI becomes shorted in this respect, I.e. +the "admin" and "management" network cant be dragged across the NICs in the GUI. + +The f_example_control_bond has the following structure: +. ++--------+----------+-----------+ + | | | + puppet/ Makefile README + | (this file) + | + | + modules/ + | + | + | + opnfv/ + | + +--------------+ + | | + files/ manifests/ + | | + | | + | | + control-bond control-bond.pp + +Makefile: +Invoked by the git root Makefile, copies the files up to the release build +directory. + +control-bond: +The control-bond file is the .init file orchestrating the interface-, bridge- +and bond actions required for enabling the control bond + +control-bond.pp: +The control-bond.pp is the pupet manifest orchestrating the placement and +configuration of the control-bond shell script file. + +To activate this example feature, add "SUBDIRS += f_example_control_bond" in the git root Makefile. + + diff --git a/build/f_example_control_bond/puppet/modules/opnfv/files/control-bond b/build/f_example_control_bond/puppet/modules/opnfv/files/control-bond new file mode 100644 index 000000000..bf2930d73 --- /dev/null +++ b/build/f_example_control_bond/puppet/modules/opnfv/files/control-bond @@ -0,0 +1,90 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +#!/bin/sh +### BEGIN INIT INFO +# Provides: control-bond +# Required-Start: $remote_fs $all +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Bonds eth0 and eth1 and changes bridge configuration. +### END INIT INFO + + +PATH=/sbin:/usr/sbin:/bin:/usr/bin +VSCTL=/usr/bin/ovs-vsctl +APPCTL=/usr/bin/ovs-appctl + + +add_control_bond() { + logger "Starting addition of control-bond" + $VSCTL --may-exist br-fw-admin + $VSCTL --may-exist br-mgmt + $VSCTL add-bond br-fw-admin bond-control eth0 eth1 + + $VSCTL set port br-mgmt tag=66 + $APPCTL bond/set-active-slave bond-control eth0 + + $VSCTL add-port br-fw-admin admin-to-mgmt + $VSCTL add-port br-mgmt mgmt-to-admin + $VSCTL set interface admin-to-mgmt type=patch + $VSCTL set interface mgmt-to-admin type=patch + + $VSCTL set interface admin-to-mgmt options:peer=mgmt-to-admin + $VSCTL set interface mgmt-to-admin options:peer=admin-to-mgmt + + $VSCTL set port admin-to-mgmt trunk=66 + $VSCTL set port mgmt-to-admin trunk=66 + logger "Finished addition of control-bond" +} + +status_control_bond() { + if [ ! -f $VSCTL ]; then + return 1 + else + $VSCTL show | grep -q "admin-to-mgmt" + return $? + fi +} + +case "$1" in + start) + status_control_bond + if [ $? -eq 0 ]; then + exit 0 + else + add_control_bond + fi + ;; + restart|reload|force-reload) + echo "Error: argument '$1' not supported" >&2 + exit 3 + ;; + status) + status_control_bond + if [ $? -eq 0 ]; then + echo "The control-bond is enabled" + exit 0 + else + echo "The control-bond is disabled" + exit 1 + fi + + ;; + stop) + echo "Stop is not supported" + exit 0 + ;; + *) + echo "Usage: $0 start|status" >&2 + exit 3 + ;; +esac diff --git a/build/f_example_control_bond/puppet/modules/opnfv/manifests/control-bond.pp b/build/f_example_control_bond/puppet/modules/opnfv/manifests/control-bond.pp new file mode 100644 index 000000000..22fe78171 --- /dev/null +++ b/build/f_example_control_bond/puppet/modules/opnfv/manifests/control-bond.pp @@ -0,0 +1,56 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +# Class: opnfv::control-bond +# +# Bridge control and management networks together using OVS. +# +# + +class opnfv::control-bond { + notify { '*** In Opnfv::control-bond-start ***': } + + file { "/etc/init.d/control-bond": + source => "puppet:///modules/opnfv/control-bond", + owner => 'root', + group => 'root', + mode => '0755', + notify => Service["control-bond"] + } + + + service { "control-bond": + ensure => running, + require => [ File["/etc/init.d/control-bond"], Service["openvswitch-service"] ], + } + + # Only start scripts - we don't want to bring down + # bridge during shutdown + + file { "/etc/rc2.d/S18control-bond": + ensure => 'link', + target => '/etc/init.d/control-bond', + } + + file { "/etc/rc3.d/S18control-bond": + ensure => 'link', + target => '/etc/init.d/control-bond', + } + + file { "/etc/rc4.d/S18control-bond": + ensure => 'link', + target => '/etc/init.d/control-bond', + } + + file { "/etc/rc5.d/S18control-bond": + ensure => 'link', + target => '/etc/init.d/control-bond', + } +} diff --git a/build/f_example_packadd/Makefile b/build/f_example_packadd/Makefile new file mode 100644 index 000000000..a64293dcb --- /dev/null +++ b/build/f_example_packadd/Makefile @@ -0,0 +1,42 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) +PACKAGE := foobar +VERSION := 1.0-1 +DEB_NAME := $(PACKAGE)_$(VERSION).deb + +.PHONY: all +all: release/pool/main/$(DEB_NAME) + +release/pool/main/$(DEB_NAME): + @mkdir -p tmp/src + @mkdir -p release/pool/main + @cp -r $(DEB_NAME) tmp/src + @gzip -9 tmp/src/$(DEB_NAME)/usr/share/doc/$(PACKAGE)/changelog.Debian + @fakeroot dpkg-deb --build tmp/src/$(DEB_NAME) + @lintian tmp/src/$(DEB_NAME) + @cp tmp/src/$(DEB_NAME) release/pool/main + +.PHONY: clean +clean: + @rm -rf tmp + @rm -rf release + @rm -f ../release/packages/ubuntu/pool/main/$(DEB_NAME) + +.PHONY: validate-cache +validate-cache: + @echo "No cache validation schema available for $(shell pwd)" + @echo "Continuing ..." + +.PHONY: release +release:release/pool/main/$(DEB_NAME) + @cp release/pool/main/$(DEB_NAME) $(DEB_DEST) + @cp -Rvp puppet/modules/* $(PUPPET_DEST) diff --git a/build/f_example_packadd/README b/build/f_example_packadd/README new file mode 100644 index 000000000..55fa7c1a1 --- /dev/null +++ b/build/f_example_packadd/README @@ -0,0 +1,47 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This is an example of a an addition of an arbitrary debian package: foobar +It adds the debian package foobar_1.0-1 to the fuel .iso image and deploys it +to the controllers and the computes. + +The f_example_packadd has the following structure: +. ++--------+----------+-----------+------------+ + | | | | + puppet/ Makefile README foobar_1.0-1/ + | (this file) (deb pack) + | + | + modules/ + | + | + | + opnfv/ + | + | + | + manifests/ + | + | + | + foobar.pp + +Makefile: +Invoked by the git root Makefile, based on the foobar_1.0-1 deb pack artifacts, and the pupet manifests, it builds a deb package +and adds it together with the manifest to a fuel build artifact directory, such that it eventually gets built into the new fuel .iso + +foobar_1.0-1: +Contains arbitrary debian package artifacts + +foobar.pp: +Controls the installation and configuration of foobar + +To activate this example feature, add "SUBDIRS += f_example_packadd" in the git root Makefile. diff --git a/build/f_example_packadd/foobar_1.0-1/DEBIAN/conffiles b/build/f_example_packadd/foobar_1.0-1/DEBIAN/conffiles new file mode 100644 index 000000000..bad6a0ef5 --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/DEBIAN/conffiles @@ -0,0 +1 @@ +/etc/foobar/foobar.conf diff --git a/build/f_example_packadd/foobar_1.0-1/DEBIAN/control b/build/f_example_packadd/foobar_1.0-1/DEBIAN/control new file mode 100644 index 000000000..f3f0eb603 --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/DEBIAN/control @@ -0,0 +1,10 @@ +Package: foobar +Version: 1.0-1 +Section: utils +Priority: optional +Architecture: amd64 +Depends: python2.7 +Maintainer: Main Tainer <maintainer@somwhere.org> +Description: foo bar daemon + This is a daemon for the Foobar service. + Foo is bar! diff --git a/build/f_example_packadd/foobar_1.0-1/DEBIAN/postinst b/build/f_example_packadd/foobar_1.0-1/DEBIAN/postinst new file mode 100755 index 000000000..f48f26075 --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/DEBIAN/postinst @@ -0,0 +1,2 @@ +#!/bin/bash -e +date diff --git a/build/f_example_packadd/foobar_1.0-1/etc/foobar/foobar.conf b/build/f_example_packadd/foobar_1.0-1/etc/foobar/foobar.conf new file mode 100644 index 000000000..e0eee5c7a --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/etc/foobar/foobar.conf @@ -0,0 +1,2 @@ +# Foobar config file +foo=bar diff --git a/build/f_example_packadd/foobar_1.0-1/usr/bin/foobar b/build/f_example_packadd/foobar_1.0-1/usr/bin/foobar new file mode 100755 index 000000000..c9651a463 --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/usr/bin/foobar @@ -0,0 +1,2 @@ +#!/bin/bash +echo Hello from the foobar package diff --git a/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/changelog.Debian b/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/changelog.Debian new file mode 100644 index 000000000..fe776f33e --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/changelog.Debian @@ -0,0 +1,5 @@ +foobar (1.0-1) precise-proposed; urgency=low + + * Genesis + + -- Main Tainer <maintainer@somewhere.org> Tue, 23 Sep 2014 11:13:27 +0200 diff --git a/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/copyright b/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/copyright new file mode 100644 index 000000000..4279ce4e2 --- /dev/null +++ b/build/f_example_packadd/foobar_1.0-1/usr/share/doc/foobar/copyright @@ -0,0 +1,18 @@ +foobar - a test daemon +Copyright (C) 2014 Main Tainer + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License with +your Debian GNU system, in /usr/share/common-licenses/GPL, or with the +Debian GNU gnupg source package as the file COPYING. If not, see +<http://www.gnu.org/licenses/> or write to the Free Software Foundation, +Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/build/f_example_packadd/puppet/modules/opnfv/manifests/foobar.pp b/build/f_example_packadd/puppet/modules/opnfv/manifests/foobar.pp new file mode 100644 index 000000000..c6219baa8 --- /dev/null +++ b/build/f_example_packadd/puppet/modules/opnfv/manifests/foobar.pp @@ -0,0 +1,7 @@ +class opnfv::foobar { + if $::osfamily == 'Debian' { + package { 'foobar': + ensure => installed, + } + } +} diff --git a/build/f_isoroot/Makefile b/build/f_isoroot/Makefile new file mode 100644 index 000000000..3831a09f0 --- /dev/null +++ b/build/f_isoroot/Makefile @@ -0,0 +1,33 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +SUBDIRS = f_kscfg f_bootstrap f_repobuild f_odlpluginbuild +SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) + +.PHONY: all +all: $(SUBDIRS) + +.PHONY: $(SUBDIRS) +$(SUBDIRS): + @mkdir -p release + $(MAKE) -C $@ -f Makefile release + +.PHONY: clean $(SUBCLEAN) +clean: $(SUBCLEAN) + @rm -Rf release + +$(SUBCLEAN): %.clean: + $(MAKE) -C $* -f Makefile clean + +.PHONY: release +release: $(SUBDIRS) + @cp -Rvp release/* ../release/isoroot + +include cache.mk diff --git a/build/f_isoroot/README b/build/f_isoroot/README new file mode 100644 index 000000000..eb54c0827 --- /dev/null +++ b/build/f_isoroot/README @@ -0,0 +1,16 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This is to (a) replace/patch existing Fuel ISO files as well +as adding new information directly into the ISO structure + +Please separate changes into "patches" and new content into +"additions". Both directories will be anchored at the ISO file +root. diff --git a/build/f_isoroot/cache.mk b/build/f_isoroot/cache.mk new file mode 100644 index 000000000..2df3b6bd1 --- /dev/null +++ b/build/f_isoroot/cache.mk @@ -0,0 +1,37 @@ +############################################################################## +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +############################################################################# +# Cache operations - only used when building through ci/build.sh +# +# This file is only meant for a top Makefile which is only calling its +# own SUBDIRS, without building any cachable artifact by itself. +############################################################################# + +# Call sub caches +SUBGETCACHE = $(addsuffix .getcache,$(SUBDIRS)) +$(SUBGETCACHE): %.getcache: + $(MAKE) -C $* -f Makefile get-cache + +SUBPUTCACHE = $(addsuffix .putcache,$(SUBDIRS)) +$(SUBPUTCACHE): %.putcache: + $(MAKE) -C $* -f Makefile put-cache + +SUBCLEANCACHE = $(addsuffix .cleancache,$(SUBDIRS)) +$(SUBCLEANCACHE): %.cleancache: + $(MAKE) -C $* -f Makefile clean-cache + +.PHONY: get-cache +get-cache: $(SUBGETCACHE) + +.PHONY: put-cache +put-cache: $(SUBPUTCACHE) + +.PHONY: clean-cache +clean-cache: $(SUBCLEANCACHE) diff --git a/build/f_isoroot/f_bootstrap/Makefile b/build/f_isoroot/f_bootstrap/Makefile new file mode 100644 index 000000000..a958aa2d6 --- /dev/null +++ b/build/f_isoroot/f_bootstrap/Makefile @@ -0,0 +1,48 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) + +.PHONY: all +all: + @mkdir -p release/opnfv/bootstrap/pre.d + @mkdir -p release/opnfv/bootstrap/post.d + @mkdir -p release/usr/local/sbin + @cp pre-scripts/* release/opnfv/bootstrap/pre.d + @cp post-scripts/* release/opnfv/bootstrap/post.d + @cp bootstrap_admin_node.sh release + @cp bootstrap_admin_node.sh.orig release + +.PHONY: clean +clean: + @rm -rf release + +.PHONY: release +release:all + @cp -Rvp release/* ../release + +############################################################################# +# Cache operations - only used when building through ci/build.sh +############################################################################# + +# Clean local data related to caching - called prior to ordinary build +.PHONY: clean-cache +clean-cache: clean + @echo "clean-cache not implemented" + +# Try to download cache - called prior to ordinary build +.PHONY: get-cache +get-cache: + @echo "get-cache not implemented" + +# Store cache if not already stored - called after ordinary build +.PHONY: put-cache +put-cache: + @echo "put-cache not implemented" diff --git a/build/f_isoroot/f_bootstrap/README b/build/f_isoroot/f_bootstrap/README new file mode 100644 index 000000000..5da954ca4 --- /dev/null +++ b/build/f_isoroot/f_bootstrap/README @@ -0,0 +1,24 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This function modifies the adds hooks to the beginning and end of +/usr/local/sbin/bootstrap_admin_nodes.sh, which is run as the +last post step from ks.cfg + +This enables other functions to place scripts into two directories +run either at the beginning or the end of the bootstrap procedure: + + /opt/opnfv/bootstrap/pre.d + /opt/opnfv/bootstrap/post.d + +These will be run in lexical order at pre or post. + +CI note: Using pre.d, it would be possible to "inject" a pre-defined +astute.yaml for Fuel. diff --git a/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh new file mode 100755 index 000000000..065d0cb7d --- /dev/null +++ b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh @@ -0,0 +1,266 @@ +#!/bin/bash +FUEL_RELEASE=$(grep release: /etc/fuel/version.yaml | cut -d: -f2 | tr -d '" ') + +function countdown() { + local i + sleep 1 + for ((i=$1-1; i>=1; i--)); do + printf '\b\b\b\b%04d' "$i" + sleep 1 + done +} + +function fail() { + echo "ERROR: Fuel node deployment FAILED! Check /var/log/puppet/bootstrap_admin_node.log for details" 1>&2 + exit 1 +} +# LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details +export LANG=en_US.UTF8 +export ADMIN_INTERFACE=eth0 + +showmenu="no" +if [ -f /etc/fuel/bootstrap_admin_node.conf ]; then + . /etc/fuel/bootstrap_admin_node.conf + echo "Applying admin interface '$ADMIN_INTERFACE'" +fi + +echo "Applying default Fuel settings..." +set -x +fuelmenu --save-only --iface=$ADMIN_INTERFACE +set +x +echo "Done!" + +### OPNFV addition BEGIN +shopt -s nullglob +for script in /opt/opnfv/bootstrap/pre.d/*.sh +do + echo "Pre script: $script" >> /root/pre.log 2>&1 + $script >> /root/pre.log 2>&1 +done +shopt -u nullglob +### OPNFV addition END + +if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then + fuelmenu + else + #Give user 15 seconds to enter fuelmenu or else continue + echo + echo -n "Press a key to enter Fuel Setup (or press ESC to skip)... 15" + countdown 15 & pid=$! + if ! read -s -n 1 -t 15 key; then + echo -e "\nSkipping Fuel Setup..." + else + { kill "$pid"; wait $!; } 2>/dev/null + case "$key" in + $'\e') echo "Skipping Fuel Setup.." + ;; + *) echo -e "\nEntering Fuel Setup..." + fuelmenu + ;; + esac + fi +fi + +if [ "$wait_for_external_config" == "yes" ]; then + wait_timeout=3000 + pidfile=/var/lock/wait_for_external_config + echo -n "Waiting for external configuration (or press ESC to skip)... +$wait_timeout" + countdown $wait_timeout & countdown_pid=$! + exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$! + echo $wait_pid > $pidfile + while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do + read -s -n 1 -t 2 key + case "$key" in + $'\e') echo -e "\b\b\b\b abort on user input" + break + ;; + *) ;; + esac + done + { kill $countdown_pid $wait_pid & wait $!; } + rm -f $pidfile +fi + + +#Reread /etc/sysconfig/network to inform puppet of changes +. /etc/sysconfig/network +hostname "$HOSTNAME" + +# XXX: ssh keys which should be included into the bootstrap image are +# generated during containers deployment. However cobbler checkfs for +# a kernel and initramfs when creating a profile, which poses chicken +# and egg problem. Fortunately cobbler is pretty happy with empty files +# so it's easy to break the loop. +make_ubuntu_bootstrap_stub () { + local bootstrap_dir='/var/www/nailgun/bootstrap/ubuntu' + mkdir -p $bootstrap_dir + for item in linux initramfs.img; do + touch "$bootstrap_dir/$item" + done +} + +get_bootstrap_flavor () { + local ASTUTE_YAML='/etc/fuel/astute.yaml' + python <<-EOF + from fuelmenu.fuelmenu import Settings + conf = Settings().read("$ASTUTE_YAML").get('BOOTSTRAP', {}) + print(conf.get('flavor', 'centos')) + EOF +} + +# Actually build the bootstrap image +build_ubuntu_bootstrap () { + local ret=1 + local max_attempts=3 + local config='/etc/fuel-bootstrap-image.conf' + local log='/var/log/fuel-bootstrap-image-build.log' + if ! grep -qE '^BOOTSTRAP_SSH_KEYS' "$config"; then + # FIXME: config file generated by fuelmenu has no trailing newline + echo >> "$config" + cat >> "$config" <<-EOF + BOOTSTRAP_SSH_KEYS=/root/.ssh/id_rsa.pub + EOF + fi + for n in `seq 1 $max_attempts`; do + echo "Bulding bootstrap image, attempt $n" >&2 + if fuel-bootstrap-image >>"$log" 2>&1; then + ret=0 + fuel-bootstrap-image-set "ubuntu" + break + fi + done + if [ $ret -ne 0 ]; then + warning="WARNING: failed to build the bootstrap image, see $log for details. +Perhaps your Internet connection is broken. Please fix the problem and run +\`fuel-bootstrap-image-set ubuntu\`" + fuel notify --topic warning --send "$warning" + fi + return $ret +} + + +# Create empty files to make cobbler happy +# (even if we don't use Ubuntu based bootstrap) +make_ubuntu_bootstrap_stub + +service docker start + +if [ -f /root/.build_images ]; then + #Fail on all errors + set -e + trap fail EXIT + + echo "Loading Fuel base image for Docker..." + docker load -i /var/www/nailgun/docker/images/fuel-images.tar + + echo "Building Fuel Docker images..." + WORKDIR=$(mktemp -d /tmp/docker-buildXXX) + SOURCE=/var/www/nailgun/docker + REPO_CONT_ID=$(docker -D run -d -p 80 -v /var/www/nailgun:/var/www/nailgun fuel/centos sh -c 'mkdir /var/www/html/os;ln -sf /var/www/nailgun/centos/x86_64 /var/www/html/os/x86_64;/usr/sbin/apachectl -DFOREGROUND') + RANDOM_PORT=$(docker port $REPO_CONT_ID 80 | cut -d':' -f2) + + for imagesource in /var/www/nailgun/docker/sources/*; do + if ! [ -f "$imagesource/Dockerfile" ]; then + echo "Skipping ${imagesource}..." + continue + fi + image=$(basename "$imagesource") + cp -R "$imagesource" $WORKDIR/$image + mkdir -p $WORKDIR/$image/etc + cp -R /etc/puppet /etc/fuel $WORKDIR/$image/etc + sed -e "s/_PORT_/${RANDOM_PORT}/" -i $WORKDIR/$image/Dockerfile + sed -e 's/production:.*/production: "docker-build"/' -i $WORKDIR/$image/etc/fuel/version.yaml + docker build -t fuel/${image}_${FUEL_RELEASE} $WORKDIR/$image + done + docker rm -f $REPO_CONT_ID + rm -rf "$WORKDIR" + + #Remove trap for normal deployment + trap - EXIT + set +e +else + echo "Loading docker images. (This may take a while)" + docker load -i /var/www/nailgun/docker/images/fuel-images.tar +fi + +# apply puppet +puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/host-only.pp +if [ $? -ge 4 ];then + fail +fi + +rmdir /var/log/remote && ln -s /var/log/docker-logs/remote /var/log/remote + +dockerctl check || fail +bash /etc/rc.local + +if [ "`get_bootstrap_flavor`" = "ubuntu" ]; then + build_ubuntu_bootstrap || true +fi + +### OPNFV addition BEGIN +shopt -s nullglob +for script in /opt/opnfv/bootstrap/post.d/*.sh +do + echo "Post script: $script" >> /root/post.log 2>&1 + $script >> /root/post.log 2>&1 +done +shopt -u nullglob +### OPNFV addition END + +# Enable updates repository +cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-updates.repo << EOF +[mos${FUEL_RELEASE}-updates] +name=mos${FUEL_RELEASE}-updates +baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/updates/x86_64/ +gpgcheck=0 +skip_if_unavailable=1 +EOF + +# Enable security repository +cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-security.repo << EOF +[mos${FUEL_RELEASE}-security] +name=mos${FUEL_RELEASE}-security +baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/security/x86_64/ +gpgcheck=0 +skip_if_unavailable=1 +EOF + +#Check if repo is accessible +echo "Checking for access to updates repository..." +repourl=$(grep baseurl /etc/yum.repos.d/*updates* 2>/dev/null | cut -d'=' -f2- | head -1) +if urlaccesscheck check "$repourl" ; then + UPDATE_ISSUES=0 +else + UPDATE_ISSUES=1 +fi + +if [ $UPDATE_ISSUES -eq 1 ]; then + message="There is an issue connecting to the Fuel update repository. \ +Please fix your connection prior to applying any updates. \ +Once the connection is fixed, we recommend reviewing and applying \ +Maintenance Updates for this release of Mirantis OpenStack: \ +https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\ +release-notes.html#maintenance-updates" + level="warning" +else + message="We recommend reviewing and applying Maintenance Updates \ +for this release of Mirantis OpenStack: \ +https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\ +release-notes.html#maintenance-updates" + level="done" +fi +echo +echo "*************************************************" +echo -e "${message}" +echo "*************************************************" +echo "Sending notification to Fuel UI..." +fuel notify --topic "${level}" --send "${message}" + +# TODO(kozhukalov) If building of bootstrap image fails +# and if this image was supposed to be a default bootstrap image +# we need to warn a user about this and give her +# advice how to treat this. + +echo "Fuel node deployment complete!" diff --git a/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig new file mode 100755 index 000000000..1bc349314 --- /dev/null +++ b/build/f_isoroot/f_bootstrap/bootstrap_admin_node.sh.orig @@ -0,0 +1,246 @@ +#!/bin/bash +FUEL_RELEASE=$(grep release: /etc/fuel/version.yaml | cut -d: -f2 | tr -d '" ') + +function countdown() { + local i + sleep 1 + for ((i=$1-1; i>=1; i--)); do + printf '\b\b\b\b%04d' "$i" + sleep 1 + done +} + +function fail() { + echo "ERROR: Fuel node deployment FAILED! Check /var/log/puppet/bootstrap_admin_node.log for details" 1>&2 + exit 1 +} +# LANG variable is a workaround for puppet-3.4.2 bug. See LP#1312758 for details +export LANG=en_US.UTF8 +export ADMIN_INTERFACE=eth0 + +showmenu="no" +if [ -f /etc/fuel/bootstrap_admin_node.conf ]; then + . /etc/fuel/bootstrap_admin_node.conf + echo "Applying admin interface '$ADMIN_INTERFACE'" +fi + +echo "Applying default Fuel settings..." +set -x +fuelmenu --save-only --iface=$ADMIN_INTERFACE +set +x +echo "Done!" + +if [[ "$showmenu" == "yes" || "$showmenu" == "YES" ]]; then + fuelmenu + else + #Give user 15 seconds to enter fuelmenu or else continue + echo + echo -n "Press a key to enter Fuel Setup (or press ESC to skip)... 15" + countdown 15 & pid=$! + if ! read -s -n 1 -t 15 key; then + echo -e "\nSkipping Fuel Setup..." + else + { kill "$pid"; wait $!; } 2>/dev/null + case "$key" in + $'\e') echo "Skipping Fuel Setup.." + ;; + *) echo -e "\nEntering Fuel Setup..." + fuelmenu + ;; + esac + fi +fi + +if [ "$wait_for_external_config" == "yes" ]; then + wait_timeout=3000 + pidfile=/var/lock/wait_for_external_config + echo -n "Waiting for external configuration (or press ESC to skip)... +$wait_timeout" + countdown $wait_timeout & countdown_pid=$! + exec -a wait_for_external_config sleep $wait_timeout & wait_pid=$! + echo $wait_pid > $pidfile + while ps -p $countdown_pid &> /dev/null && ps -p $wait_pid &>/dev/null; do + read -s -n 1 -t 2 key + case "$key" in + $'\e') echo -e "\b\b\b\b abort on user input" + break + ;; + *) ;; + esac + done + { kill $countdown_pid $wait_pid & wait $!; } + rm -f $pidfile +fi + + +#Reread /etc/sysconfig/network to inform puppet of changes +. /etc/sysconfig/network +hostname "$HOSTNAME" + +# XXX: ssh keys which should be included into the bootstrap image are +# generated during containers deployment. However cobbler checkfs for +# a kernel and initramfs when creating a profile, which poses chicken +# and egg problem. Fortunately cobbler is pretty happy with empty files +# so it's easy to break the loop. +make_ubuntu_bootstrap_stub () { + local bootstrap_dir='/var/www/nailgun/bootstrap/ubuntu' + mkdir -p $bootstrap_dir + for item in linux initramfs.img; do + touch "$bootstrap_dir/$item" + done +} + +get_bootstrap_flavor () { + local ASTUTE_YAML='/etc/fuel/astute.yaml' + python <<-EOF + from fuelmenu.fuelmenu import Settings + conf = Settings().read("$ASTUTE_YAML").get('BOOTSTRAP', {}) + print(conf.get('flavor', 'centos')) + EOF +} + +# Actually build the bootstrap image +build_ubuntu_bootstrap () { + local ret=1 + local max_attempts=3 + local config='/etc/fuel-bootstrap-image.conf' + local log='/var/log/fuel-bootstrap-image-build.log' + if ! grep -qE '^BOOTSTRAP_SSH_KEYS' "$config"; then + # FIXME: config file generated by fuelmenu has no trailing newline + echo >> "$config" + cat >> "$config" <<-EOF + BOOTSTRAP_SSH_KEYS=/root/.ssh/id_rsa.pub + EOF + fi + for n in `seq 1 $max_attempts`; do + echo "Bulding bootstrap image, attempt $n" >&2 + if fuel-bootstrap-image >>"$log" 2>&1; then + ret=0 + fuel-bootstrap-image-set "ubuntu" + break + fi + done + if [ $ret -ne 0 ]; then + warning="WARNING: failed to build the bootstrap image, see $log for details. +Perhaps your Internet connection is broken. Please fix the problem and run +\`fuel-bootstrap-image-set ubuntu\`" + fuel notify --topic warning --send "$warning" + fi + return $ret +} + + +# Create empty files to make cobbler happy +# (even if we don't use Ubuntu based bootstrap) +make_ubuntu_bootstrap_stub + +service docker start + +if [ -f /root/.build_images ]; then + #Fail on all errors + set -e + trap fail EXIT + + echo "Loading Fuel base image for Docker..." + docker load -i /var/www/nailgun/docker/images/fuel-images.tar + + echo "Building Fuel Docker images..." + WORKDIR=$(mktemp -d /tmp/docker-buildXXX) + SOURCE=/var/www/nailgun/docker + REPO_CONT_ID=$(docker -D run -d -p 80 -v /var/www/nailgun:/var/www/nailgun fuel/centos sh -c 'mkdir /var/www/html/os;ln -sf /var/www/nailgun/centos/x86_64 /var/www/html/os/x86_64;/usr/sbin/apachectl -DFOREGROUND') + RANDOM_PORT=$(docker port $REPO_CONT_ID 80 | cut -d':' -f2) + + for imagesource in /var/www/nailgun/docker/sources/*; do + if ! [ -f "$imagesource/Dockerfile" ]; then + echo "Skipping ${imagesource}..." + continue + fi + image=$(basename "$imagesource") + cp -R "$imagesource" $WORKDIR/$image + mkdir -p $WORKDIR/$image/etc + cp -R /etc/puppet /etc/fuel $WORKDIR/$image/etc + sed -e "s/_PORT_/${RANDOM_PORT}/" -i $WORKDIR/$image/Dockerfile + sed -e 's/production:.*/production: "docker-build"/' -i $WORKDIR/$image/etc/fuel/version.yaml + docker build -t fuel/${image}_${FUEL_RELEASE} $WORKDIR/$image + done + docker rm -f $REPO_CONT_ID + rm -rf "$WORKDIR" + + #Remove trap for normal deployment + trap - EXIT + set +e +else + echo "Loading docker images. (This may take a while)" + docker load -i /var/www/nailgun/docker/images/fuel-images.tar +fi + +# apply puppet +puppet apply --detailed-exitcodes -d -v /etc/puppet/modules/nailgun/examples/host-only.pp +if [ $? -ge 4 ];then + fail +fi + +rmdir /var/log/remote && ln -s /var/log/docker-logs/remote /var/log/remote + +dockerctl check || fail +bash /etc/rc.local + +if [ "`get_bootstrap_flavor`" = "ubuntu" ]; then + build_ubuntu_bootstrap || true +fi + +# Enable updates repository +cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-updates.repo << EOF +[mos${FUEL_RELEASE}-updates] +name=mos${FUEL_RELEASE}-updates +baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/updates/x86_64/ +gpgcheck=0 +skip_if_unavailable=1 +EOF + +# Enable security repository +cat > /etc/yum.repos.d/mos${FUEL_RELEASE}-security.repo << EOF +[mos${FUEL_RELEASE}-security] +name=mos${FUEL_RELEASE}-security +baseurl=http://mirror.fuel-infra.org/mos-repos/centos/mos${FUEL_RELEASE}-centos6-fuel/security/x86_64/ +gpgcheck=0 +skip_if_unavailable=1 +EOF + +#Check if repo is accessible +echo "Checking for access to updates repository..." +repourl=$(grep baseurl /etc/yum.repos.d/*updates* 2>/dev/null | cut -d'=' -f2- | head -1) +if urlaccesscheck check "$repourl" ; then + UPDATE_ISSUES=0 +else + UPDATE_ISSUES=1 +fi + +if [ $UPDATE_ISSUES -eq 1 ]; then + message="There is an issue connecting to the Fuel update repository. \ +Please fix your connection prior to applying any updates. \ +Once the connection is fixed, we recommend reviewing and applying \ +Maintenance Updates for this release of Mirantis OpenStack: \ +https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\ +release-notes.html#maintenance-updates" + level="warning" +else + message="We recommend reviewing and applying Maintenance Updates \ +for this release of Mirantis OpenStack: \ +https://docs.mirantis.com/openstack/fuel/fuel-${FUEL_RELEASE}/\ +release-notes.html#maintenance-updates" + level="done" +fi +echo +echo "*************************************************" +echo -e "${message}" +echo "*************************************************" +echo "Sending notification to Fuel UI..." +fuel notify --topic "${level}" --send "${message}" + +# TODO(kozhukalov) If building of bootstrap image fails +# and if this image was supposed to be a default bootstrap image +# we need to warn a user about this and give her +# advice how to treat this. + +echo "Fuel node deployment complete!" diff --git a/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh b/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh new file mode 100755 index 000000000..7ac896589 --- /dev/null +++ b/build/f_isoroot/f_bootstrap/post-scripts/00_post_example.sh @@ -0,0 +1,4 @@ +#/bin/sh +date +echo "This is an example file run at post-bootstrap." +exit 0 diff --git a/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh b/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh new file mode 100755 index 000000000..427a55add --- /dev/null +++ b/build/f_isoroot/f_bootstrap/post-scripts/03_install_repo.sh @@ -0,0 +1,19 @@ +#/bin/sh +echo "Installing pre-build repo" +if [ ! -d /opt/opnfv/nailgun ]; then + echo "Error - found no repo!" + exit 1 +fi + +mkdir -p /var/www/nailgun +mv /opt/opnfv/nailgun/* /var/www/nailgun +if [ $? -ne 0 ]; then + echo "Error moving repos to their correct location!" + exit 1 +fi +rmdir /opt/opnfv/nailgun +if [ $? -ne 0 ]; then + echo "Error removing /opt/opnfv/nailgun directory!" + exit 1 +fi +echo "Done installing pre-build repo" diff --git a/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh b/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh new file mode 100755 index 000000000..ac427bf87 --- /dev/null +++ b/build/f_isoroot/f_bootstrap/pre-scripts/00_pre_example.sh @@ -0,0 +1,4 @@ +#/bin/sh +date +echo "This is an example file run at pre-bootstrap." +exit 0 diff --git a/build/f_isoroot/f_kscfg/Makefile b/build/f_isoroot/f_kscfg/Makefile new file mode 100644 index 000000000..fe740418d --- /dev/null +++ b/build/f_isoroot/f_kscfg/Makefile @@ -0,0 +1,44 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) + +.PHONY: all +all: + @mkdir -p release + @cp ks.cfg release + @cp ks.cfg.orig release + +.PHONY: clean +clean: + @rm -rf release + +.PHONY: release +release: all + @cp -Rvp release/* ../release + +############################################################################# +# Cache operations - only used when building through ci/build.sh +############################################################################# + +# Clean local data related to caching - called prior to ordinary build +.PHONY: clean-cache +clean-cache: clean + @echo "clean-cache not implemented" + +# Try to download cache - called prior to ordinary build +.PHONY: get-cache +get-cache: + @echo "get-cache not implemented" + +# Store cache if not already stored - called after ordinary build +.PHONY: put-cache +put-cache: + @echo "put-cache not implemented" diff --git a/build/f_isoroot/f_kscfg/README b/build/f_isoroot/f_kscfg/README new file mode 100644 index 000000000..c85efde77 --- /dev/null +++ b/build/f_isoroot/f_kscfg/README @@ -0,0 +1,18 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +This function modifies the ks.cfg of the Fuel master to +make copy whatever is in the top level opnfv directory +of the ISO (populated by, for example, f_configfrontend) to +/opt/opnfv. In the end this is where the installation +parts will evolve. + +This is also the place to force the installation to overwrite +the disk (set forceformat="yes" instead of "no"). diff --git a/build/f_isoroot/f_kscfg/ks.cfg b/build/f_isoroot/f_kscfg/ks.cfg new file mode 100644 index 000000000..8c20971f8 --- /dev/null +++ b/build/f_isoroot/f_kscfg/ks.cfg @@ -0,0 +1,609 @@ +install +text +%include /tmp/source.ks +reboot --eject +lang en_US.UTF-8 +keyboard us +rootpw r00tme +timezone --utc Etc/UTC +firewall --disabled +selinux --disabled +# ignore unsupported hardware warning +unsupported_hardware +# SKIP CONFIGURING X +skipx +# NEVER ever place zerombr here, it breaks automated installation +%include /tmp/bootloader.ks +%include /tmp/partition.ks + +# PREINSTALL SECTION +# HERE ARE COMMANDS THAT WILL BE LAUNCHED BEFORE +# INSTALLATION PROCESS ITSELF +%pre +#!/bin/sh + +# hard drives +drives="" +removable_drives="" +for drv in `ls -1 /sys/block | grep "sd\|hd\|vd\|cciss"`; do + if !(blkid | grep -q "${drv}.*Fuel"); then + if (grep -q 0 /sys/block/${drv}/removable); then + drives="${drives} ${drv}" + else + removable_drives="${removable_drives} ${drv}" + fi + fi +done +default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + +installdrive="undefined" +forceformat="no" +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + +set ${drives} ${removable_drives} +numdrives=`echo $#` + +tgtdrive="${installdrive}" + +function confirm_format { + check_drive="$1" + local confirm_format="no" + + if [[ "$forceformat" == "yes" ]] ; then + return 0 + fi + + if parted -s /dev/$check_drive print &>/dev/null ; then + echo + echo "$check_drive drive contains partition table:" + parted -s /dev/$check_drive print + echo + read -p "Are you sure you want to erase ALL data on disk $check_drive? (y/N)" confirm_format + if [[ "$confirm_format" == "y" ]] || [[ "$confirm_format" == "Y" ]] || [[ "$forceformat" == "yes" ]]; then + return 0 + else + return 1 + fi + else + return 0 + fi +} + +format_confirmed="no" + +if [ $numdrives -lt 1 ]; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* There is no suitable media available for installation. *' + echo '* Please attach a drive and try again. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to shut down the system: " _ + poweroff +fi + +if [ ${numdrives} -gt 1 ] || [ `echo ${drives} | wc -w` -eq 0 ] ; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + while [ "${tgtdrive}" = "undefined" ]; do + clear + echo + echo '********************************************************************************' + echo '* W A R N I N G *' + echo '* *' + echo '* Which of the detected hard drives do you want to be used as *' + echo '* the installation target? *' + echo '* *' + echo '********************************************************************************' + echo + echo "Possible choices" + echo "Persistent drives: ${drives}" + echo "Removable drives: ${removable_drives}" + echo + if [ `echo ${drives} | wc -w` -eq 1 ] ; then + read -t 30 -p "Choose hard drive: " tgtdrive || tgtdrive=$default_drive + else + read -p "Choose hard drive: " tgtdrive + fi + match="no" + for drive in ${drives[@]} ${removable_drives[@]}; do + if [[ "$drive" == "$tgtdrive" ]] && match="yes" ; then + if confirm_format $tgtdrive ; then + format_confirmed="yes" + break + else + tgtdrive="undefined" + read -p "You may select another disk. Press Enter to continue." _ + fi + fi + done + if [[ "$match" == "no" ]]; then + tgtdrive="undefined" + read -p "Invalid choice. Press Enter to continue." _ + fi + done + clear + chvt 1 +else + tgtdrive=`echo ${drives} | sed -e "s/^\s*//" -e "s/\s*$//"` +fi + +if [ "$format_confirmed" != "yes" ] ; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + if ! confirm_format $tgtdrive ; then + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* Disk $tgtdrive contains active partition(s). *' + echo '* Installation cannot continue without confirmation. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to restart: " _ + reboot + fi + chvt 1 +fi + +# verify tgtdrive is at least 41GB +tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 )) +if [ $tgtdrivesize -lt 41984 ]; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* Your disk is under 41GB in size. Installation cannot continue. *' + echo '* Restart installation with a larger disk. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to restart: " _ + reboot +fi + +# paths in /dev have "/" instead of "!" for cciss devices +tgtdrive=$(echo $tgtdrive | sed -e 's/!/\//') + +# source +if test -e /dev/disk/by-label/"OpenStack_Fuel"; then + echo "harddrive --partition=LABEL="OpenStack_Fuel" --dir=/" > /tmp/source.ks +elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then + echo "harddrive --partition=UUID=will_be_substituted_with_actual_uuid --dir=/" > /tmp/source.ks +else + echo "cdrom" > /tmp/source.ks +fi + +vgremove -ff os +dd if=/dev/zero of=/dev/${tgtdrive} bs=10M count=10 +sleep 3 +hdparm -z /dev/${tgtdrive} +parted -s /dev/${tgtdrive} mklabel gpt +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 0 24 +parted -s /dev/${tgtdrive} set 1 bios_grub on +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary fat16 24 224 +parted -s /dev/${tgtdrive} set 2 boot on +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 224 424 +sleep 3 +hdparm -z /dev/${tgtdrive} + +# partition + +# This adds support for the p seperator required for cciss devices +if echo ${tgtdrive} | grep -q -e cciss ; then + bootdev=${tgtdrive}p +else + bootdev=${tgtdrive} +fi +echo > /tmp/partition.ks +echo "partition /boot --onpart=/dev/${bootdev}3" >> /tmp/partition.ks +echo "partition /boot/efi --onpart=/dev/${bootdev}2" >> /tmp/partition.ks +echo "partition pv.001 --ondisk=${tgtdrive} --size=41000 --grow" >> /tmp/partition.ks +echo "volgroup os pv.001" >> /tmp/partition.ks +echo "logvol swap --vgname=os --recommended --name=swap" >> /tmp/partition.ks +echo "logvol / --vgname=os --size=10000 --name=root --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var --vgname=os --size=10000 --percent 30 --grow --name=var --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var/lib/docker --vgname=os --size=17000 --percent 20 --grow --name=varlibdocker --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var/log --vgname=os --size=4096 --percent 50 --grow --name=varlog --fstype=ext4" >> /tmp/partition.ks + + +# bootloader +echo "bootloader --location=partition --driveorder=${tgtdrive} --append=' biosdevname=0 crashkernel=none'" > /tmp/bootloader.ks + +# Anaconda can not install grub 0.97 on disks which are >4T. +# The reason is that grub does not support such large geometries +# and it simply thinks that the cylinder number has negative value. +# Here we just set geometry manually so that grub thinks that disk +# size is equal to 1G. +# 130 cylinders * (16065 * 512 = 8225280 bytes) = 1G +echo "%post --nochroot --log=/mnt/sysimage/root/anaconda-post-partition.log" > /tmp/post_partition.ks +echo "echo \"device (hd0) /dev/${tgtdrive}\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"geometry (hd0) 130 255 63\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"root (hd0,2)\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo quit >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "cat /tmp/grub.script | chroot /mnt/sysimage /sbin/grub --no-floppy --batch" >> /tmp/post_partition.ks + +%end + +%packages --nobase --excludedocs +@Core +fuel +fuel-library >= 7.0 +fuel-dockerctl +authconfig +bind-utils +cronie +crontabs +curl +daemonize +dhcp +docker-io +fuel-bootstrap-image +fuel-bootstrap-image-builder +fuel-createmirror +fuel-target-centos-images6.6 +fuel-package-updates +fuelmenu +fuel-docker-images +gdisk +lrzip +lsof +man +mlocate +nmap-ncat +ntp +ntpdate +openssh-clients +policycoreutils +python-daemon +rsync +ruby21-puppet +ruby21-rubygem-netaddr +ruby21-rubygem-openstack +selinux-policy-targeted +strace +subscription-manager +sysstat +system-config-firewall-base +tcpdump +telnet +vim-enhanced +virt-what +wget +yum +yum-plugin-priorities + +%include /tmp/post_partition.ks + +# POSTINSTALL SECTION +# HERE ARE COMMANDS THAT WILL BE LAUNCHED JUST AFTER +# INSTALLATION ITSELF COMPLETED +%post +echo -e "modprobe nf_conntrack_ipv4\nmodprobe nf_conntrack_ipv6\nmodprobe nf_conntrack_tftp\nmodprobe nf_nat_tftp" >> /etc/rc.modules +chmod +x /etc/rc.modules +echo -e "net.nf_conntrack_max=1048576" >> /etc/sysctl.conf +mkdir -p /var/log/coredump +echo -e "kernel.core_pattern=/var/log/coredump/core.%e.%p.%h.%t" >> /etc/sysctl.conf +chmod 777 /var/log/coredump +echo -e "* soft core unlimited\n* hard core unlimited" >> /etc/security/limits.conf + +# Mount installation media in chroot +%post --nochroot --log=/mnt/sysimage/root/anaconda-post-before-chroot.log +#!/bin/sh + +set -x + +SOURCE="/mnt/sysimage/tmp/source" + +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + +mkdir -p "${SOURCE}" + +case "${repo}" in + nfs:*) + nfs_url="${repo#nfs:}" + mount -t nfs "${nfs_url}" "${SOURCE}" + ;; + *) + if [ -d "/mnt/source" ]; then + mount -o bind "/mnt/source" "${SOURCE}" + fi + ;; +esac + +%post --log=/root/anaconda-post-after-chroot.log +#!/bin/bash + +set -x + +function save_cfg { + scrFile="/etc/sysconfig/network-scripts/ifcfg-$admin_interface" + search="domain $domain\nsearch $domain" + sed -i -e 's#^\(HOSTNAME=\).*$#\1'"$hostname"'#' /etc/sysconfig/network + grep -q "^\s*$ip\s+$hostname" /etc/hosts || echo "$ip $hostname" >> /etc/hosts + echo "${search}\nnameserver 127.0.0.1" > /etc/resolv.conf + [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/resolv.conf + [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/dnsmasq.upstream + [ $dns2 ] && echo "nameserver $dns2" >> /etc/resolv.conf + [ $dns2 ] && echo "nameserver $dns2" >> /etc/dnsmasq.upstream + + echo DEVICE=$admin_interface > $scrFile + echo ONBOOT=yes >> $scrFile + echo NM_CONTROLLED=no >> $scrFile + echo HWADDR=$hwaddr >> $scrFile + echo USERCTL=no >> $scrFile + echo PEERDNS=no >> $scrFile + if [ $ip ]; then + echo BOOTPROTO=static >> $scrFile + echo IPADDR=$ip >> $scrFile + echo NETMASK=$netmask >> $scrFile + else + echo BOOTPROTO=dhcp >> $scrFile + fi + scrDHCPFile="/etc/sysconfig/network-scripts/ifcfg-$dhcp_interface" + #Ignore gateway and set up DHCP if it is used, otherwise apply it + if [ $dhcp_interface ] && [ "$dhcp_interface" != "$admin_interface" ]; then + echo "DEVICE=$dhcp_interface" > $scrDHCPFile + echo "BOOTPROTO=dhcp" >> $scrDHCPFile + echo "ONBOOT=yes" >> $scrDHCPFile + echo "USERCTL=no" >> $scrDHCPFile + else + echo GATEWAY=$gw >> /etc/sysconfig/network + fi + [ -n "$build_images" -a "$build_images" != "0" ] && echo -e "$build_images" > /root/.build_images +} + +# Default FQDN +hostname="nailgun.mirantis.com" + +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done +hostname=$hostname +domain=${hostname#*.} +ip=$ip +netmask=$netmask +gw=$gw +admin_interface=${admin_interface:-"eth0"} +hwaddr=`ifconfig $admin_interface | grep -i hwaddr | sed -e 's#^.*hwaddr[[:space:]]*##I'` +dhcp_interface=$dhcp_interface +build_images=$build_images +wait_for_external_config=$wait_for_external_config +save_cfg + +# Mounting installation source +SOURCE=/tmp/source +FS=/tmp/fs + +echo +mkdir -p ${SOURCE} +mkdir -p ${FS} + +if test -e /dev/disk/by-label/"OpenStack_Fuel"; then + mount /dev/disk/by-label/"OpenStack_Fuel" ${SOURCE} +elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then + mount /dev/disk/by-uuid/will_be_substituted_with_actual_uuid ${FS} + mount -o loop ${FS}/nailgun.iso ${SOURCE} +fi + +OPENSTACK_VERSION=`cat ${SOURCE}/openstack_version` + +# ---------------------- +# UNPACKING REPOSITORIES +# ---------------------- + +wwwdir="/var/www/nailgun" +repodir="${wwwdir}/${OPENSTACK_VERSION}" + +# Copying Centos files +mkdir -p ${repodir}/centos/x86_64 +cp -r ${SOURCE}/images ${repodir}/centos/x86_64 +cp -r ${SOURCE}/isolinux ${repodir}/centos/x86_64 +cp -r ${SOURCE}/repodata ${repodir}/centos/x86_64 +cp -r ${SOURCE}/Packages ${repodir}/centos/x86_64 +cp ${SOURCE}/.treeinfo ${repodir}/centos/x86_64 + +# Copying Ubuntu files +mkdir -p ${repodir}/ubuntu/x86_64/images +cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/x86_64 +cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/x86_64 + +# We do not ship debian-installer kernel and initrd on ISO. +# But we still need to be able to create ubuntu cobbler distro +# which requires kernel and initrd to be available. So, we +# just touch these files to work around cobbler's limitation. +touch ${repodir}/ubuntu/x86_64/images/linux +touch ${repodir}/ubuntu/x86_64/images/initrd.gz + +# make links for backward compatibility +ln -s ${repodir}/centos ${wwwdir}/centos +ln -s ${repodir}/ubuntu ${wwwdir}/ubuntu + +# -------------------------- +# UNPACKING PUPPET MANIFESTS +# -------------------------- + +# create folders +#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/manifests/ +#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/modules/ +#rm -rf /etc/puppet/modules/ + +# TODO(ikalnitsky): investigate why we need this +#cp ${SOURCE}/puppet-slave.tgz ${wwwdir}/ + +# place modules and manifests +#tar zxf ${SOURCE}/puppet-slave.tgz -C /etc/puppet/${OPENSTACK_VERSION}/modules +#cp /etc/puppet/${OPENSTACK_VERSION}/modules/osnailyfacter/examples/site.pp /etc/puppet/${OPENSTACK_VERSION}/manifests/site.pp +cp ${SOURCE}/centos-versions.yaml ${SOURCE}/ubuntu-versions.yaml /etc/puppet/${OPENSTACK_VERSION}/manifests/ + +# make links for backward compatibility +#pushd /etc/puppet +#ln -s ${OPENSTACK_VERSION}/manifests/ /etc/puppet/manifests +#ln -s ${OPENSTACK_VERSION}/modules/ /etc/puppet/modules +#popd + +cp ${SOURCE}/send2syslog.py /bin/send2syslog.py +mkdir -p /var/lib/hiera +touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml + +# Prepare local repository specification +rm /etc/yum.repos.d/CentOS*.repo +cat > /etc/yum.repos.d/nailgun.repo << EOF +[nailgun] +name=Nailgun Local Repo +baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/centos/x86_64 +gpgcheck=0 +EOF + +# Disable subscription-manager plugins +sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/product-id.conf || : +sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/subscription-manager.conf || : + +# Disable GSSAPI in ssh server config +sed -i -e "/^\s*GSSAPICleanupCredentials yes/d" -e "/^\s*GSSAPIAuthentication yes/d" /etc/ssh/sshd_config + +# Enable MOTD banner in sshd +sed -i -e "s/^\s*PrintMotd no/PrintMotd yes/g" /etc/ssh/sshd_config + +# Add note regarding local repos creation to MOTD +cat >> /etc/motd << EOF + +All environments use online repositories by default. +Use the following commands to create local repositories +on master node and change default repository settings: + +* CentOS: fuel-package-updates (see --help for options) +* Ubuntu: fuel-createmirror (see --help for options) + +Please refer to the following guide for more information: +https://docs.mirantis.com/openstack/fuel/fuel-7.0/reference-architecture.html#fuel-rep-mirror + +EOF + +# Copying bootstrap_admin_node.sh, chmod it and +# adding /etc/init/bootstrap_admin_node.conf +cp ${SOURCE}/bootstrap_admin_node.sh /usr/local/sbin/bootstrap_admin_node.sh +chmod 0777 /usr/local/sbin/bootstrap_admin_node.sh +cp ${SOURCE}/bootstrap_admin_node.conf /etc/init/bootstrap_admin_node.conf +echo "ENABLED=1" > /etc/sysconfig/bootstrap_admin_node + +# Copying version.yaml file. It contains COMMIT_SHA of last commit. +RELEASE=$(awk '/release/{gsub(/"/, "");print $2}' ${SOURCE}/version.yaml) +mkdir -p /etc/nailgun /etc/fuel/${RELEASE} /etc/fuel/release_versions +cp ${SOURCE}/version.yaml /etc/nailgun/version.yaml +cp ${SOURCE}/version.yaml /etc/fuel/${RELEASE}/version.yaml +ln -s /etc/fuel/${RELEASE}/version.yaml /etc/fuel/version.yaml +cp ${SOURCE}/version.yaml /etc/fuel/release_versions/`cat ${SOURCE}/openstack_version`.yaml + +# Generete Fuel UUID +uuidgen > /etc/fuel/fuel-uuid + +# Run fuel menu +[ -z "$showmenu" ] && showmenu="no" + +# Pause during bootstrap_admin_node to wait for external config +[ -z "$wait_for_external_config" ] && wait_for_external_config="no" + + +# Prepare bootstrap_admin_node config +cat > /etc/fuel/bootstrap_admin_node.conf << EOF +#Set to yes to run Fuel Setup +#Set to no to accept default settings +ADMIN_INTERFACE=${admin_interface} +showmenu=${showmenu} +wait_for_external_config=${wait_for_external_config} +EOF + +# Prepare custom /etc/issue logon banner and script for changing IP in it +cat > /etc/issue << EOF +######################################### +# Welcome to the Fuel server # +######################################### +Server is running on \m platform + +Fuel UI is available on: +https://:8443 + +Default administrator login: root +Default administrator password: r00tme + +Default Fuel UI login: admin +Default Fuel UI password: admin + +Please change root password on first login. + +EOF + + +cat >> '/etc/rc.local' << EOF +first=yes +for ip in \$(ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1); do +if [ "\$first" = "yes" ]; then + ipstr="Fuel UI is available on: https://\$ip:8443" + first=no +else + ipstr=\$(printf "%s\n%25s%s" "\$ipstr" " " "https://\$ip:8443") +fi +done +tmpissue=\$(mktemp) +while read -r line; do + if [[ "\$line" =~ "Fuel UI is available on" ]]; then + echo -e "\$ipstr" >> \$tmpissue + elif [[ "\$line" =~ :8443$ ]]; then + : + else + echo -e "\$line" >> \$tmpissue + fi +done < /etc/issue +mv "\$tmpissue" /etc/issue + +EOF + +######### OPNFV addition BEGIN ############ +# Copy data into /opt/opnfv +# TODO: This ought to be a package instead! +mkdir -p /opt/opnfv +cp -r ${SOURCE}/opnfv /opt +cp ${SOURCE}/gitinfo.txt / +######### OPNFV addition END ############ + +# Unmounting source +umount -f ${SOURCE} +rm -rf ${SOURCE} + +umount -f ${FS} || true +rm -rf ${FS} + +echo "tos orphan 7" >> /etc/ntp.conf + +# Do not show error message on ntpdate failure. Customers should not be confused +# if admin node does not have access to the internet time servers. +sed -i /etc/rc.d/init.d/ntpdate -e 's/\([ $RETVAL -eq 0 ] && success || \)failure/\1success/' + +# Disabling splash +sed -i --follow-symlinks -e '/^\skernel/ s/rhgb//' /etc/grub.conf +sed -i --follow-symlinks -e '/^\skernel/ s/quiet//' /etc/grub.conf + +# Disabling console clearing +sed -i 's/getty/getty --noclear/' /etc/init/tty.conf + +# Disabling starting first console from start-ttys service +sed -i --follow-symlinks -e 's/ACTIVE_CONSOLES=.*/ACTIVE_CONSOLES=\/dev\/tty\[2-6\]/' /etc/sysconfig/init + +# Copying default bash settings to the root directory +cp -f /etc/skel/.bash* /root/ + +# Blacklist i2c_piix4 module for VirtualBox so it does not create kernel errors +[[ $(virt-what) = "virtualbox" ]] && echo "blacklist i2c_piix4" > /etc/modprobe.d/blacklist-i2c-piix4.conf + +%end diff --git a/build/f_isoroot/f_kscfg/ks.cfg.orig b/build/f_isoroot/f_kscfg/ks.cfg.orig new file mode 100644 index 000000000..148ef9908 --- /dev/null +++ b/build/f_isoroot/f_kscfg/ks.cfg.orig @@ -0,0 +1,602 @@ +install +text +%include /tmp/source.ks +reboot --eject +lang en_US.UTF-8 +keyboard us +rootpw r00tme +timezone --utc Etc/UTC +firewall --disabled +selinux --disabled +# ignore unsupported hardware warning +unsupported_hardware +# SKIP CONFIGURING X +skipx +# NEVER ever place zerombr here, it breaks automated installation +%include /tmp/bootloader.ks +%include /tmp/partition.ks + +# PREINSTALL SECTION +# HERE ARE COMMANDS THAT WILL BE LAUNCHED BEFORE +# INSTALLATION PROCESS ITSELF +%pre +#!/bin/sh + +# hard drives +drives="" +removable_drives="" +for drv in `ls -1 /sys/block | grep "sd\|hd\|vd\|cciss"`; do + if !(blkid | grep -q "${drv}.*Fuel"); then + if (grep -q 0 /sys/block/${drv}/removable); then + drives="${drives} ${drv}" + else + removable_drives="${removable_drives} ${drv}" + fi + fi +done +default_drive=`echo ${drives} ${removable_drives} | awk '{print $1}'` + +installdrive="undefined" +forceformat="no" +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + +set ${drives} ${removable_drives} +numdrives=`echo $#` + +tgtdrive="${installdrive}" + +function confirm_format { + check_drive="$1" + local confirm_format="no" + + if [[ "$forceformat" == "yes" ]] ; then + return 0 + fi + + if parted -s /dev/$check_drive print &>/dev/null ; then + echo + echo "$check_drive drive contains partition table:" + parted -s /dev/$check_drive print + echo + read -p "Are you sure you want to erase ALL data on disk $check_drive? (y/N)" confirm_format + if [[ "$confirm_format" == "y" ]] || [[ "$confirm_format" == "Y" ]] || [[ "$forceformat" == "yes" ]]; then + return 0 + else + return 1 + fi + else + return 0 + fi +} + +format_confirmed="no" + +if [ $numdrives -lt 1 ]; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* There is no suitable media available for installation. *' + echo '* Please attach a drive and try again. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to shut down the system: " _ + poweroff +fi + +if [ ${numdrives} -gt 1 ] || [ `echo ${drives} | wc -w` -eq 0 ] ; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + while [ "${tgtdrive}" = "undefined" ]; do + clear + echo + echo '********************************************************************************' + echo '* W A R N I N G *' + echo '* *' + echo '* Which of the detected hard drives do you want to be used as *' + echo '* the installation target? *' + echo '* *' + echo '********************************************************************************' + echo + echo "Possible choices" + echo "Persistent drives: ${drives}" + echo "Removable drives: ${removable_drives}" + echo + if [ `echo ${drives} | wc -w` -eq 1 ] ; then + read -t 30 -p "Choose hard drive: " tgtdrive || tgtdrive=$default_drive + else + read -p "Choose hard drive: " tgtdrive + fi + match="no" + for drive in ${drives[@]} ${removable_drives[@]}; do + if [[ "$drive" == "$tgtdrive" ]] && match="yes" ; then + if confirm_format $tgtdrive ; then + format_confirmed="yes" + break + else + tgtdrive="undefined" + read -p "You may select another disk. Press Enter to continue." _ + fi + fi + done + if [[ "$match" == "no" ]]; then + tgtdrive="undefined" + read -p "Invalid choice. Press Enter to continue." _ + fi + done + clear + chvt 1 +else + tgtdrive=`echo ${drives} | sed -e "s/^\s*//" -e "s/\s*$//"` +fi + +if [ "$format_confirmed" != "yes" ] ; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + if ! confirm_format $tgtdrive ; then + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* Disk $tgtdrive contains active partition(s). *' + echo '* Installation cannot continue without confirmation. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to restart: " _ + reboot + fi + chvt 1 +fi + +# verify tgtdrive is at least 41GB +tgtdrivesize=$(( $(cat "/sys/class/block/${tgtdrive}/size") / 2 / 1024 )) +if [ $tgtdrivesize -lt 41984 ]; then + exec < /dev/tty3 > /dev/tty3 2>&1 + chvt 3 + clear + echo + echo '********************************************************************' + echo '* E R R O R *' + echo '* *' + echo '* Your disk is under 41GB in size. Installation cannot continue. *' + echo '* Restart installation with a larger disk. *' + echo '* *' + echo '********************************************************************' + echo + read -p "Press Enter to restart: " _ + reboot +fi + +# paths in /dev have "/" instead of "!" for cciss devices +tgtdrive=$(echo $tgtdrive | sed -e 's/!/\//') + +# source +if test -e /dev/disk/by-label/"OpenStack_Fuel"; then + echo "harddrive --partition=LABEL="OpenStack_Fuel" --dir=/" > /tmp/source.ks +elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then + echo "harddrive --partition=UUID=will_be_substituted_with_actual_uuid --dir=/" > /tmp/source.ks +else + echo "cdrom" > /tmp/source.ks +fi + +vgremove -ff os +dd if=/dev/zero of=/dev/${tgtdrive} bs=10M count=10 +sleep 3 +hdparm -z /dev/${tgtdrive} +parted -s /dev/${tgtdrive} mklabel gpt +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 0 24 +parted -s /dev/${tgtdrive} set 1 bios_grub on +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary fat16 24 224 +parted -s /dev/${tgtdrive} set 2 boot on +parted -a none -s /dev/${tgtdrive} unit MiB mkpart primary 224 424 +sleep 3 +hdparm -z /dev/${tgtdrive} + +# partition + +# This adds support for the p seperator required for cciss devices +if echo ${tgtdrive} | grep -q -e cciss ; then + bootdev=${tgtdrive}p +else + bootdev=${tgtdrive} +fi +echo > /tmp/partition.ks +echo "partition /boot --onpart=/dev/${bootdev}3" >> /tmp/partition.ks +echo "partition /boot/efi --onpart=/dev/${bootdev}2" >> /tmp/partition.ks +echo "partition pv.001 --ondisk=${tgtdrive} --size=41000 --grow" >> /tmp/partition.ks +echo "volgroup os pv.001" >> /tmp/partition.ks +echo "logvol swap --vgname=os --recommended --name=swap" >> /tmp/partition.ks +echo "logvol / --vgname=os --size=10000 --name=root --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var --vgname=os --size=10000 --percent 30 --grow --name=var --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var/lib/docker --vgname=os --size=17000 --percent 20 --grow --name=varlibdocker --fstype=ext4" >> /tmp/partition.ks +echo "logvol /var/log --vgname=os --size=4096 --percent 50 --grow --name=varlog --fstype=ext4" >> /tmp/partition.ks + + +# bootloader +echo "bootloader --location=partition --driveorder=${tgtdrive} --append=' biosdevname=0 crashkernel=none'" > /tmp/bootloader.ks + +# Anaconda can not install grub 0.97 on disks which are >4T. +# The reason is that grub does not support such large geometries +# and it simply thinks that the cylinder number has negative value. +# Here we just set geometry manually so that grub thinks that disk +# size is equal to 1G. +# 130 cylinders * (16065 * 512 = 8225280 bytes) = 1G +echo "%post --nochroot --log=/mnt/sysimage/root/anaconda-post-partition.log" > /tmp/post_partition.ks +echo "echo \"device (hd0) /dev/${tgtdrive}\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"geometry (hd0) 130 255 63\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"root (hd0,2)\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo \"install /grub/stage1 (hd0) /grub/stage2 p /grub/grub.conf\" >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "echo quit >> /tmp/grub.script" >> /tmp/post_partition.ks +echo "cat /tmp/grub.script | chroot /mnt/sysimage /sbin/grub --no-floppy --batch" >> /tmp/post_partition.ks + +%end + +%packages --nobase --excludedocs +@Core +fuel +fuel-library >= 7.0 +fuel-dockerctl +authconfig +bind-utils +cronie +crontabs +curl +daemonize +dhcp +docker-io +fuel-bootstrap-image +fuel-bootstrap-image-builder +fuel-createmirror +fuel-target-centos-images6.6 +fuel-package-updates +fuelmenu +fuel-docker-images +gdisk +lrzip +lsof +man +mlocate +nmap-ncat +ntp +ntpdate +openssh-clients +policycoreutils +python-daemon +rsync +ruby21-puppet +ruby21-rubygem-netaddr +ruby21-rubygem-openstack +selinux-policy-targeted +strace +subscription-manager +sysstat +system-config-firewall-base +tcpdump +telnet +vim-enhanced +virt-what +wget +yum +yum-plugin-priorities + +%include /tmp/post_partition.ks + +# POSTINSTALL SECTION +# HERE ARE COMMANDS THAT WILL BE LAUNCHED JUST AFTER +# INSTALLATION ITSELF COMPLETED +%post +echo -e "modprobe nf_conntrack_ipv4\nmodprobe nf_conntrack_ipv6\nmodprobe nf_conntrack_tftp\nmodprobe nf_nat_tftp" >> /etc/rc.modules +chmod +x /etc/rc.modules +echo -e "net.nf_conntrack_max=1048576" >> /etc/sysctl.conf +mkdir -p /var/log/coredump +echo -e "kernel.core_pattern=/var/log/coredump/core.%e.%p.%h.%t" >> /etc/sysctl.conf +chmod 777 /var/log/coredump +echo -e "* soft core unlimited\n* hard core unlimited" >> /etc/security/limits.conf + +# Mount installation media in chroot +%post --nochroot --log=/mnt/sysimage/root/anaconda-post-before-chroot.log +#!/bin/sh + +set -x + +SOURCE="/mnt/sysimage/tmp/source" + +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done + +mkdir -p "${SOURCE}" + +case "${repo}" in + nfs:*) + nfs_url="${repo#nfs:}" + mount -t nfs "${nfs_url}" "${SOURCE}" + ;; + *) + if [ -d "/mnt/source" ]; then + mount -o bind "/mnt/source" "${SOURCE}" + fi + ;; +esac + +%post --log=/root/anaconda-post-after-chroot.log +#!/bin/bash + +set -x + +function save_cfg { + scrFile="/etc/sysconfig/network-scripts/ifcfg-$admin_interface" + search="domain $domain\nsearch $domain" + sed -i -e 's#^\(HOSTNAME=\).*$#\1'"$hostname"'#' /etc/sysconfig/network + grep -q "^\s*$ip\s+$hostname" /etc/hosts || echo "$ip $hostname" >> /etc/hosts + echo "${search}\nnameserver 127.0.0.1" > /etc/resolv.conf + [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/resolv.conf + [ $dns1 ] && echo -e "${search}\nnameserver $dns1" > /etc/dnsmasq.upstream + [ $dns2 ] && echo "nameserver $dns2" >> /etc/resolv.conf + [ $dns2 ] && echo "nameserver $dns2" >> /etc/dnsmasq.upstream + + echo DEVICE=$admin_interface > $scrFile + echo ONBOOT=yes >> $scrFile + echo NM_CONTROLLED=no >> $scrFile + echo HWADDR=$hwaddr >> $scrFile + echo USERCTL=no >> $scrFile + echo PEERDNS=no >> $scrFile + if [ $ip ]; then + echo BOOTPROTO=static >> $scrFile + echo IPADDR=$ip >> $scrFile + echo NETMASK=$netmask >> $scrFile + else + echo BOOTPROTO=dhcp >> $scrFile + fi + scrDHCPFile="/etc/sysconfig/network-scripts/ifcfg-$dhcp_interface" + #Ignore gateway and set up DHCP if it is used, otherwise apply it + if [ $dhcp_interface ] && [ "$dhcp_interface" != "$admin_interface" ]; then + echo "DEVICE=$dhcp_interface" > $scrDHCPFile + echo "BOOTPROTO=dhcp" >> $scrDHCPFile + echo "ONBOOT=yes" >> $scrDHCPFile + echo "USERCTL=no" >> $scrDHCPFile + else + echo GATEWAY=$gw >> /etc/sysconfig/network + fi + [ -n "$build_images" -a "$build_images" != "0" ] && echo -e "$build_images" > /root/.build_images +} + +# Default FQDN +hostname="nailgun.mirantis.com" + +for I in `cat /proc/cmdline`; do case "$I" in *=*) eval $I;; esac ; done +hostname=$hostname +domain=${hostname#*.} +ip=$ip +netmask=$netmask +gw=$gw +admin_interface=${admin_interface:-"eth0"} +hwaddr=`ifconfig $admin_interface | grep -i hwaddr | sed -e 's#^.*hwaddr[[:space:]]*##I'` +dhcp_interface=$dhcp_interface +build_images=$build_images +wait_for_external_config=$wait_for_external_config +save_cfg + +# Mounting installation source +SOURCE=/tmp/source +FS=/tmp/fs + +echo +mkdir -p ${SOURCE} +mkdir -p ${FS} + +if test -e /dev/disk/by-label/"OpenStack_Fuel"; then + mount /dev/disk/by-label/"OpenStack_Fuel" ${SOURCE} +elif test -e /dev/disk/by-uuid/will_be_substituted_with_actual_uuid; then + mount /dev/disk/by-uuid/will_be_substituted_with_actual_uuid ${FS} + mount -o loop ${FS}/nailgun.iso ${SOURCE} +fi + +OPENSTACK_VERSION=`cat ${SOURCE}/openstack_version` + +# ---------------------- +# UNPACKING REPOSITORIES +# ---------------------- + +wwwdir="/var/www/nailgun" +repodir="${wwwdir}/${OPENSTACK_VERSION}" + +# Copying Centos files +mkdir -p ${repodir}/centos/x86_64 +cp -r ${SOURCE}/images ${repodir}/centos/x86_64 +cp -r ${SOURCE}/isolinux ${repodir}/centos/x86_64 +cp -r ${SOURCE}/repodata ${repodir}/centos/x86_64 +cp -r ${SOURCE}/Packages ${repodir}/centos/x86_64 +cp ${SOURCE}/.treeinfo ${repodir}/centos/x86_64 + +# Copying Ubuntu files +mkdir -p ${repodir}/ubuntu/x86_64/images +cp -r ${SOURCE}/ubuntu/dists ${repodir}/ubuntu/x86_64 +cp -r ${SOURCE}/ubuntu/pool ${repodir}/ubuntu/x86_64 + +# We do not ship debian-installer kernel and initrd on ISO. +# But we still need to be able to create ubuntu cobbler distro +# which requires kernel and initrd to be available. So, we +# just touch these files to work around cobbler's limitation. +touch ${repodir}/ubuntu/x86_64/images/linux +touch ${repodir}/ubuntu/x86_64/images/initrd.gz + +# make links for backward compatibility +ln -s ${repodir}/centos ${wwwdir}/centos +ln -s ${repodir}/ubuntu ${wwwdir}/ubuntu + +# -------------------------- +# UNPACKING PUPPET MANIFESTS +# -------------------------- + +# create folders +#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/manifests/ +#mkdir -p /etc/puppet/${OPENSTACK_VERSION}/modules/ +#rm -rf /etc/puppet/modules/ + +# TODO(ikalnitsky): investigate why we need this +#cp ${SOURCE}/puppet-slave.tgz ${wwwdir}/ + +# place modules and manifests +#tar zxf ${SOURCE}/puppet-slave.tgz -C /etc/puppet/${OPENSTACK_VERSION}/modules +#cp /etc/puppet/${OPENSTACK_VERSION}/modules/osnailyfacter/examples/site.pp /etc/puppet/${OPENSTACK_VERSION}/manifests/site.pp +cp ${SOURCE}/centos-versions.yaml ${SOURCE}/ubuntu-versions.yaml /etc/puppet/${OPENSTACK_VERSION}/manifests/ + +# make links for backward compatibility +#pushd /etc/puppet +#ln -s ${OPENSTACK_VERSION}/manifests/ /etc/puppet/manifests +#ln -s ${OPENSTACK_VERSION}/modules/ /etc/puppet/modules +#popd + +cp ${SOURCE}/send2syslog.py /bin/send2syslog.py +mkdir -p /var/lib/hiera +touch /var/lib/hiera/common.yaml /etc/puppet/hiera.yaml + +# Prepare local repository specification +rm /etc/yum.repos.d/CentOS*.repo +cat > /etc/yum.repos.d/nailgun.repo << EOF +[nailgun] +name=Nailgun Local Repo +baseurl=file:/var/www/nailgun/${OPENSTACK_VERSION}/centos/x86_64 +gpgcheck=0 +EOF + +# Disable subscription-manager plugins +sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/product-id.conf || : +sed -i 's/^enabled.*/enabled=0/' /etc/yum/pluginconf.d/subscription-manager.conf || : + +# Disable GSSAPI in ssh server config +sed -i -e "/^\s*GSSAPICleanupCredentials yes/d" -e "/^\s*GSSAPIAuthentication yes/d" /etc/ssh/sshd_config + +# Enable MOTD banner in sshd +sed -i -e "s/^\s*PrintMotd no/PrintMotd yes/g" /etc/ssh/sshd_config + +# Add note regarding local repos creation to MOTD +cat >> /etc/motd << EOF + +All environments use online repositories by default. +Use the following commands to create local repositories +on master node and change default repository settings: + +* CentOS: fuel-package-updates (see --help for options) +* Ubuntu: fuel-createmirror (see --help for options) + +Please refer to the following guide for more information: +https://docs.mirantis.com/openstack/fuel/fuel-7.0/reference-architecture.html#fuel-rep-mirror + +EOF + +# Copying bootstrap_admin_node.sh, chmod it and +# adding /etc/init/bootstrap_admin_node.conf +cp ${SOURCE}/bootstrap_admin_node.sh /usr/local/sbin/bootstrap_admin_node.sh +chmod 0777 /usr/local/sbin/bootstrap_admin_node.sh +cp ${SOURCE}/bootstrap_admin_node.conf /etc/init/bootstrap_admin_node.conf +echo "ENABLED=1" > /etc/sysconfig/bootstrap_admin_node + +# Copying version.yaml file. It contains COMMIT_SHA of last commit. +RELEASE=$(awk '/release/{gsub(/"/, "");print $2}' ${SOURCE}/version.yaml) +mkdir -p /etc/nailgun /etc/fuel/${RELEASE} /etc/fuel/release_versions +cp ${SOURCE}/version.yaml /etc/nailgun/version.yaml +cp ${SOURCE}/version.yaml /etc/fuel/${RELEASE}/version.yaml +ln -s /etc/fuel/${RELEASE}/version.yaml /etc/fuel/version.yaml +cp ${SOURCE}/version.yaml /etc/fuel/release_versions/`cat ${SOURCE}/openstack_version`.yaml + +# Generete Fuel UUID +uuidgen > /etc/fuel/fuel-uuid + +# Run fuel menu +[ -z "$showmenu" ] && showmenu="no" + +# Pause during bootstrap_admin_node to wait for external config +[ -z "$wait_for_external_config" ] && wait_for_external_config="no" + + +# Prepare bootstrap_admin_node config +cat > /etc/fuel/bootstrap_admin_node.conf << EOF +#Set to yes to run Fuel Setup +#Set to no to accept default settings +ADMIN_INTERFACE=${admin_interface} +showmenu=${showmenu} +wait_for_external_config=${wait_for_external_config} +EOF + +# Prepare custom /etc/issue logon banner and script for changing IP in it +cat > /etc/issue << EOF +######################################### +# Welcome to the Fuel server # +######################################### +Server is running on \m platform + +Fuel UI is available on: +https://:8443 + +Default administrator login: root +Default administrator password: r00tme + +Default Fuel UI login: admin +Default Fuel UI password: admin + +Please change root password on first login. + +EOF + + +cat >> '/etc/rc.local' << EOF +first=yes +for ip in \$(ip -o -4 addr | grep "eth." | awk '{print \$4 }' | cut -d/ -f1); do +if [ "\$first" = "yes" ]; then + ipstr="Fuel UI is available on: https://\$ip:8443" + first=no +else + ipstr=\$(printf "%s\n%25s%s" "\$ipstr" " " "https://\$ip:8443") +fi +done +tmpissue=\$(mktemp) +while read -r line; do + if [[ "\$line" =~ "Fuel UI is available on" ]]; then + echo -e "\$ipstr" >> \$tmpissue + elif [[ "\$line" =~ :8443$ ]]; then + : + else + echo -e "\$line" >> \$tmpissue + fi +done < /etc/issue +mv "\$tmpissue" /etc/issue + +EOF + + +# Unmounting source +umount -f ${SOURCE} +rm -rf ${SOURCE} + +umount -f ${FS} || true +rm -rf ${FS} + +echo "tos orphan 7" >> /etc/ntp.conf + +# Do not show error message on ntpdate failure. Customers should not be confused +# if admin node does not have access to the internet time servers. +sed -i /etc/rc.d/init.d/ntpdate -e 's/\([ $RETVAL -eq 0 ] && success || \)failure/\1success/' + +# Disabling splash +sed -i --follow-symlinks -e '/^\skernel/ s/rhgb//' /etc/grub.conf +sed -i --follow-symlinks -e '/^\skernel/ s/quiet//' /etc/grub.conf + +# Disabling console clearing +sed -i 's/getty/getty --noclear/' /etc/init/tty.conf + +# Disabling starting first console from start-ttys service +sed -i --follow-symlinks -e 's/ACTIVE_CONSOLES=.*/ACTIVE_CONSOLES=\/dev\/tty\[2-6\]/' /etc/sysconfig/init + +# Copying default bash settings to the root directory +cp -f /etc/skel/.bash* /root/ + +# Blacklist i2c_piix4 module for VirtualBox so it does not create kernel errors +[[ $(virt-what) = "virtualbox" ]] && echo "blacklist i2c_piix4" > /etc/modprobe.d/blacklist-i2c-piix4.conf + +%end
\ No newline at end of file diff --git a/build/f_isoroot/f_odlpluginbuild/Makefile b/build/f_isoroot/f_odlpluginbuild/Makefile new file mode 100644 index 000000000..a63cdadf8 --- /dev/null +++ b/build/f_isoroot/f_odlpluginbuild/Makefile @@ -0,0 +1,73 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# mskalski@mirantis.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) +ODL_BRANCH=7.0 +ODL_REPO="https://github.com/openstack/fuel-plugin-opendaylight.git" + +.PHONY: all +all: .odlbuild + +.PHONY: clean +clean: + @rm -f .odlbuild ../release/opnfv/opendaylight*.rpm opendaylight*.rpm + @rm -f $(BUILD_BASE)/gitinfo_odlplugin.txt gitinfo_odlplugin.txt + +.PHONY: release +release:.odlbuild + @rm -f ../release/opnfv/opendaylight*.rpm + @mkdir -p ../release/opnfv + @cp opendaylight*.rpm ../release/opnfv/ + cp gitinfo_odlplugin.txt $(BUILD_BASE) + cd $(BUILD_BASE) && mkdir -p ../deploy/templates/plugins && cp -rf $(TOP)/config/* ../deploy/templates/plugins +.odlbuild: + rm -rf fuel-plugin-opendaylight + sudo apt-get -y install build-essential ruby-dev rubygems-integration python-pip git rpm createrepo dpkg-dev + sudo gem install fpm + sudo pip install fuel-plugin-builder + git clone -b $(ODL_BRANCH) $(ODL_REPO) + @$(BUILD_BASE)/check_dependencies.sh fuel-plugin-opendaylight/odl_package/ubuntu/dependencies.txt + INCLUDE_DEPENDENCIES=true fpb --debug --build fuel-plugin-opendaylight/ + mv fuel-plugin-opendaylight/opendaylight*.rpm . + $(REPOINFO) -r . > gitinfo_odlplugin.txt + rm -rf fuel-plugin-opendaylight + touch .odlbuild + +############################################################################# +# Cache operations - only used when building through ci/build.sh +############################################################################# + + +# Create a unique hash to be used for getting and putting cache, based on: +# - The SHA1 hash of the HEAD on the plugin repo's $(ODL_BRANCH) +# - The contents of this Makefile +.cacheid: + git ls-remote --heads $(ODL_REPO) | grep $(ODL_BRANCH) > .cachedata + sha1sum Makefile >> .cachedata + cat .cachedata | $(CACHETOOL) getid > .cacheid + +# Clean local data related to caching - called prior to ordinary build +.PHONY: clean-cache +clean-cache: clean + rm -f .cachedata .cacheid + +# Try to download cache - called prior to ordinary build +.PHONY: get-cache +get-cache: .cacheid + @if $(CACHETOOL) check $(shell cat .cacheid); then \ + $(CACHETOOL) get $(shell cat .cacheid) | tar xf -;\ + else \ + echo "No cache item found for $(shell cat .cacheid)" ;\ + exit 0;\ + fi + +# Store cache if not already stored - called after ordinary build +.PHONY: put-cache +put-cache: .cacheid + @tar cf - .odlbuild opendaylight*.rpm gitinfo_odlplugin.txt | $(CACHETOOL) put $(shell cat .cacheid) diff --git a/build/f_isoroot/f_odlpluginbuild/config/opendaylight_config.yaml b/build/f_isoroot/f_odlpluginbuild/config/opendaylight_config.yaml new file mode 100644 index 000000000..183ef9ca9 --- /dev/null +++ b/build/f_isoroot/f_odlpluginbuild/config/opendaylight_config.yaml @@ -0,0 +1,52 @@ +opendaylight: + metadata: + enabled: true + label: OpenDaylight plugin + plugin_id: 1 + restrictions: + - cluster:net_provider != 'neutron': Only neutron is supported by OpenDaylight + toggleable: true + weight: 70 + rest_api_port: + description: Port on which ODL REST API will be available. + label: Port number + regex: + error: Invalid port number + source: ^([1-9][0-9]{0,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$ + type: text + value: '8282' + weight: 40 + use_vxlan: + description: Configure neutron to use VXLAN tunneling + label: Use vxlan + restrictions: + - action: disable + condition: networking_parameters:segmentation_type == 'vlan' + message: Neutron with GRE segmentation required + type: checkbox + value: true + weight: 20 + vni_range_end: + description: VXLAN VNI IDs range end + label: VNI range end + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10000' + weight: 31 + vni_range_start: + description: VXLAN VNI IDs range start + label: VNI range start + regex: + error: Invalid ID number + source: ^\d+$ + restrictions: + - action: hide + condition: networking_parameters:segmentation_type == 'vlan' + type: text + value: '10' + weight: 30 diff --git a/build/f_isoroot/f_repobuild/Makefile b/build/f_isoroot/f_repobuild/Makefile new file mode 100644 index 000000000..d7db2dd90 --- /dev/null +++ b/build/f_isoroot/f_repobuild/Makefile @@ -0,0 +1,86 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +SHELL := /bin/bash +TOP := $(shell pwd) +RSYNC_HOST := $(shell ./select_ubuntu_repo.sh) + + +.PHONY: all +all: nailgun + +nailgun: +# If RSYNC_CONNECT_PROG is set we need to do some magic to copy the +# keys. Make sure to have the username set in the SSH_CONNECT_PROG +# as well! + @if [ -n "${RSYNC_CONNECT_PROG}" -a ! -d /root/.ssh ]; then \ + sudo mkdir -p /root/.ssh; \ + test -d ${HOME}/.ssh && sudo find ${HOME}/.ssh -maxdepth 1 -type f -exec cp {} /root/.ssh \; ; \ + sudo bash -c "echo StrictHostKeyChecking=no > /root/.ssh/config"; \ + sudo chmod 700 /root/.ssh; \ + fi + sudo apt-get install -y rsync python python-yaml dpkg-dev openssl + rm -rf tmpiso tmpdir + mkdir tmpiso + fuseiso ${ISOCACHE} tmpiso + cp tmpiso/ubuntu/pool/main/f/fuel-createmirror/fuel-createmirror_*.deb . + fusermount -u tmpiso + rm -rf tmpiso + sudo dpkg -i fuel-createmirror_*.deb + sudo sed -i 's/DOCKER_MODE=true/DOCKER_MODE=false/' /etc/fuel-createmirror/common.cfg + sudo sed -i 's/DEBUG="no"/DEBUG="yes"/' /etc/fuel-createmirror/ubuntu.cfg + sudo sed -i "s/MIRROR_UBUNTU_HOST=\".*\"/MIRROR_UBUNTU_HOST=\"$(RSYNC_HOST)\"/" /etc/fuel-createmirror/common.cfg + rm -Rf nailgun + sudo mkdir -p /var/www + sudo su - -c /opt/fuel-createmirror-*/fuel-createmirror + sudo chmod -R 755 /var/www/nailgun + cp -Rp /var/www/nailgun . + +.PHONY: clean +clean: + @rm -rf ../release/opnfv/nailgun nailgun fuel-createmirror_6.1*.deb + +.PHONY: release +release:nailgun + @rm -Rf ../release/opnfv/nailgun + @mkdir -p ../release/opnfv + @cp -Rp nailgun ../release/opnfv/nailgun + +############################################################################# +# Cache operations - only used when building through ci/build.sh +############################################################################# + +# Create a unique hash to be used for getting and putting cache, based on: +# - Year and week (causing the cache to be rebuilt weekly) +# - The contents of this Makefile +.cacheid: + date +"Repocache %G%V" > .cachedata + sha1sum Makefile >> .cachedata + cat .cachedata | $(CACHETOOL) getid > .cacheid + +# Clean local data related to caching - called prior to ordinary build +.PHONY: clean-cache +clean-cache: clean + rm -f .cachedata .cacheid + +# Try to download cache - called prior to ordinary build +.PHONY: get-cache +get-cache: .cacheid + @if $(CACHETOOL) check $(shell cat .cacheid); then \ + $(CACHETOOL) get $(shell cat .cacheid) | tar xf -;\ + else \ + echo "No cache item found for $(shell cat .cacheid)" ;\ + exit 0;\ + fi + +# Store cache if not already stored - called after ordinary build +.PHONY: put-cache +put-cache: .cacheid + @tar cf - nailgun | $(CACHETOOL) put $(shell cat .cacheid) diff --git a/build/f_isoroot/f_repobuild/select_ubuntu_repo.sh b/build/f_isoroot/f_repobuild/select_ubuntu_repo.sh new file mode 100755 index 000000000..cb05fe136 --- /dev/null +++ b/build/f_isoroot/f_repobuild/select_ubuntu_repo.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +RSYNC="rsync -4 --contimeout 5 --no-motd --list-only" + +# try to choose close ubuntu mirror which support rsync protocol +# https://bugs.launchpad.net/fuel/+bug/1459252 + +# A minor modificiation of Michal Skalski's original Makefile version +# to only consider repos where no repo updates are in progress (as +# that may have us hanging quite a while otherwise). If no suitable +# local mirror can be found after four attempts, the default archive +# is returned instead. + +cnt=0 +while [ $cnt -lt 4 ] +do + for url in $(curl -s http://mirrors.ubuntu.com/mirrors.txt) + do + host=$(echo $url | cut -d'/' -f3) + if $RSYNC "${host}::ubuntu/." &> /dev/null + then + if ! $RSYNC "${host}::ubuntu/Archive-Update-in-Progress*" &> /dev/null + then + echo "$host" + exit 0 + fi + fi + done + cnt=$[cnt + 1] + sleep 15 +done +echo "archive.ubuntu.com" + diff --git a/build/fuel-main_5.patch b/build/fuel-main_5.patch new file mode 100644 index 000000000..ec75626d0 --- /dev/null +++ b/build/fuel-main_5.patch @@ -0,0 +1,19 @@ +*** prepare-build-env.sh.orig Tue Sep 8 10:29:08 2015 +--- prepare-build-env.sh Tue Sep 8 10:30:21 2015 +*************** +*** 43,49 **** + GEMPKG="ruby ruby-dev" + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 1D2B45A2 + echo "deb http://mirror.fuel-infra.org/devops/ubuntu/ ./" | sudo tee /etc/apt/sources.list.d/fuel-devops.list +! sudo apt-get update && sudo apt-get -y install nodejs nodejs-legacy npm + ;; + + precise) +--- 43,49 ---- + GEMPKG="ruby ruby-dev" + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 1D2B45A2 + echo "deb http://mirror.fuel-infra.org/devops/ubuntu/ ./" | sudo tee /etc/apt/sources.list.d/fuel-devops.list +! sudo apt-get update && sudo apt-get -y install nodejs nodejs-legacy npm dosfstools xorriso + ;; + + precise) diff --git a/build/fuel-main_6.patch b/build/fuel-main_6.patch new file mode 100644 index 000000000..2659e2d17 --- /dev/null +++ b/build/fuel-main_6.patch @@ -0,0 +1,30 @@ +*** prepare-build-env.sh.orig Mon Oct 19 13:28:30 2015 +--- prepare-build-env.sh Mon Oct 19 13:29:10 2015 +*************** +*** 87,92 **** +--- 87,93 ---- + echo "Docker is running." + else + echo "Process is not running, starting it..." ++ sudo sh -c 'echo DOCKER_OPTS=\"--dns 8.8.8.8 --dns 8.8.4.4 --bip 172.45.0.1/24\" >> /etc/default/docker*' + sudo service docker start + fi + else +*************** +*** 102,108 **** + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 + # Install docker + sudo apt-get update +! sudo apt-get -y install lxc-docker-1.5.0 + fi + + # Install software +--- 103,110 ---- + sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9 + # Install docker + sudo apt-get update +! sudo sh -c 'echo DOCKER_OPTS=\"--dns 8.8.8.8 --dns 8.8.4.4 --bip 172.45.0.1/24\" > /etc/default/docker' +! sudo apt-get -y -o Dpkg::Options::="--force-confold" install lxc-docker-1.5.0 + fi + + # Install software diff --git a/build/install/apt-ftparchive-deb.conf b/build/install/apt-ftparchive-deb.conf new file mode 100644 index 000000000..0d15aec6f --- /dev/null +++ b/build/install/apt-ftparchive-deb.conf @@ -0,0 +1,35 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +Dir { + ArchiveDir "."; +}; + +TreeDefault { + Directory "pool"; +}; + +BinDirectory "pool/main" { + Packages "dists/trusty/main/binary-amd64/Packages"; + BinOverride "./indices/override.trusty.main"; + ExtraOverride "./indices/override.trusty.extra.main"; +}; + +Default { + Packages { + Extensions ".deb"; + Compress ". gzip"; + }; +}; + +Contents { + Compress "gzip"; +}; + diff --git a/build/install/apt-ftparchive-release.conf b/build/install/apt-ftparchive-release.conf new file mode 100644 index 000000000..02706bd7d --- /dev/null +++ b/build/install/apt-ftparchive-release.conf @@ -0,0 +1,18 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +APT::FTPArchive::Release::Origin "Ubuntu"; +APT::FTPArchive::Release::Label "Ubuntu"; +APT::FTPArchive::Release::Suite "trusty"; +APT::FTPArchive::Release::Version "1.04"; +APT::FTPArchive::Release::Codename "trusty"; +APT::FTPArchive::Release::Architectures "amd64"; +APT::FTPArchive::Release::Components "main"; +APT::FTPArchive::Release::Description "Ubuntu Trusty Tahr 14.04 LTS"; diff --git a/build/install/apt-ftparchive-udeb.conf b/build/install/apt-ftparchive-udeb.conf new file mode 100644 index 000000000..3b5b239a6 --- /dev/null +++ b/build/install/apt-ftparchive-udeb.conf @@ -0,0 +1,33 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +Dir { + ArchiveDir "."; +}; + +TreeDefault { + Directory "pool"; +}; + +BinDirectory "pool/debian-installer" { + Packages "dists/trusty/main/debian-installer/binary-amd64/Packages"; + BinOverride "./indices/override.trusty.main.debian-installer"; +}; + +Default { + Packages { + Extensions ".udeb"; + Compress ". gzip"; + }; +}; + +Contents { + Compress "gzip"; +}; diff --git a/build/install/install.sh b/build/install/install.sh new file mode 100755 index 000000000..6155a4162 --- /dev/null +++ b/build/install/install.sh @@ -0,0 +1,481 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + rc=$? + + cd /tmp + + if [ -n "$TMP_HOSTMOUNT" ]; then + if [ -d "$TMP_HOSTMOUNT" ]; then + fusermount -u $TMP_HOSTMOUNT + rmdir $TMP_HOSTMOUNT + fi + fi + + if [ -d "$TMP_OLDISO" ]; then + fusermount -u $TMP_OLDISO + rmdir $TMP_OLDISO + fi + + if [ -f "$CONF" ]; then + rm $CONF + fi + + if [ -d "$TMP_ISOPUPPET" ]; then + rm -Rf $TMP_ISOPUPPET + fi +} + +get_deb_name() { + ar p $1 control.tar.gz | tar xzO ./control | grep "^Package:.* " | sed 's/.* //' + if [ $PIPESTATUS -ne 0 ]; then + echo "Error in get_deb_name($1)" + exit 1 + fi +} + +get_deb_rev() { + ar p $1 control.tar.gz | tar xzO ./control | grep "^Version:.* " | sed 's/.* //' + if [ $PIPESTATUS -ne 0 ]; then + echo "Error in get_deb_rev($1)" + exit 1 + fi +} + + +# Added logic for ".orig" files: +# 1. Is there an .orig file for the new file? +# 2. If the file is not present in base ISO -> Error! +# 3. If the file is changed i base ISO -> Error! (need manual rebase) +# 4. If there is no .orig file, but file is present in base ISO: Error! +verify_orig_files() { + OLDDIR=$1 + NEWDIR=$2 + + pushd $NEWDIR >/dev/null + for f in $(find * -type f -name '*.orig') + do + origfile=$NEWDIR/$f + oldfile=$OLDDIR/$(echo $f | sed 's/.orig$//') + newfile=$NEWDIR/$(echo $f | sed 's/.orig$//') + + origfile=${newfile}.orig + # If no corresponding base file, error + if [ ! -f $oldfile ]; then + printf "\n\n\n\n" + echo "Error: found ${newfile} but no" + echo "Error: ${oldfile}" + echo "Error: Manual rebase is needed!" + printf "\n\n\n\n" + exit 1 + fi + + # If orig file differs from base file, error + if ! diff -q $origfile $oldfile > /dev/null; then + printf "\n\n\n\n" + echo "Error: $origfile differs from" + echo "Error: $oldfile!" + echo "Error: Manual rebase is needed!" + printf "\n\n\n\n" + exit 1 + fi + + done + + + # Check that there we're not overwriting oldfiles without having a ".orig" copy + for f in $(find * -type f ! -name '*.orig') + do + newfile=$NEWDIR/$(echo $f | sed 's/.orig$//') + origfile=${newfile}.orig + oldfile=$OLDDIR/$f + if [ -f $oldfile ]; then + if [ ! -f $origfile ]; then + printf "\n\n\n\n" + echo "Error: Will overwrite $oldfile, but there is no" + echo "Error: $origfile!" + echo "Error: You need to create the `basename $origfile`!" + printf "\n\n\n\n" + exit 1 + fi + fi + done + + + popd >/dev/null +} + +prep_make_live() { + DEST=$TMP_HOSTMOUNT + REPO=$DEST/var/www/nailgun/ubuntu/fuelweb/x86_64 + echo "Live install" + ssh-copy-id root@$FUELHOST + sshfs root@1${FUELHOST}:/ $TMP_HOSTMOUNT + + if [ -f $REPO/dists/trusty/main/binary-amd64/Packages.backup ]; then + echo "Error - found backup file for Packages!" + exit 1 + fi + + if [ -f $REPO/dists/trusty/main/binary-amd64/Packages.gz.backup ]; then + echo "Error - found backup file for Packages.gz!" + exit 1 + fi + + if [ -f $REPO/dists/trusty/Release.backup ]; then + echo "Error - found backup file for Release!" + exit 1 + fi + + if [ -d $DEST/etc/puppet.backup ]; then + echo "Error - found backup file for Puppet!" + exit 1 + fi + + cp $REPO/dists/trusty/main/binary-amd64/Packages $REPO/dists/trusty/main/binary-amd64/Packages.backup + cp $REPO/dists/trusty/main/binary-amd64/Packages.gz $REPO/dists/trusty/main/binary-amd64/Packages.gz.backup + cp $REPO/dists/trusty/Release $REPO/dists/trusty/Release.backup + cp -Rvp $DEST/etc/puppet $DEST/etc/puppet.backup +} + +post_make_live() { + if [ -d $TOP/release/puppet/modules ]; then + echo "Installing into Puppet:" + cd $TOP/release/puppet/modules + if [ `ls -1 | wc -l` -gt 0 ]; then + for dir in * + do + echo " $dir" + cp -Rp $dir $DEST/etc/puppet/modules + done + fi + fi +} + +make_live() { + prep_make_live + copy_packages + post_make_live +} + + +prep_make_iso() { + DEST=$TOP/newiso + REPO=$DEST/ubuntu + echo "Making ISO..." + echo "Unpack of old ISO..." + if [ -d newiso ]; then + chmod -R 755 newiso + rm -rf newiso + fi + mkdir newiso + fusermount -u $TMP_OLDISO 2>/dev/null || cat /dev/null + fuseiso -p $ORIGISO $TMP_OLDISO + sleep 1 + cd $TMP_OLDISO + find . | cpio -pd $TOP/newiso + cd .. + fusermount -u $TMP_OLDISO + rm -Rf $TMP_OLDISO + chmod -R 755 $TOP/newiso +} + +make_iso_image() { + echo "Making ISO..." + cd $DEST + find . -name TRANS.TBL -exec rm {} \; + rm -rf rr_moved + + mkisofs --quiet -r -V "$VOLUMEID" -publisher "$PUBLISHER" \ + -p `git rev-parse --verify HEAD` -J -R -b isolinux/isolinux.bin \ + -no-emul-boot \ + -boot-load-size 4 -boot-info-table \ + --hide-rr-moved \ + -x "lost+found" -o $NEWISO . + + isoinfo -d -i $NEWISO +} + +# iso_copy_puppet: Create a new puppet-slave.tgz for the iso +iso_copy_puppet() { + echo "Installing into Puppet..." + mkdir -p $TMP_ISOPUPPET/release/puppet + cd $TMP_ISOPUPPET/release/puppet + tar xzf $DEST/puppet-slave.tgz + cd $TOP/release/puppet/modules + + # Remove all .orig files before copying as they now have been verfied + + if [ -d $TOP/release/puppet/modules ]; then + if [ `ls -1 | wc -l` -gt 0 ]; then + verify_orig_files $TMP_ISOPUPPET/release/puppet $TOP/release/puppet/modules + find $TOP/release/puppet/modules -type f -name '*.orig' -exec rm {} \; + for dir in $TOP/release/puppet/modules/* + do + echo " $dir" + cp -Rp $dir $TMP_ISOPUPPET/release/puppet + done + fi + fi + + cd $TMP_ISOPUPPET/release/puppet + tar czf $DEST/puppet-slave.tgz . + cd $TOP + rm -Rf $TMP_ISOPUPPET +} + +# iso_modify_image: Add/patch files in the ISO root +iso_modify_image () { + # TODO: Add logic for ".orig" files (hey! make a function!), which would look + # something like: + # 1. Is there an .orig file? + # 2. If the file is not present in origiso -> Error exit + # 3. If the file is changed in origiso -> Error exit (need manual rebase) + # 4. Otherwise continue, but don't copy orig file (or maybe we should?) + # ... and corresponding reverse logic: + # 1. If there is no .orig file, but file is present in origiso -> Error exit + echo "Modify ISO files (wild copy)..." + + verify_orig_files $DEST $TOP/release/isoroot + # Remove all .orig files before copying as they now have been verfied + find $TOP/release/isoroot -type f -name '*.orig' -exec rm {} \; + + cd $TOP/release/isoroot + cp -Rvp . $DEST + + # Add all Git info files + sort $TOP/gitinfo*.txt > $DEST/gitinfo.txt + cp $DEST/gitinfo.txt $REPORTFILE +} + +make_iso() { + prep_make_iso + copy_packages + #iso_copy_puppet + iso_modify_image + make_iso_image +} + +copy_packages() { + echo "Copying Debian packages..." + cd $TOP/release/packages/ubuntu/pool/debian-installer + + for udeb in `ls -1 | grep '\.udeb$'` + do + echo " $udeb" + cp $udeb $REPO/pool/debian-installer + echo "Did not expect a package here, not supported" + exit 1 + done + + cd $TOP/release/packages/ubuntu/pool/main + for deb in `ls -1 | grep '\.deb$'` + do + echo " $deb" + cp $deb $REPO/pool/main + echo "Did not expect a package here, not supported" + exit 1 + done + + echo "Running Fuel package patch file" + pushd $REPO/pool/main > /dev/null + + for line in `cat $TOP/apply_patches | grep -v "^#" | grep -v "^$"`; do + echo "Line is $line" + echo "Did not expect a line here, not supported" + exit 1 + ref=`echo $line | cut -d '>' -f 1` + origpkg=`echo $line| cut -d '>' -f 2` + url=`echo $line | cut -d '>' -f 3` + + if [ -z "$origpkg" ]; then + echo "Error: No origpkg for patching" + exit 1 + fi + + if [ -z "$url" ]; then + echo "Error: No url for patching" + exit 1 + fi + + if [ -z "$ref" ]; then + echo "Error: No reference text for patching" + exit 1 + fi + + echo "CM: Patching Fuel package for $ref" | tee -a $REPORTFILE + echo "CM: Replacing package $origpkg with $url" | tee -a $REPORTFILE + oldrev=`get_deb_rev $origpkg` + rm $origpkg + wget --quiet $url + topkg=`basename $url` + echo "CM: MD5 of new package:" | tee -a $REPORTFILE + md5sum $topkg | tee -a $REPORTFILE + + patchname=`get_deb_name $topkg` + patchrev=`get_deb_rev $topkg` + echo "Correcting dependencies towards $patchname rev $patchrev - old rev $oldrev" | tee -a $REPORTFILE + $TOP/patch-packages/tools/correct_deps $patchname $oldrev $patchrev | tee -a $REPORTFILE + if [ $PIPESTATUS -ne 0 ]; then + exit 1 + fi + done + + printf "Done running Fuel patch file\n\n" + echo "Running add packages file" + for line in `cat $TOP/add_opnfv_packages | grep -v "^#" | grep -v "^$"`; do + echo "Line is $line" + echo "Did not expect a line here, not supported" + exit 1 + ref=`echo $line | cut -d '>' -f 1` + origpkg=`echo $line| cut -d '>' -f 2` + url=`echo $line | cut -d '>' -f 3` + + if [ -z "$origpkg" ]; then + echo "Error: No origpkg for patching" + exit 1 + fi + + if [ -z "$url" ]; then + echo "Error: No url for patching" + exit 1 + fi + + if [ -z "$ref" ]; then + echo "Error: No reference text for patching" + exit 1 + fi + + if [ "$origpkg" != "NONE" ]; then + echo "CM: Patching added package for $ref" | tee -a $REPORTFILE + echo "CM: Replacing package $origpkg with $url" | tee -a $REPORTFILE + oldrev=`get_deb_rev $origpkg` + rm $origpkg + else + echo "CM: Adding previoulsy uninstalled package for $ref" tee -a $REPORTFILE + fi + wget --quiet $url + topkg=`basename $url` + echo "CM: MD5 of new package:" | tee -a $REPORTFILE + md5sum $topkg | tee -a $REPORTFILE + if [ "$origpkg" != "NONE" ]; then + patchname=`get_deb_name $topkg` + patchrev=`get_deb_rev $topkg` + echo "Correcting dependencies towards $patchname rev $patchrev - old rev $oldrev" | tee -a $REPORTFILE + $TOP/patch-packages/tools/correct_deps $patchname $oldrev $patchrev | tee -a $REPORTFILE + if [ $PIPESTATUS -ne 0 ]; then + exit 1 + fi + fi + done + printf "Done running add packages file\n\n" + + popd > /dev/null + + if [ -f $TOP/patch-packages/release/patch-replacements ]; then + echo "Applying package patches" | tee -a $REPORTFILE + pushd $REPO/pool/main > /dev/null + printf "\n\n" | tee -a $REPORTFILE + for line in `cat $TOP/patch-packages/release/patch-replacements` + do + echo "Did not expect a line here, not supported" + exit 1 + frompkg=`echo $line | cut -d ">" -f 1` + topkg=`echo $line | cut -d ">" -f 2` + echo "CM: Applying patch to $frompkg" | tee -a $REPORTFILE + echo "CM: New package rev after patch: $topkg" | tee -a $REPORTFILE + + if [ ! -f $frompkg ]; then + echo "Error: Can't find $frompkg in repo" + exit 1 + else + oldrev=`get_deb_rev $frompkg` + echo "Removing $frompkg from repo" + rm $frompkg + fi + + if [ ! -f $TOP/patch-packages/release/packages/$topkg ]; then + echo "Error: Can't find $topkg in patch release" + exit 1 + else + echo "Adding $topkg to repo" + cp $TOP/patch-packages/release/packages/$topkg . + fi + + patchname=`get_deb_name $topkg` + patchrev=`get_deb_rev $topkg` + echo "Correcting dependencies towards $patchname rev $patchrev - old rev $oldrev" | tee -a $REPORTFILE + $TOP/patch-packages/tools/correct_deps $patchname $oldrev $patchrev | tee -a $REPORTFILE + if [ $PIPESTATUS -ne 0 ]; then + exit 1 + fi + done + popd > /dev/null + fi + + echo "Generating metadata..." + pushd $REPO > /dev/null + + # The below methods are from 15B + APT_REL_CONF="$TOP/install/apt-ftparchive-release.conf" + APT_DEB_CONF="$TOP/install/apt-ftparchive-deb.conf" + APT_UDEB_CONF="$TOP/install/apt-ftparchive-udeb.conf" + + echo Not running echo apt-ftparchive -c "${APT_REL_CONF}" generate "${APT_DEB_CONF}" + echo Not running apt-ftparchive -c "${APT_REL_CONF}" generate "${APT_DEB_CONF}" + echo Not running apt-ftparchive generate "${APT_UDEB_CONF}" + echo Not running apt-ftparchive generate "${APT_UDEB_CONF}" + + # Fuel also needs this index file + # cat dists/trusty/main/binary-amd64/Packages | \ + # awk '/^Package:/{pkg=$2} + # /^Version:/{print pkg ": \"" $2 "\""}' > ubuntu-versions.yaml + # cp ubuntu-versions.yaml $DEST + + # apt-ftparchive -c "${APT_REL_CONF}" release dists/trusty/ > dists/trusty/Release + # gzip -9cf dists/trusty/Release > dists/trusty/Release.gz + + popd > /dev/null + +} + + +############################################################################# + +trap my_exit EXIT + +CONF=`mktemp /tmp/XXXXXXX` +MODE=$1 +TOP=`pwd` + +if [ $MODE = "iso" ]; then + PUBLISHER="OPNFV" + TMP_OLDISO=`mktemp -d /tmp/XXXXXXX` + TMP_ISOPUPPET=`mktemp -d /tmp/XXXXXXX` + ORIGISO=$2 + NEWISO=$3 + VOLUMEID="$4 $5" + REPORTFILE="${NEWISO}.txt" + echo "Opening reportfile at $REPORTFILE" + touch $REPORTFILE + if [ ! -f $ORIGISO ]; then + echo "Can't find original iso at $ORIGISO" + rm $CONF + exit 1 + fi + + make_iso +else + echo "Unknown mode: $MODE" + exit 1 +fi diff --git a/build/install/uninstall.sh b/build/install/uninstall.sh new file mode 100755 index 000000000..a9e74bc39 --- /dev/null +++ b/build/install/uninstall.sh @@ -0,0 +1,79 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + cd /tmp + if [ -d "$MOUNT" ]; then + fusermount -u $MOUNT + rmdir $MOUNT + fi +} +trap my_exit EXIT + +echo "Live uninstall is currently disabled as it is not tested" +exit 1 + +TOP=`pwd` +MOUNT=`mktemp -d /tmp/XXXXXXX` +ssh-copy-id root@10.20.0.2 +sshfs root@10.20.0.2:/ $MOUNT + +DEST=$MOUNT +REPO=$DEST/var/www/nailgun/ubuntu/fuelweb/x86_64 + +cd $REPO +if [ ! -f $REPO/dists/trusty/main/binary-amd64/Packages.backup ]; then + echo "Error - didn't find backup file for Packages!" + exit 1 +fi + +if [ ! -f $REPO/dists/trusty/main/binary-amd64/Packages.gz.backup ]; then + echo "Error - didn't find backup file for Packages.gz!" + exit 1 +fi + +if [ ! -f $REPO/dists/trusty/Release.backup ]; then + echo "Error - didn't find backup file for Release!" + exit 1 +fi + +if [ ! -f $DEST/etc/puppet/manifests/site.pp.backup ]; then + echo "Error - didn't find backup file for site.pp!" + exit 1 +fi + +echo "Removing Debian packages:" +cd $TOP/release/pool/main +for deb in *.deb +do + echo " $deb" + rm -Rf $REPO/pool/main/$deb +done +cd $REPO + +echo "Removing Puppet modules:" +cd $TOP/puppet/modules +for dir in * +do + echo " $dir" + rm -Rf $DEST/etc/puppet/modules/$dir +done +cd $REPO + +echo "Restoring backups of datafiles" + +rm -f $REPO/dists/trusty/main/binary-amd64/Packages $REPO/dists/trusty/main/binary-amd64/Packages.gz +rm -f $REPO/dists/trusty/Release $DEST/etc/puppet/manifests/site.pp +mv $REPO/dists/trusty/main/binary-amd64/Packages.backup $REPO/dists/trusty/main/binary-amd64/Packages +mv $REPO/dists/trusty/main/binary-amd64/Packages.gz.backup $REPO/dists/trusty/main/binary-amd64/Packages.gz +mv $REPO/dists/trusty/Release.backup $REPO/dists/trusty/Release +mv $DEST/etc/puppet/manifests/site.pp.backup $DEST/etc/puppet/manifests/site.pp diff --git a/build/patch-packages/Makefile b/build/patch-packages/Makefile new file mode 100644 index 000000000..339c9e7cf --- /dev/null +++ b/build/patch-packages/Makefile @@ -0,0 +1,26 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +SUBDIRS := +SUBCLEAN = $(addsuffix .clean,$(SUBDIRS)) + +.PHONY: $(SUBDIRS) $(SUBCLEAN) clean +$(SUBDIRS): + @mkdir -p release/packages + ORIGISO=$(ORIGISO) REVSTATE=$(REVSTATE) $(MAKE) -C $@ -f Makefile release + +release: $(SUBDIRS) + @echo $(ORIGISO) + +clean: $(SUBCLEAN) + @rm -Rf release + +$(SUBCLEAN): %.clean: + $(MAKE) -C $* -f Makefile clean diff --git a/build/patch-packages/tools/correct_deps b/build/patch-packages/tools/correct_deps new file mode 100755 index 000000000..cfb7d538f --- /dev/null +++ b/build/patch-packages/tools/correct_deps @@ -0,0 +1,78 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +patch_package () { + deb=$1 + pkgdep=$2 + newrev=$3 + + + tmpdir=`mktemp -d /tmp/patchXXXXX` + + cp $deb $tmpdir + pushd $tmpdir > /dev/null + + mkdir -p repack + dpkg -x $deb repack + + mkdir -p repack/DEBIAN + dpkg -e $deb repack/DEBIAN + + + pushd repack/DEBIAN > /dev/null + + echo "Before: `cat control | grep '^Depends:'`" + sed -i "s/$pkgdep (\([^ ]*\) [^)]*)/$pkgdep (\1 $newrev)/" control + echo "After: `cat control | grep '^Depends:'`" + popd > /dev/null + + fakeroot dpkg-deb --build repack + + popd > /dev/null + + cp $tmpdir/repack.deb $deb + rm -Rf $tmpdir +} + +# Name of package for which to check dependencies to +PKGDEP=$1 +# The old revision of the package in question +OLDREV=$2 +# The new revision of the package in question +NEWREV=$3 + +if [ -z "$PKGDEP" ]; then + echo "No package dependency name" + exit 1 +fi + +if [ -z "$OLDREV" ]; then + echo "No old rev" + exit 1 +fi + +if [ -z "$NEWREV" ]; then + echo "No new rev" + exit 1 +fi + + +for deb in *.deb +do + ar p $deb control.tar.gz | tar xzO ./control | grep -q "^Depends:.* ${PKGDEP} ([^ ]* ${OLDREV})" + if [ $? -eq 0 ]; then + name=`ar p $deb control.tar.gz | tar xzO ./control | grep "^Package:.* " | sed 's/.* //'` + echo "**** Changing dependencies line in $deb ($name) ****" + patch_package $deb $PKGDEP $NEWREV + fi +done + diff --git a/build/patch-packages/tools/deb_pack b/build/patch-packages/tools/deb_pack new file mode 100755 index 000000000..f5d42dec3 --- /dev/null +++ b/build/patch-packages/tools/deb_pack @@ -0,0 +1,63 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + + if [ -d "$ISOROOT" ]; then + fusermount -u $ISOROOT + fi +} + +ME=$(basename $0) + +trap my_exit EXIT + +REV="$(echo $1 | tr '_' '-')" +if [ -z "$REV" ]; then + echo "$ME: Error - no revision info provided" + exit 1 +fi + +if [ ! -d package ]; then + echo "$ME: Error - package directory does not exist" + exit 1 +fi + +echo "Stepping revision number to $REV" + + +revision_step () +{ + REV=$1 + + sed -i "s/^\(Version:.*$\)/\1-eri$REV/" package/DEBIAN/control +} + +md5sum_gen () +{ + pushd package + find * -type f | grep -v "^DEBIAN/" | xargs md5sum | sort > DEBIAN/md5sums + popd +} + +revision_step $REV +md5sum_gen +fakeroot dpkg-deb --build package +PKGNAME=`grep "^Package: " package/DEBIAN/control | awk '{ print $2 }'` +PKGREV=`grep "^Version: " package/DEBIAN/control | awk '{ print $2 }'` +mv package.deb ${PKGNAME}_${PKGREV}.deb + +ORIGPKG=`cat .package` + +# Add patch into file read by install.sh +echo "$ORIGPKG>${PKGNAME}_${PKGREV}.deb" > patch-replacements + diff --git a/build/patch-packages/tools/deb_unpack b/build/patch-packages/tools/deb_unpack new file mode 100755 index 000000000..aaa60b743 --- /dev/null +++ b/build/patch-packages/tools/deb_unpack @@ -0,0 +1,58 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + + if [ -d "$ISOROOT" ]; then + fusermount -u $ISOROOT + fi +} + +ME=$(basename $0) + +trap my_exit EXIT + + +if [ -z "$1" ]; then + echo "$ME: Error - No package specified" + exit 1 +fi + +if [ -z "$2" ]; then + echo "$ME: Error - No ISO path specified" + exit 1 +fi + +DEB=$1 +ORIGISO=$2 +DEST=package + +if [ -e $DEST -o -d $DEST ]; then + echo "$ME: Error - $DEST already exists" + exit 1 +fi + +ISOROOT=`mktemp -d /tmp/XXXXXXX` +fuseiso -p $ORIGISO $ISOROOT +sleep 1 + +if [ ! -f $ISOROOT/ubuntu/pool/main/$DEB ];then + echo "Could not find package $DEB in source ISO!" +fi + +mkdir -p $DEST +dpkg -x $ISOROOT/ubuntu/pool/main/$DEB $DEST + +mkdir -p $DEST/DEBIAN +dpkg -e $ISOROOT/ubuntu/pool/main/$DEB $DEST/DEBIAN + +echo $DEB > .package
\ No newline at end of file diff --git a/build/patch-packages/tools/udeb_pack b/build/patch-packages/tools/udeb_pack new file mode 100755 index 000000000..e961a7320 --- /dev/null +++ b/build/patch-packages/tools/udeb_pack @@ -0,0 +1,38 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + + if [ -d "$ISOROOT" ]; then + fusermount -u $ISOROOT + fi +} + +ME=$(basename $0) + +trap my_exit EXIT + +if [ ! -d udebPackage ]; then + echo "$ME: Error - package directory does not exist" + exit 1 +fi + +echo "Stepping revision number to $REV" + + +fakeroot dpkg-deb --build -Zgzip udebPackage +PKGNAME=`grep "^Package: " udebPackage/DEBIAN/control | awk '{ print $2 }'` +PKGREV=`grep "^Version: " udebPackage/DEBIAN/control | awk '{ print $2 }'` +ARCH=`grep "^Architecture: " udebPackage/DEBIAN/control | awk '{ print $2 }'` +mv udebPackage.deb ${PKGNAME}_${PKGREV}_${ARCH}.udeb + +ORIGPKG=`cat .udebpackage` diff --git a/build/patch-packages/tools/udeb_unpack b/build/patch-packages/tools/udeb_unpack new file mode 100755 index 000000000..ed9cd21aa --- /dev/null +++ b/build/patch-packages/tools/udeb_unpack @@ -0,0 +1,58 @@ +#!/bin/bash -e +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + + +my_exit() { + + if [ -d "$ISOROOT" ]; then + fusermount -u $ISOROOT + fi +} + +ME=$(basename $0) + +trap my_exit EXIT + + +if [ -z "$1" ]; then + echo "$ME: Error - No package specified" + exit 1 +fi + +if [ -z "$2" ]; then + echo "$ME: Error - No ISO path specified" + exit 1 +fi + +DEB=$1 +ORIGISO=$2 +DEST=udebPackage + +if [ -e $DEST -o -d $DEST ]; then + echo "$ME: Error - $DEST already exists" + exit 1 +fi + +ISOROOT=`mktemp -d /tmp/XXXXXXX` +fuseiso -p $ORIGISO $ISOROOT +sleep 1 + +if [ ! -f $ISOROOT/ubuntu/pool/debian-installer/$DEB ];then + echo "Could not find package $DEB in source ISO!" +fi + +mkdir -p $DEST +dpkg -x $ISOROOT/ubuntu/pool/debian-installer/$DEB $DEST + +mkdir -p $DEST/DEBIAN +dpkg -e $ISOROOT/ubuntu/pool/debian-installer/$DEB $DEST/DEBIAN + +echo $DEB > .udebpackage diff --git a/build/patch-packages/tr_example/Makefile b/build/patch-packages/tr_example/Makefile new file mode 100644 index 000000000..b7cab3590 --- /dev/null +++ b/build/patch-packages/tr_example/Makefile @@ -0,0 +1,30 @@ +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +TOP := $(shell pwd) + +.PHONY: all +all: + +.PHONY: clean +clean: + @rm -rf package + @rm -rf *.deb + @rm -rf patch-replacements + @rm -rf .package + +.PHONY: release +release: + ../tools/deb_unpack python-oslo.messaging_1.3.0-fuel5.1~mira4_all.deb $(ORIGISO) + @mkdir -p package/etc + @echo "Hello, world" > package/etc/hello.txt + ../tools/deb_pack $(REVSTATE) + @cp *.deb ../release/packages + @cat patch-replacements >> ../release/patch-replacements diff --git a/build/repo_info.sh b/build/repo_info.sh new file mode 100755 index 000000000..347ede7f7 --- /dev/null +++ b/build/repo_info.sh @@ -0,0 +1,63 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2015 Ericsson AB and others. +# stefan.k.berg@ericsson.com +# jonas.bjurel@ericsson.com +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +usage() { + cat <<EOF +Usage: `basename $0` [-r] <path> + + -r + Recursively list all repos found starting at <path> + -h + Display help text +EOF +} + +repoinfo() { + repotop=$(git -C $1 rev-parse --show-toplevel) + origin=$(git -C $repotop config --get remote.origin.url) + sha1=$(git -C $repotop rev-parse HEAD) + echo "$origin: $sha1" +} + + +if [ $# -eq 2 ]; then + case $1 in + -r) + RECURSE=1 + shift + ;; + -h) + usage + exit 0 + ;; + *) + echo "Error, argument $1 not known" >&2 + usage + exit 1 + esac +fi + +if [ $# -gt 1 ]; then + echo "Error, too many arguments" >&2 + usage + exit 1 +fi + +abspath=$(readlink -f $1) + +if [ -n "$RECURSE" ]; then + for dir in $(find $abspath -type d -name .git) + do + repoinfo $(readlink -f $dir/..) + done +else + repoinfo $abspath +fi |