diff --git a/tinyipa/.gitignore b/tinyipa/.gitignore new file mode 100644 index 0000000..1e6b193 --- /dev/null +++ b/tinyipa/.gitignore @@ -0,0 +1,13 @@ +*.gz +*.zip +*.tar.gz +tinyipabuild +tinyipafinal +*.vmlinuz +vmlinuz64 +*.sha256 +*.iso +*.tcz* +squashfs-root +syslinux* +newiso diff --git a/tinyipa/Makefile b/tinyipa/Makefile new file mode 100644 index 0000000..ad0bf47 --- /dev/null +++ b/tinyipa/Makefile @@ -0,0 +1,45 @@ +.PHONY: default all dependencies build finalise addssh iso clean clean_build clean_iso +default: dependencies build finalise instance-images + +all: dependencies build finalise iso instance-images + +dependencies: + ./install-deps.sh + +build: + ./build-tinyipa.sh + +finalise: + ./finalise-tinyipa.sh + +addssh: + ./add-ssh-tinyipa.sh + +iso: + ./build-iso.sh + +instance-images: + ./build-instance-images.sh + +clean: clean_build clean_iso + +clean_build: + sudo -v + sudo rm -rf tinyipabuild + sudo rm -rf tinyipafinal + sudo rm -rf tinyipaaddssh + rm -f *tinyipa*.vmlinuz + rm -f *tinyipa*.gz + rm -f *tinyipa*.sha256 + rm -f build_files/corepure64.gz + rm -f build_files/vmlinuz64 + rm -f build_files/*.tcz + rm -f build_files/*.tcz.* + rm -f tiny-instance-part*.img + rm -f tiny-instance-uec*.tar.gz + +clean_iso: + rm -rf newiso + rm -f build_files/syslinux-4.06.tar.gz + rm -rf build_files/syslinux-4.06 + rm -f tinyipa.iso diff --git a/tinyipa/README.rst b/tinyipa/README.rst new file mode 100644 index 0000000..90a13e6 --- /dev/null +++ b/tinyipa/README.rst @@ -0,0 +1,146 @@ +============================= +Tiny Core Ironic Python Agent +============================= + +Build script requirements +------------------------- +For the main build script: + +* wget +* pip +* unzip +* sudo +* awk +* mksquashfs + +For building an ISO you'll also need: + +* genisoimage + +Instructions: +------------- +To create a new ramdisk, run:: + + make + +or:: + + ./build-tinyipa.sh && ./finalise-tinyipa.sh + +This will create two new files once completed: + +* tinyipa.vmlinuz +* tinyipa.gz + +These are your two files to upload to glance for use with Ironic. + +Building an ISO from a previous make run: +----------------------------------------- +Once you've built tinyipa it is possible to pack it into an ISO if required. To +create a bootable ISO, run:: + + make iso + +or:: + +./build-iso.sh + +This will create one new file once completed: + +* tinyipa.iso + +To build a fresh ramdisk and build an iso from it: +-------------------------------------------------- +Run:: + + make all + +To clean up the whole build environment run: +-------------------------------------------- +Run:: + + make clean + +For cleaning up just the iso or just the ramdisk build:: + + make clean_iso + +or:: + + make clean_build + +Advanced options +---------------- + +(De)Optimizing the image +~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want the build script to preinstall everything into the ramdisk, +instead of loading some things at runtime (this results in a slightly bigger +ramdisk), before running make or build-tinyipa.sh run:: + + export BUILD_AND_INSTALL_TINYIPA=true + +By default, building TinyIPA will compile most of the Python code to +optimized ``*.pyo`` files, completely remove most of ``*.py`` and ``*.pyc`` +files, and run ironic-python-agent with ``PYTHONOPTIMIZE=1`` +to save space on the ramdisk. +If instead you want a normal Python experience inside the image, +for example for debugging/hacking on IPA in a running ramdisk, +before running make or build-tinyipa.sh run:: + + export PYOPTIMIZE_TINYIPA=false + + +Enabling/disabling SSH access to the ramdisk +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default tinyipa will be built with OpenSSH server installed but no +public SSH keys authorized to access it. + +If you want to enable SSH access to the image, set ``AUTHORIZE_SSH`` variable +in your shell before building the tinyipa:: + + export AUTHORIZE_SSH=true + +By default it will use public RSA or DSA keys of the user running the build. +To provide other public SSH key, export path to it in your shell before +building tinyipa as follows:: + + export SSH_PUBLIC_KEY= + +If you want to disable SSH altogether, set ``INSTALL_SSH`` variable in your +shell to ``false`` before building the tinyipa:: + + export INSTALL_SSH=false + +You can also rebuild an already built tinyipa image by using ``addssh`` make +tagret:: + + make addssh + +This will fetch the pre-built tinyipa image from "tarballs.openstack.org" +using the version specified as ``BRANCH_NAME`` shell variable as described +above, or it may use an already downloaded ramdisk image if path to it is set +as ``TINYIPA_RAMDISK_FILE`` shell variable before running this make target. +It will install and configure OpenSSH if needed and add public SSH keys for +``tc`` user using the same ``SSH_PUBLIC_KEY`` shell variable as described +above. + +Enabling biosdevname in the ramdisk +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to collect BIOS given names of NICs in the inventory, set +``TINYIPA_REQUIRE_BIOSDEVNAME`` variable in your shell before building the +tinyipa:: + + export TINYIPA_REQUIRE_BIOSDEVNAME=true + +Using ironic-lib from source +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`ironic-lib `_ contains +important parts of the provisioning logic. If you need to build an IPA image +with your local checkout of `ironic-lib`, export the following variable:: + + export IRONIC_LIB_SOURCE=/absolute/path/to/ironic-lib/checkout diff --git a/tinyipa/add-ssh-tinyipa.sh b/tinyipa/add-ssh-tinyipa.sh new file mode 100755 index 0000000..c1372e0 --- /dev/null +++ b/tinyipa/add-ssh-tinyipa.sh @@ -0,0 +1,139 @@ +#!/bin/bash + +# Rebuild upstream pre-built tinyipa it to be usable with ansible-deploy. +# +# Downloads the pre-built tinyipa ramdisk from tarballs.openstack.org or +# rebuilds a ramdisk under path set as TINYIPA_RAMDISK_FILE shell var. + +# During rebuild this script installs and configures OpenSSH server if needed +# and makes required changes for Ansible + Python to work in compiled/optimized +# Python environment. +# +# By default, id_rsa or id_dsa keys of the user performing the build +# are baked into the image as authorized_keys for 'tc' user. +# To supply different public ssh key, befor running this script set +# SSH_PUBLIC_KEY environment variable to point to absolute path to the key. +# +# This script produces "ansible-" ramdisk that can serve +# as ramdisk for both ansible-deploy driver and agent-based Ironic drivers, + +set -ex +WORKDIR=$(readlink -f $0 | xargs dirname) +REBUILDDIR="$WORKDIR/tinyipaaddssh" +DST_DIR=$REBUILDDIR +source ${WORKDIR}/common.sh + +TINYCORE_MIRROR_URL=${TINYCORE_MIRROR_URL:-} +BRANCH_PATH=${BRANCH_PATH:-master} +TINYIPA_RAMDISK_FILE=${TINYIPA_RAMDISK_FILE:-} + +SSH_PUBLIC_KEY=${SSH_PUBLIC_KEY:-} + +function validate_params { + echo "Validating location of public SSH key" + if [ -n "$SSH_PUBLIC_KEY" ]; then + if [ -r "$SSH_PUBLIC_KEY" ]; then + _found_ssh_key="$SSH_PUBLIC_KEY" + fi + else + for fmt in rsa dsa; do + if [ -r "$HOME/.ssh/id_$fmt.pub" ]; then + _found_ssh_key="$HOME/.ssh/id_$fmt.pub" + break + fi + done + fi + + if [ -z $_found_ssh_key ]; then + echo "Failed to find neither provided nor default SSH key" + exit 1 + fi +} + +function get_tinyipa { + if [ -z $TINYIPA_RAMDISK_FILE ]; then + mkdir -p $WORKDIR/build_files/cache + cd $WORKDIR/build_files/cache + wget -N https://tarballs.openstack.org/ironic-python-agent/tinyipa/files/tinyipa${BRANCH_EXT}.gz + TINYIPA_RAMDISK_FILE="$WORKDIR/build_files/cache/tinyipa${BRANCH_EXT}.gz" + fi +} + +function unpack_ramdisk { + + if [ -d "$REBUILDDIR" ]; then + sudo rm -rf "$REBUILDDIR" + fi + + mkdir -p "$REBUILDDIR" + + # Extract rootfs from .gz file + ( cd "$REBUILDDIR" && zcat "$TINYIPA_RAMDISK_FILE" | sudo cpio -i -H newc -d ) + +} + +function install_ssh { + if [ ! -f "$REBUILDDIR/usr/local/etc/ssh/sshd_config" ]; then + # tinyipa was built without SSH server installed + # Install and configure bare minimum for SSH access + $TC_CHROOT_CMD tce-load -wic openssh + # Configure OpenSSH + $CHROOT_CMD cp /usr/local/etc/ssh/sshd_config.orig /usr/local/etc/ssh/sshd_config + echo "PasswordAuthentication no" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + # Generate and configure host keys - RSA, DSA, Ed25519 + # NOTE(pas-ha) ECDSA host key will still be re-generated fresh on every image boot + $CHROOT_CMD ssh-keygen -q -t rsa -N "" -f /usr/local/etc/ssh/ssh_host_rsa_key + $CHROOT_CMD ssh-keygen -q -t dsa -N "" -f /usr/local/etc/ssh/ssh_host_dsa_key + $CHROOT_CMD ssh-keygen -q -t ed25519 -N "" -f /usr/local/etc/ssh/ssh_host_ed25519_key + echo "HostKey /usr/local/etc/ssh/ssh_host_rsa_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo "HostKey /usr/local/etc/ssh/ssh_host_dsa_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo "HostKey /usr/local/etc/ssh/ssh_host_ed25519_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + fi + + # setup new user SSH keys anyway + $CHROOT_CMD mkdir -p /home/tc + $CHROOT_CMD chown -R tc.staff /home/tc + $TC_CHROOT_CMD mkdir -p /home/tc/.ssh + cat $_found_ssh_key | $TC_CHROOT_CMD tee /home/tc/.ssh/authorized_keys + $CHROOT_CMD chown tc.staff /home/tc/.ssh/authorized_keys + $TC_CHROOT_CMD chmod 600 /home/tc/.ssh/authorized_keys +} + +function fix_python_optimize { + if grep -q "PYTHONOPTIMIZE=1" "$REBUILDDIR/opt/bootlocal.sh"; then + # tinyipa was built with optimized Python environment, apply fixes + echo "PYTHONOPTIMIZE=1" | $TC_CHROOT_CMD tee -a /home/tc/.ssh/environment + echo "PermitUserEnvironment yes" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo 'Defaults env_keep += "PYTHONOPTIMIZE"' | $CHROOT_CMD tee -a /etc/sudoers + fi +} + + +function rebuild_ramdisk { + # Rebuild build directory into gz file + ansible_basename="ansible-$(basename $TINYIPA_RAMDISK_FILE)" + ( cd "$REBUILDDIR" && sudo find | sudo cpio -o -H newc | gzip -9 > "$WORKDIR/${ansible_basename}" ) + # Output file created by this script and its size + cd "$WORKDIR" + echo "Produced files:" + du -h "${ansible_basename}" +} + +sudo -v + + +validate_params +get_tinyipa +unpack_ramdisk +setup_tce "$DST_DIR" + +# NOTE (pas-ha) default tinyipa is built without SSH access, enable it here +install_ssh +# NOTE(pas-ha) default tinyipa is built with PYOPTIMIZE_TINYIPA=true and +# for Ansible+python to work we need to ensure that PYTHONOPTIMIZE=1 is +# set for all sessions from 'tc' user including those that are escalated +# with 'sudo' afterwards +fix_python_optimize + +cleanup_tce "$DST_DIR" +rebuild_ramdisk diff --git a/tinyipa/build-instance-images.sh b/tinyipa/build-instance-images.sh new file mode 100755 index 0000000..1203771 --- /dev/null +++ b/tinyipa/build-instance-images.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -ex +WORKDIR=$(readlink -f $0 | xargs dirname) +DST_DIR=$(mktemp -d) +source ${WORKDIR}/common.sh +PARTIMG="$WORKDIR/tiny-instance-part${BRANCH_EXT}.img" +UECFILE="$WORKDIR/tiny-instance-uec${BRANCH_EXT}.tar.gz" +fs_type='ext4' + +sudo rm -rf $PARTIMG $UECFILE +sudo truncate --size=150M $PARTIMG + +sudo mkfs."${fs_type}" -F "$PARTIMG" -L "root" +sudo mount -o loop "$PARTIMG" "$DST_DIR/" + +# Extract rootfs from .gz file +( cd "$DST_DIR" && zcat $WORKDIR/build_files/corepure64.gz | sudo cpio -i -H newc -d ) + +setup_tce $DST_DIR + +$TC_CHROOT_CMD tce-load -wci grub2-multi.tcz + +cleanup_tce $DST_DIR +sudo umount $DST_DIR/ + +pushd $DST_DIR/ +cp $WORKDIR/tinyipa${BRANCH_EXT}.gz $DST_DIR/tinyipa-initrd +cp $WORKDIR/tinyipa${BRANCH_EXT}.vmlinuz $DST_DIR/tinyipa-vmlinuz +cp $PARTIMG $DST_DIR/ + +tar -czf $UECFILE ./ + +popd + +sudo rm -rf $DST_DIR diff --git a/tinyipa/build-iso.sh b/tinyipa/build-iso.sh new file mode 100755 index 0000000..be0db45 --- /dev/null +++ b/tinyipa/build-iso.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -ex +WORKDIR=$(readlink -f $0 | xargs dirname) + +cd $WORKDIR/build_files +wget -N https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-4.06.tar.gz && tar zxf syslinux-4.06.tar.gz + +cd $WORKDIR +rm -rf newiso +mkdir -p newiso/boot/isolinux +cp build_files/syslinux-4.06/core/isolinux.bin newiso/boot/isolinux/. +cp build_files/isolinux.cfg newiso/boot/isolinux/. +cp tinyipa.gz newiso/boot/corepure64.gz +cp tinyipa.vmlinuz newiso/boot/vmlinuz64 +genisoimage -l -r -J -R -V TC-custom -no-emul-boot -boot-load-size 4 -boot-info-table -b boot/isolinux/isolinux.bin -c boot/isolinux/boot.cat -o tinyipa.iso newiso diff --git a/tinyipa/build-tinyipa.sh b/tinyipa/build-tinyipa.sh new file mode 100755 index 0000000..b011bca --- /dev/null +++ b/tinyipa/build-tinyipa.sh @@ -0,0 +1,198 @@ +#!/bin/bash + +set -ex +WORKDIR=$(readlink -f $0 | xargs dirname) +source ${WORKDIR}/tc-mirror.sh +BUILDDIR="$WORKDIR/tinyipabuild" +BUILD_AND_INSTALL_TINYIPA=${BUILD_AND_INSTALL_TINYIPA:-false} +TINYCORE_MIRROR_URL=${TINYCORE_MIRROR_URL:-} +TINYIPA_REQUIRE_BIOSDEVNAME=${TINYIPA_REQUIRE_BIOSDEVNAME:-false} +TINYIPA_REQUIRE_IPMITOOL=${TINYIPA_REQUIRE_IPMITOOL:-true} +IRONIC_LIB_SOURCE=${IRONIC_LIB_SOURCE:-} +USE_PYTHON3=${USE_PYTHON3:-True} + +CHROOT_PATH="/tmp/overides:/usr/local/sbin:/usr/local/bin:/apps/bin:/usr/sbin:/usr/bin:/sbin:/bin" +CHROOT_CMD="sudo chroot $BUILDDIR /usr/bin/env -i PATH=$CHROOT_PATH http_proxy=$http_proxy https_proxy=$https_proxy no_proxy=$no_proxy" + +TC=1001 +STAFF=50 + +# NOTE(moshele): Git < 1.7.10 requires a separate checkout, see LP #1590912 +function clone_and_checkout { + git clone $1 $2 --depth=1 --branch $3; cd $2; git checkout $3; cd - +} + +echo "Building tinyipa:" + +# Ensure we have an extended sudo to prevent the need to enter a password over +# and over again. +sudo -v + +# If an old build directory exists remove it +if [ -d "$BUILDDIR" ]; then + sudo rm -rf "$BUILDDIR" +fi + +############################################## +# Download and Cache Tiny Core Files +############################################## + +# Find a working TC mirror if none is explicitly provided +choose_tc_mirror + +cd $WORKDIR/build_files +wget -N $TINYCORE_MIRROR_URL/8.x/x86_64/release/distribution_files/corepure64.gz +wget -N $TINYCORE_MIRROR_URL/8.x/x86_64/release/distribution_files/vmlinuz64 +cd $WORKDIR + +######################################################## +# Build Required Python Dependecies in a Build Directory +######################################################## + +# Make directory for building in +mkdir "$BUILDDIR" + +# Extract rootfs from .gz file +( cd "$BUILDDIR" && zcat $WORKDIR/build_files/corepure64.gz | sudo cpio -i -H newc -d ) + +# Configure mirror +sudo sh -c "echo $TINYCORE_MIRROR_URL > $BUILDDIR/opt/tcemirror" + +# Download TGT, Qemu-utils, Biosdevname and IPMItool source +clone_and_checkout "https://github.com/fujita/tgt.git" "${BUILDDIR}/tmp/tgt" "v1.0.62" +clone_and_checkout "https://github.com/qemu/qemu.git" "${BUILDDIR}/tmp/qemu" "v2.5.0" +clone_and_checkout "https://github.com/lyonel/lshw.git" "${BUILDDIR}/tmp/lshw" "B.02.18" +if $TINYIPA_REQUIRE_BIOSDEVNAME; then + wget -N -O - https://linux.dell.com/biosdevname/biosdevname-0.7.2/biosdevname-0.7.2.tar.gz | tar -xz -C "${BUILDDIR}/tmp" -f - +fi +if $TINYIPA_REQUIRE_IPMITOOL; then + wget -N -O - https://github.com/ipmitool/ipmitool/archive/IPMITOOL_1_8_18.tar.gz | tar -xz -C "${BUILDDIR}/tmp" -f - +fi + +# Create directory for python local mirror +mkdir -p "$BUILDDIR/tmp/localpip" + +# Download IPA and requirements +IPA_SOURCE_DIR=${IPA_SOURCE_DIR:-/opt/stack/ironic-python-agent} +cd $IPA_SOURCE_DIR +rm -rf *.egg-info +pwd +python setup.py sdist --dist-dir "$BUILDDIR/tmp/localpip" --quiet +ls $BUILDDIR/tmp/localpip || true +cp requirements.txt $BUILDDIR/tmp/ipa-requirements.txt + +if [ -n "$IRONIC_LIB_SOURCE" ]; then + pushd $IRONIC_LIB_SOURCE + rm -rf *.egg-info + python setup.py sdist --dist-dir "$BUILDDIR/tmp/localpip" --quiet + cp requirements.txt $BUILDDIR/tmp/ironic-lib-requirements.txt + popd +fi + +imagebuild/common/generate_upper_constraints.sh upper-constraints.txt +if [ -n "$IRONIC_LIB_SOURCE" ]; then + sed -i '/ironic-lib/d' upper-constraints.txt $BUILDDIR/tmp/ipa-requirements.txt +fi +cp upper-constraints.txt $BUILDDIR/tmp/upper-constraints.txt +echo Using upper-constraints: +cat upper-constraints.txt +cd $WORKDIR + +sudo cp /etc/resolv.conf $BUILDDIR/etc/resolv.conf + +trap "sudo umount $BUILDDIR/proc; sudo umount $BUILDDIR/dev/pts" EXIT +sudo mount --bind /proc $BUILDDIR/proc +sudo mount --bind /dev/pts $BUILDDIR/dev/pts + +if [ -d /opt/stack/new ]; then + CI_DIR=/opt/stack/new +elif [ -d /opt/stack ]; then + CI_DIR=/opt/stack +else + CI_DIR= +fi + +if [ -n "$CI_DIR" ]; then + # Running in CI environment, make checkouts available + $CHROOT_CMD mkdir -p $CI_DIR + for project in $(ls $CI_DIR); do + if grep -q "$project" $BUILDDIR/tmp/upper-constraints.txt && + [ -d "$CI_DIR/$project/.git" ]; then + sudo cp -R "$CI_DIR/$project" $BUILDDIR/$CI_DIR/ + fi + done +fi + +$CHROOT_CMD mkdir /etc/sysconfig/tcedir +$CHROOT_CMD chmod a+rwx /etc/sysconfig/tcedir +$CHROOT_CMD touch /etc/sysconfig/tcuser +$CHROOT_CMD chmod a+rwx /etc/sysconfig/tcuser + +mkdir $BUILDDIR/tmp/overides +cp $WORKDIR/build_files/fakeuname $BUILDDIR/tmp/overides/uname + +PY_REQS="buildreqs_python2.lst" +if [[ $USE_PYTHON3 == "True" ]]; then + PY_REQS="buildreqs_python3.lst" +fi + +while read line; do + sudo chroot --userspec=$TC:$STAFF $BUILDDIR /usr/bin/env -i PATH=$CHROOT_PATH http_proxy=$http_proxy https_proxy=$https_proxy no_proxy=$no_proxy tce-load -wci $line +done < <(paste $WORKDIR/build_files/$PY_REQS $WORKDIR/build_files/buildreqs.lst) + +PIP_COMMAND="pip" +TINYIPA_PYTHON_EXE="python" +if [[ $USE_PYTHON3 == "True" ]]; then + PIP_COMMAND="pip3" + TINYIPA_PYTHON_EXE="python3" +fi + +# Build python wheels +$CHROOT_CMD ${TINYIPA_PYTHON_EXE} -m ensurepip +$CHROOT_CMD ${PIP_COMMAND} install --upgrade pip wheel +$CHROOT_CMD ${PIP_COMMAND} install pbr +$CHROOT_CMD ${PIP_COMMAND} wheel -c /tmp/upper-constraints.txt --wheel-dir /tmp/wheels -r /tmp/ipa-requirements.txt +if [ -n "$IRONIC_LIB_SOURCE" ]; then + $CHROOT_CMD ${PIP_COMMAND} wheel -c /tmp/upper-constraints.txt --wheel-dir /tmp/wheels -r /tmp/ironic-lib-requirements.txt + $CHROOT_CMD ${PIP_COMMAND} wheel -c /tmp/upper-constraints.txt --no-index --pre --wheel-dir /tmp/wheels --find-links=/tmp/localpip --find-links=/tmp/wheels ironic-lib +fi +$CHROOT_CMD ${PIP_COMMAND} wheel -c /tmp/upper-constraints.txt --no-index --pre --wheel-dir /tmp/wheels --find-links=/tmp/localpip --find-links=/tmp/wheels ironic-python-agent +echo Resulting wheels: +ls -1 $BUILDDIR/tmp/wheels + +# Build tgt +rm -rf $WORKDIR/build_files/tgt.tcz +$CHROOT_CMD /bin/sh -c "cd /tmp/tgt && make && make install-programs install-conf install-scripts DESTDIR=/tmp/tgt-installed" +find $BUILDDIR/tmp/tgt-installed/ -type f -executable | xargs file | awk -F ':' '/ELF/ {print $1}' | sudo xargs strip +cd $WORKDIR/build_files && mksquashfs $BUILDDIR/tmp/tgt-installed tgt.tcz && md5sum tgt.tcz > tgt.tcz.md5.txt + +# Build qemu-utils +rm -rf $WORKDIR/build_files/qemu-utils.tcz +$CHROOT_CMD /bin/sh -c "cd /tmp/qemu && ./configure --disable-system --disable-user --disable-linux-user --disable-bsd-user --disable-guest-agent --disable-blobs && make && make install DESTDIR=/tmp/qemu-utils" +find $BUILDDIR/tmp/qemu-utils/ -type f -executable | xargs file | awk -F ':' '/ELF/ {print $1}' | sudo xargs strip +cd $WORKDIR/build_files && mksquashfs $BUILDDIR/tmp/qemu-utils qemu-utils.tcz && md5sum qemu-utils.tcz > qemu-utils.tcz.md5.txt +# Create qemu-utils.tcz.dep +echo "glib2.tcz" > qemu-utils.tcz.dep + +# Build lshw +rm -rf $WORKDIR/build_files/lshw.tcz +# NOTE(mjturek): We touch src/lshw.1 and clear src/po/Makefile to avoid building the man pages, as they aren't used and require large dependencies to build. +$CHROOT_CMD /bin/sh -c "cd /tmp/lshw && touch src/lshw.1 && echo install: > src/po/Makefile && make && make install DESTDIR=/tmp/lshw-installed" +find $BUILDDIR/tmp/lshw-installed/ -type f -executable | xargs file | awk -F ':' '/ELF/ {print $1}' | sudo xargs strip +cd $WORKDIR/build_files && mksquashfs $BUILDDIR/tmp/lshw-installed lshw.tcz && md5sum lshw.tcz > lshw.tcz.md5.txt + +# Build biosdevname +if $TINYIPA_REQUIRE_BIOSDEVNAME; then + rm -rf $WORKDIR/build_files/biosdevname.tcz + $CHROOT_CMD /bin/sh -c "cd /tmp/biosdevname-* && ./configure && make && make install DESTDIR=/tmp/biosdevname-installed" + find $BUILDDIR/tmp/biosdevname-installed/ -type f -executable | xargs file | awk -F ':' '/ELF/ {print $1}' | sudo xargs strip + cd $WORKDIR/build_files && mksquashfs $BUILDDIR/tmp/biosdevname-installed biosdevname.tcz && md5sum biosdevname.tcz > biosdevname.tcz.md5.txt +fi + +if $TINYIPA_REQUIRE_IPMITOOL; then + rm -rf $WORKDIR/build_files/ipmitool.tcz + # NOTE(TheJulia): Explicitly add the libtool path since /usr/local/ is not in path from the chroot. + $CHROOT_CMD /bin/sh -c "cd /tmp/ipmitool-* && env LIBTOOL='/usr/local/bin/libtool' ./bootstrap && ./configure && make && make install DESTDIR=/tmp/ipmitool" + find $BUILDDIR/tmp/ipmitool/ -type f -executable | xargs file | awk -F ':' '/ELF/ {print $1}' | sudo xargs strip + cd $WORKDIR/build_files && mksquashfs $BUILDDIR/tmp/ipmitool ipmitool.tcz && md5sum ipmitool.tcz > ipmitool.tcz.md5.txt +fi diff --git a/tinyipa/build_files/bootlocal.sh b/tinyipa/build_files/bootlocal.sh new file mode 100755 index 0000000..0fcf0b4 --- /dev/null +++ b/tinyipa/build_files/bootlocal.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# put other system startup commands here + +#exec > /tmp/installlogs 2>&1 +set -x + +echo "Starting bootlocal script:" +date + +export HOME=/root + +# Start SSHd +if [ -f /usr/local/etc/init.d/openssh ]; then + echo "Starting OpenSSH server:" + /usr/local/etc/init.d/openssh start +fi + +# Maybe save some RAM? +#rm -rf /tmp/builtin + +# Install IPA and dependecies +if ! type "ironic-python-agent" > /dev/null ; then + PIP_COMMAND="pip" + if hash pip3 2>/dev/null; then + PIP_COMMAND="pip3" + fi + $PIP_COMMAND install --no-index --find-links=file:///tmp/wheelhouse ironic_python_agent +fi + +# Create ipa-rescue-config directory for rescue password +sudo mkdir -p /etc/ipa-rescue-config + +export PYTHONOPTIMIZE=1 + +# Run IPA +echo "Starting Ironic Python Agent:" +date +ironic-python-agent 2>&1 | tee /var/log/ironic-python-agent.log + + +create_rescue_user() { + crypted_pass=$(cat /etc/ipa-rescue-config/ipa-rescue-password) + sudo adduser rescue -D -G root # no useradd + echo "rescue:$crypted_pass" | sudo chpasswd -e + sudo sh -c "echo \"rescue ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers" # no suooers.d in tiny core. + + # Restart sshd with allowing password authentication + sudo sed -i -e 's/^PasswordAuthentication no/PasswordAuthentication yes/' /usr/local/etc/ssh/sshd_config + sudo /usr/local/etc/init.d/openssh restart +} + +# Setup DHCP network +configure_dhcp_network() { + for pidfile in `ls /var/run/udhcpc/*.pid`; do + kill `cat $pidfile` + done + + # NOTE(TheJulia): We may need to add a short wait here as + # network interface plugging actions may not be asynchronous. + echo "Sleeping 30 sec as network interface is being updated" + sleep 30 + INTERFACES=$(ip -o link |grep "LOWER_UP"|cut -f2 -d" "|sed 's/://'|grep -v "lo") + for interface in $INTERFACES; do + pidfile="/var/run/udhcpc/${interface}.pid" + /sbin/udhcpc -b -p ${pidfile} -i ${interface} -s /opt/udhcpc.script >> /var/log/udhcpc.log 2>&1 + done +} + +if [ -f /etc/ipa-rescue-config/ipa-rescue-password ]; then + create_rescue_user || exit 0 + configure_dhcp_network || exit 0 +else + echo "IPA has exited. No rescue password file was defined." +fi diff --git a/tinyipa/build_files/buildreqs.lst b/tinyipa/build_files/buildreqs.lst new file mode 100644 index 0000000..6fd9293 --- /dev/null +++ b/tinyipa/build_files/buildreqs.lst @@ -0,0 +1,25 @@ +autoconf.tcz +autogen-dev.tcz +autogen.tcz +automake.tcz +bash.tcz +binutils.tcz +compiletc.tcz +coreutils.tcz +dmidecode.tcz +gdisk.tcz +git.tcz +glib2-dev.tcz +hdparm.tcz +libpci-dev.tcz +libtool-dev.tcz +libtool.tcz +parted.tcz +pciutils.tcz +pixman-dev.tcz +pkg-config.tcz +raid-dm-4.8.17-tinycore64.tcz +scsi-4.8.17-tinycore64.tcz +udev-lib.tcz +util-linux.tcz +zlib_base-dev.tcz diff --git a/tinyipa/build_files/buildreqs_python2.lst b/tinyipa/build_files/buildreqs_python2.lst new file mode 100644 index 0000000..cc75492 --- /dev/null +++ b/tinyipa/build_files/buildreqs_python2.lst @@ -0,0 +1,2 @@ +python.tcz +python-dev.tcz \ No newline at end of file diff --git a/tinyipa/build_files/buildreqs_python3.lst b/tinyipa/build_files/buildreqs_python3.lst new file mode 100644 index 0000000..1b6b0c0 --- /dev/null +++ b/tinyipa/build_files/buildreqs_python3.lst @@ -0,0 +1,2 @@ +python3.6.tcz +python3.6-dev.tcz \ No newline at end of file diff --git a/tinyipa/build_files/dhcp.sh b/tinyipa/build_files/dhcp.sh new file mode 100644 index 0000000..8383f26 --- /dev/null +++ b/tinyipa/build_files/dhcp.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# The DHCP portion is now separated out, in order to not slow the boot down +# only to wait for slow network cards +. /etc/init.d/tc-functions + +# This waits until all devices have registered +/sbin/udevadm settle --timeout=%UDEV_SETTLE_TIMEOUT% + +NETDEVICES="$(awk -F: '/eth.:|tr.:/{print $1}' /proc/net/dev 2>/dev/null)" +echo "$0: Discovered network devices: $NETDEVICES" +for DEVICE in $NETDEVICES; do + ifconfig $DEVICE | grep -q "inet addr" + if [ "$?" != 0 ]; then + echo -e "\nNetwork device $DEVICE detected, DHCP broadcasting for IP." + trap 2 3 11 + /sbin/udhcpc -b -i $DEVICE -x hostname:$(/bin/hostname) -p /var/run/udhcpc.$DEVICE.pid 2>&1 & + trap "" 2 3 11 + sleep 1 + fi +done + diff --git a/tinyipa/build_files/fakeuname b/tinyipa/build_files/fakeuname new file mode 100755 index 0000000..96405e3 --- /dev/null +++ b/tinyipa/build_files/fakeuname @@ -0,0 +1,110 @@ +#!/bin/sh + +S="Linux" +N="box" +R="4.8.17-tinycore64" +P="unknown" +V="#2017 SMP" +M="x86_64" +I="unknown" +O="GNU/Linux" + +OPT_A=false +OPT_S=false +OPT_N=false +OPT_R=false +OPT_P=false +OPT_V=false +OPT_M=false +OPT_I=false +OPT_O=false + +if [ -z "$1" ]; then + echo "-ASNRPVMIO" + exit 1 +fi + +while :; do + case $1 in + -a) + OPT_A=true + shift + ;; + -s) + OPT_S=true + shift + ;; + -n) + OPT_N=true + shift + ;; + -r) + OPT_R=true + shift + ;; + -p) + OPT_P=true + shift + ;; + -v) + OPT_V=true + shift + ;; + -m) + OPT_M=true + shift + ;; + -i) + OPT_I=true + shift + ;; + -o) + OPT_O=true + shift + ;; + -rs) + OPT_R=true + OPT_S=true + shift + ;; + *) + if [ ! -z "$1" ]; then + echo "uname -asnrpvmio" + exit 1 + fi + break + ;; + esac +done + +if $OPT_A; then + echo "$S $N $R $V $M $O" + exit 0 +fi + +string='' +if $OPT_S; then + string="$string $S" +fi +if $OPT_N; then + string="$string $N" +fi +if $OPT_R; then + string="$string $R" +fi +if $OPT_P; then + string="$string $P" +fi +if $OPT_V; then + string="$string $V" +fi +if $OPT_M; then + string="$string $M" +fi +if $OPT_I; then + string="$string $I" +fi +if $OPT_O; then + string="$string $O" +fi +echo $string diff --git a/tinyipa/build_files/finalreqs.lst b/tinyipa/build_files/finalreqs.lst new file mode 100644 index 0000000..fa210ab --- /dev/null +++ b/tinyipa/build_files/finalreqs.lst @@ -0,0 +1,16 @@ +bash.tcz +coreutils.tcz +dmidecode.tcz +gdisk.tcz +hdparm.tcz +iproute2.tcz +parted.tcz +popt.tcz +pciutils.tcz +raid-dm-4.8.17-tinycore64.tcz +scsi-4.8.17-tinycore64.tcz +udev-lib.tcz +util-linux.tcz +glib2.tcz +iproute2.tcz +smartmontools.tcz diff --git a/tinyipa/build_files/finalreqs_python2.lst b/tinyipa/build_files/finalreqs_python2.lst new file mode 100644 index 0000000..c298884 --- /dev/null +++ b/tinyipa/build_files/finalreqs_python2.lst @@ -0,0 +1 @@ +python.tcz \ No newline at end of file diff --git a/tinyipa/build_files/finalreqs_python3.lst b/tinyipa/build_files/finalreqs_python3.lst new file mode 100644 index 0000000..a2a4bdc --- /dev/null +++ b/tinyipa/build_files/finalreqs_python3.lst @@ -0,0 +1,2 @@ +python3.6.tcz +expat2.tcz \ No newline at end of file diff --git a/tinyipa/build_files/isolinux.cfg b/tinyipa/build_files/isolinux.cfg new file mode 100755 index 0000000..7fe8c22 --- /dev/null +++ b/tinyipa/build_files/isolinux.cfg @@ -0,0 +1,9 @@ +display boot.msg +default corepure64 + +label corepure64 + kernel /boot/vmlinuz64 + initrd /boot/corepure64.gz + append loglevel=3 syslog showapps + +implicit 0 diff --git a/tinyipa/common.sh b/tinyipa/common.sh new file mode 100755 index 0000000..44d9d08 --- /dev/null +++ b/tinyipa/common.sh @@ -0,0 +1,56 @@ +#!/bin/bash + +WORKDIR=$(readlink -f $0 | xargs dirname) +source ${WORKDIR}/tc-mirror.sh + +# Allow an extension to be added to the generated files by specifying +# $BRANCH_PATH e.g. export BRANCH_PATH=master results in tinyipa-master.gz etc +BRANCH_EXT='' +if [ -n "$BRANCH_PATH" ]; then + BRANCH_EXT="-$BRANCH_PATH" +fi +export BRANCH_EXT + +TC=1001 +STAFF=50 + +CHROOT_PATH="/tmp/overides:/usr/local/sbin:/usr/local/bin:/apps/bin:/usr/sbin:/usr/bin:/sbin:/bin" +CHROOT_CMD="sudo chroot $DST_DIR /usr/bin/env -i PATH=$CHROOT_PATH http_proxy=$http_proxy https_proxy=$https_proxy no_proxy=$no_proxy" +TC_CHROOT_CMD="sudo chroot --userspec=$TC:$STAFF $DST_DIR /usr/bin/env -i PATH=$CHROOT_PATH http_proxy=$http_proxy https_proxy=$https_proxy no_proxy=$no_proxy" + +function setup_tce { + # Setup resolv.conf, add mirrors, mount proc + local dst_dir="$1" + + # Find a working TC mirror if none is explicitly provided + choose_tc_mirror + + sudo cp $dst_dir/etc/resolv.conf $dst_dir/etc/resolv.conf.old + sudo cp /etc/resolv.conf $dst_dir/etc/resolv.conf + + sudo cp -a $dst_dir/opt/tcemirror $dst_dir/opt/tcemirror.old + sudo sh -c "echo $TINYCORE_MIRROR_URL > $dst_dir/opt/tcemirror" + + mkdir -p $dst_dir/tmp/builtin/optional + $CHROOT_CMD chown -R tc.staff /tmp/builtin + $CHROOT_CMD chmod -R a+w /tmp/builtin + $CHROOT_CMD ln -sf /tmp/builtin /etc/sysconfig/tcedir + echo "tc" | $CHROOT_CMD tee -a /etc/sysconfig/tcuser + + # Mount /proc for chroot commands + sudo mount --bind /proc $dst_dir/proc +} + +function cleanup_tce { + local dst_dir="$1" + + # Unmount /proc and clean up everything + sudo umount $dst_dir/proc + sudo rm -rf $dst_dir/tmp/builtin + sudo rm -rf $dst_dir/tmp/tcloop + sudo rm -rf $dst_dir/usr/local/tce.installed + sudo mv $dst_dir/opt/tcemirror.old $dst_dir/opt/tcemirror + sudo mv $dst_dir/etc/resolv.conf.old $dst_dir/etc/resolv.conf + sudo rm $dst_dir/etc/sysconfig/tcuser + sudo rm $dst_dir/etc/sysconfig/tcedir +} diff --git a/tinyipa/finalise-tinyipa.sh b/tinyipa/finalise-tinyipa.sh new file mode 100755 index 0000000..d8f967d --- /dev/null +++ b/tinyipa/finalise-tinyipa.sh @@ -0,0 +1,246 @@ +#!/bin/bash + +set -ex +WORKDIR=$(readlink -f $0 | xargs dirname) +FINALDIR="$WORKDIR/tinyipafinal" +DST_DIR=$FINALDIR +source ${WORKDIR}/common.sh + +BUILDDIR="$WORKDIR/tinyipabuild" +BUILD_AND_INSTALL_TINYIPA=${BUILD_AND_INSTALL_TINYIPA:-true} +TINYCORE_MIRROR_URL=${TINYCORE_MIRROR_URL:-} +ENABLE_SSH=${ENABLE_SSH:-false} +INSTALL_SSH=${INSTALL_SSH:-true} +AUTHORIZE_SSH=${ENABLE_SSH:-false} + +if $ENABLE_SSH; then + echo "WARNING: using ENABLE_SSH is deprecated, use INSTALL_SSH and AUTHORIZE_SSH variables instead" + INSTALL_SSH=true + AUTHORIZE_SSH=true +fi + +SSH_PUBLIC_KEY=${SSH_PUBLIC_KEY:-} +PYOPTIMIZE_TINYIPA=${PYOPTIMIZE_TINYIPA:-true} +TINYIPA_REQUIRE_BIOSDEVNAME=${TINYIPA_REQUIRE_BIOSDEVNAME:-false} +TINYIPA_REQUIRE_IPMITOOL=${TINYIPA_REQUIRE_IPMITOOL:-true} +TINYIPA_UDEV_SETTLE_TIMEOUT=${TINYIPA_UDEV_SETTLE_TIMEOUT:-20} +USE_PYTHON3=${USE_PYTHON3:-True} + + +echo "Finalising tinyipa:" + +if $AUTHORIZE_SSH ; then + echo "Validating location of public SSH key" + if [ -n "$SSH_PUBLIC_KEY" ]; then + if [ -f "$SSH_PUBLIC_KEY" ]; then + _found_ssh_key="$SSH_PUBLIC_KEY" + fi + else + for fmt in rsa dsa; do + if [ -f "$HOME/.ssh/id_$fmt.pub" ]; then + _found_ssh_key="$HOME/.ssh/id_$fmt.pub" + break + fi + done + fi + + if [ -z $_found_ssh_key ]; then + echo "Failed to find neither provided nor default SSH key" + exit 1 + fi +fi + +sudo -v + +if [ -d "$FINALDIR" ]; then + sudo rm -rf "$FINALDIR" +fi + +mkdir "$FINALDIR" + +# Extract rootfs from .gz file +( cd "$FINALDIR" && zcat $WORKDIR/build_files/corepure64.gz | sudo cpio -i -H newc -d ) + +# Setup Final Dir +setup_tce "$DST_DIR" + +# Modify ldconfig for x86-64 +$CHROOT_CMD cp /sbin/ldconfig /sbin/ldconfigold +printf '#!/bin/sh\n/sbin/ldconfigold $@ | sed -r "s/libc6|ELF/libc6,x86-64/"' | $CHROOT_CMD tee -a /sbin/ldconfignew +$CHROOT_CMD cp /sbin/ldconfignew /sbin/ldconfig +$CHROOT_CMD chmod u+x /sbin/ldconfig + +# Copy python wheels from build to final dir +cp -Rp "$BUILDDIR/tmp/wheels" "$FINALDIR/tmp/wheelhouse" + +cp $WORKDIR/build_files/tgt.* $FINALDIR/tmp/builtin/optional +cp $WORKDIR/build_files/qemu-utils.* $FINALDIR/tmp/builtin/optional +cp $WORKDIR/build_files/lshw.* $FINALDIR/tmp/builtin/optional + +if $TINYIPA_REQUIRE_BIOSDEVNAME; then + cp $WORKDIR/build_files/biosdevname.* $FINALDIR/tmp/builtin/optional +fi +if $TINYIPA_REQUIRE_IPMITOOL; then + cp $WORKDIR/build_files/ipmitool.* $FINALDIR/tmp/builtin/optional +fi + +mkdir $FINALDIR/tmp/overides +cp $WORKDIR/build_files/fakeuname $FINALDIR/tmp/overides/uname + +PY_REQS="finalreqs_python2.lst" +if [[ $USE_PYTHON3 == "True" ]]; then + PY_REQS="finalreqs_python3.lst" +fi + +while read line; do + $TC_CHROOT_CMD tce-load -wic $line +done < <(paste $WORKDIR/build_files/finalreqs.lst $WORKDIR/build_files/$PY_REQS) + +if $INSTALL_SSH ; then + # Install and configure bare minimum for SSH access + $TC_CHROOT_CMD tce-load -wic openssh + # Configure OpenSSH + $CHROOT_CMD cp /usr/local/etc/ssh/sshd_config.orig /usr/local/etc/ssh/sshd_config + echo "PasswordAuthentication no" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + # Generate and configure host keys - RSA, DSA, Ed25519 + # NOTE(pas-ha) ECDSA host key will still be re-generated fresh on every image boot + $CHROOT_CMD ssh-keygen -t rsa -N "" -f /usr/local/etc/ssh/ssh_host_rsa_key + $CHROOT_CMD ssh-keygen -t dsa -N "" -f /usr/local/etc/ssh/ssh_host_dsa_key + $CHROOT_CMD ssh-keygen -t ed25519 -N "" -f /usr/local/etc/ssh/ssh_host_ed25519_key + echo "HostKey /usr/local/etc/ssh/ssh_host_rsa_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo "HostKey /usr/local/etc/ssh/ssh_host_dsa_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo "HostKey /usr/local/etc/ssh/ssh_host_ed25519_key" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + + # setup user and SSH keys + if $AUTHORIZE_SSH; then + $CHROOT_CMD mkdir -p /home/tc + $CHROOT_CMD chown -R tc.staff /home/tc + $TC_CHROOT_CMD mkdir -p /home/tc/.ssh + cat $_found_ssh_key | $TC_CHROOT_CMD tee /home/tc/.ssh/authorized_keys + $CHROOT_CMD chown tc.staff /home/tc/.ssh/authorized_keys + $TC_CHROOT_CMD chmod 600 /home/tc/.ssh/authorized_keys + fi +fi + +$TC_CHROOT_CMD tce-load -ic /tmp/builtin/optional/tgt.tcz +$TC_CHROOT_CMD tce-load -ic /tmp/builtin/optional/qemu-utils.tcz +$TC_CHROOT_CMD tce-load -ic /tmp/builtin/optional/lshw.tcz +if $TINYIPA_REQUIRE_BIOSDEVNAME; then + $TC_CHROOT_CMD tce-load -ic /tmp/builtin/optional/biosdevname.tcz +fi +if $TINYIPA_REQUIRE_IPMITOOL; then + $TC_CHROOT_CMD tce-load -ic /tmp/builtin/optional/ipmitool.tcz +fi + +# Ensure tinyipa picks up installed kernel modules +$CHROOT_CMD depmod -a `$WORKDIR/build_files/fakeuname -r` + +PIP_COMMAND="pip" +TINYIPA_PYTHON_EXE="python" +if [[ $USE_PYTHON3 == "True" ]]; then + PIP_COMMAND="pip3" + TINYIPA_PYTHON_EXE="python3" +fi + +# Install pip +$CHROOT_CMD ${TINYIPA_PYTHON_EXE} -m ensurepip --upgrade + +# If flag is set install python now +if $BUILD_AND_INSTALL_TINYIPA ; then + $CHROOT_CMD $PIP_COMMAND install --no-index --find-links=file:///tmp/wheelhouse --pre ironic_python_agent + rm -rf $FINALDIR/tmp/wheelhouse +fi + +# Unmount /proc and clean up everything +cleanup_tce "$DST_DIR" + +# Copy bootlocal.sh to opt +sudo cp "$WORKDIR/build_files/bootlocal.sh" "$FINALDIR/opt/." + +# Copy udhcpc.script to opt +sudo cp "$WORKDIR/udhcpc.script" "$FINALDIR/opt/" + +# Replace etc/init.d/dhcp.sh +sudo cp "$WORKDIR/build_files/dhcp.sh" "$FINALDIR/etc/init.d/dhcp.sh" +sudo sed -i "s/%UDEV_SETTLE_TIMEOUT%/$TINYIPA_UDEV_SETTLE_TIMEOUT/" "$FINALDIR/etc/init.d/dhcp.sh" + +# Disable ZSwap +sudo sed -i '/# Main/a NOZSWAP=1' "$FINALDIR/etc/init.d/tc-config" +# sudo cp $WORKDIR/build_files/tc-config $FINALDIR/etc/init.d/tc-config + +if $PYOPTIMIZE_TINYIPA; then + # Precompile all python + if [[ $USE_PYTHON3 == "True" ]]; then + set +e + $CHROOT_CMD /bin/bash -c "python3 -OO -m compileall /usr/local/lib/python3.6" + set -e + find $FINALDIR/usr/local/lib/python3.6 -name "*.py" -not -path "*ironic_python_agent/api/config.py" | sudo xargs --no-run-if-empty rm + find $FINALDIR/usr/local/lib/python3.6 -name "*.pyc" ! -name "*opt-2*" | sudo xargs --no-run-if-empty rm + sudo find $FINALDIR/usr/local/lib/python3.6 -type d -name __pycache__ -exec sh -c 'cd "$1"; for f in *; do mv -i "$f" .. ; done' find-sh {} \; + find $FINALDIR/usr/local/lib/python3.6 -name "*.cpython-36.opt-2*" | sed 'p;s/\.cpython-36\.opt-2//' | sudo xargs -n2 --no-run-if-empty mv + fi + set +e + $CHROOT_CMD /bin/bash -c "python -OO -m compileall /usr/local/lib/python2.7" + set -e + find $FINALDIR/usr/local/lib/python2.7 -name "*.py" -not -path "*ironic_python_agent/api/config.py" | sudo xargs --no-run-if-empty rm + find $FINALDIR/usr/local/lib/python2.7 -name "*.pyc" | sudo xargs --no-run-if-empty rm + if $INSTALL_SSH && $AUTHORIZE_SSH ; then + # NOTE(pas-ha) for Ansible+Python to work we need to ensure that + # PYTHONOPTIMIZE=1 is set for all sessions from 'tc' user including + # those that are elevated with 'sudo' afterwards + echo "PYTHONOPTIMIZE=1" | $TC_CHROOT_CMD tee -a /home/tc/.ssh/environment + echo "PermitUserEnvironment yes" | $CHROOT_CMD tee -a /usr/local/etc/ssh/sshd_config + echo 'Defaults env_keep += "PYTHONOPTIMIZE"' | $CHROOT_CMD tee -a /etc/sudoers + fi +else + sudo sed -i "s/PYTHONOPTIMIZE=1/PYTHONOPTIMIZE=0/" "$FINALDIR/opt/bootlocal.sh" +fi + +# Delete unnecessary Babel .dat files +find $FINALDIR -path "*babel/locale-data/*.dat" -not -path "*en_US*" | sudo xargs --no-run-if-empty rm + +# NOTE(pas-ha) Apparently on TinyCore Ansible's 'command' module is +# not searching for executables in the '/usr/local/(s)bin' paths. +# Thus we symlink everything from there to '/usr/(s)bin' which is being searched, +# so that 'command' module picks full utilities installed by 'util-linux' +# instead of built-in simplified BusyBox ones. +set +x +echo "Symlink all from /usr/local/sbin to /usr/sbin" +pushd "$FINALDIR/usr/local/sbin" +for target in *; do + if [ ! -f "$FINALDIR/usr/sbin/$target" ]; then + $CHROOT_CMD ln -s "/usr/local/sbin/$target" "/usr/sbin/$target" + fi +done +popd +echo "Symlink all from /usr/local/bin to /usr/bin" +# this also includes symlinking Python to the place expected by Ansible +pushd "$FINALDIR/usr/local/bin" +for target in *; do + if [ ! -f "$FINALDIR/usr/bin/$target" ]; then + $CHROOT_CMD ln -s "/usr/local/bin/$target" "/usr/bin/$target" + fi +done +popd +set -x + +# Rebuild build directory into gz file +( cd "$FINALDIR" && sudo find | sudo cpio -o -H newc | gzip -9 > "$WORKDIR/tinyipa${BRANCH_EXT}.gz" ) + +# Copy vmlinuz to new name +cp "$WORKDIR/build_files/vmlinuz64" "$WORKDIR/tinyipa${BRANCH_EXT}.vmlinuz" + +# Create tar.gz containing tinyipa files +tar czf tinyipa${BRANCH_EXT}.tar.gz tinyipa${BRANCH_EXT}.gz tinyipa${BRANCH_EXT}.vmlinuz + +# Create sha256 files which will be uploaded by the publish jobs along with +# the tinyipa ones in order to provide a way to verify the integrity of the tinyipa +# builds. +for f in tinyipa${BRANCH_EXT}.{gz,tar.gz,vmlinuz}; do + sha256sum $f > $f.sha256 +done + +# Output files with sizes created by this script +echo "Produced files:" +du -h tinyipa${BRANCH_EXT}.gz tinyipa${BRANCH_EXT}.tar.gz tinyipa${BRANCH_EXT}.vmlinuz +echo "Checksums: " tinyipa${BRANCH_EXT}.*sha256 diff --git a/tinyipa/install-deps.sh b/tinyipa/install-deps.sh new file mode 100755 index 0000000..1c05554 --- /dev/null +++ b/tinyipa/install-deps.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +COMMON_PACKAGES="wget python-pip unzip sudo gawk" +APT_PACKAGES="${COMMON_PACKAGES} squashfs-tools" +YUM_PACKAGES="${COMMON_PACKAGES} squashfs-tools" +ZYPPER_PACKAGES="${COMMON_PACKAGES} squashfs" + +echo "Installing dependencies:" + +# first zypper in case zypper-aptitude is installed +if [ -x "/usr/bin/zypper" ]; then + sudo -E zypper -n install -l ${ZYPPER_PACKAGES} +elif [ -x "/usr/bin/apt-get" ]; then + sudo -E apt-get update + sudo -E apt-get install -y ${APT_PACKAGES} +elif [ -x "/usr/bin/dnf" ]; then + sudo -E dnf install -y ${YUM_PACKAGES} +elif [ -x "/usr/bin/yum" ]; then + sudo -E yum install -y ${YUM_PACKAGES} +else + echo "No supported package manager installed on system. Supported: apt, yum, dnf, zypper" + exit 1 +fi diff --git a/tinyipa/tc-mirror.sh b/tinyipa/tc-mirror.sh new file mode 100644 index 0000000..d7cd8b9 --- /dev/null +++ b/tinyipa/tc-mirror.sh @@ -0,0 +1,53 @@ + +#NOTE(pas-ha) +# The first URL is the official TC repo, +# the rest of the list is taken from +# http://wiki.tinycorelinux.net/wiki:mirrors +# as of time of this writing. +# Only HTTP mirrors were considered with the following ordering +# - those that were unavailable are moved to the bottom of the list +# - those that already responded with 404 are moved to the very bottom + +# List generated on 12-Dec-2016 +TC_MIRRORS="http://repo.tinycorelinux.net +http://distro.ibiblio.org/tinycorelinux +http://mirror.cedia.org.ec/tinycorelinux +http://mirror.epn.edu.ec/tinycorelinux +http://mirrors.163.com/tinycorelinux +http://kambing.ui.ac.id/tinycorelinux +http://ftp.nluug.nl/os/Linux/distr/tinycorelinux +http://ftp.vim.org/os/Linux/distr/tinycorelinux +http://www.gtlib.gatech.edu/pub/tinycore +http://tinycore.mirror.uber.com.au +http://l4u-00.jinr.ru/LinuxArchive/Ftp/tinycorelinux" + +function probe_url { + wget -q --spider --tries 1 --timeout 10 "$1" 2>&1 +} + +function choose_tc_mirror { + if [ -z ${TINYCORE_MIRROR_URL} ]; then + for url in ${TC_MIRRORS}; do + echo "Checking Tiny Core Linux mirror ${url}" + if probe_url ${url} ; then + echo "Check succeeded: ${url} is responding." + TINYCORE_MIRROR_URL=${url} + break + else + echo "Check failed: ${url} is not responding" + fi + done + if [ -z ${TINYCORE_MIRROR_URL} ]; then + echo "Failed to find working Tiny Core Linux mirror" + exit 1 + fi + else + echo "Probing provided Tiny Core Linux mirror ${TINYCORE_MIRROR_URL}" + if probe_url ${TINYCORE_MIRROR_URL} ; then + echo "Check succeeded: ${TINYCORE_MIRROR_URL} is responding." + else + echo "Check failed: ${TINYCORE_MIRROR_URL} is not responding" + exit 1 + fi + fi +} diff --git a/tinyipa/udhcpc.script b/tinyipa/udhcpc.script new file mode 100755 index 0000000..ecd008c --- /dev/null +++ b/tinyipa/udhcpc.script @@ -0,0 +1,44 @@ +#!/bin/sh + +# udhcpc script edited by Tim Riker + +# file created to be used for static network configuration as well + +[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 + +RESOLV_CONF="/etc/resolv.conf" +[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" +[ -n "$subnet" ] && NETMASK="netmask $subnet" + +case "$1" in + deconfig) + /sbin/ifconfig $interface 0.0.0.0 + ;; + + renew|bound) + /sbin/ifconfig $interface up + /sbin/ifconfig $interface $ip $BROADCAST $NETMASK + + if [ -n "$router" ] ; then + echo "deleting routers" + while route del default gw 0.0.0.0 dev $interface ; do + : + done + + metric=0 + for i in $router ; do + route add default gw $i dev $interface metric $((metric++)) + done + fi + + echo -n > $RESOLV_CONF + [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF + for i in $dns ; do + echo adding dns $i + echo nameserver $i >> $RESOLV_CONF + done + ;; +esac + +exit 0 +