Building Apache CloudStack - linux-on-ibm-z/docs GitHub Wiki

Building Apache CloudStack

The instructions provided below specify the steps to build Apache CloudStack version 4.22.0.0 on Linux on IBM Z for the following distributions:

  • RHEL (8.10, 9.4, 9.6, 10.0)
  • SLES 15 SP6
  • Ubuntu (22.04, 24.04)

General Notes:

  • When following the steps below please use a standard permission user unless otherwise specified.
  • A directory /<source_root>/ will be referred to in these instructions, this is a temporary writable directory anywhere you'd like to place it.

We currently support only KVM hypervisor on Apache CloudStack for Linux on IBM Z.

Note: Apache CloudStack(4.22.0.0) was verified with management-server, agent, UI and KVM(4.18.0-553.22.1) at the time of creation of these instructions.

1. Build using script

If you want to build Apache CloudStack using manual steps, go to STEP 2.

Use the following commands to build Apache CloudStack using the build script. Please make sure you have wget installed.

wget -q https://raw.githubusercontent.com/linux-on-ibm-z/scripts/master/CloudStack/4.22.0.0/build_cloudstack.sh

# Build Apache CloudStack
bash build_cloudsatck.sh [The script will use the distro provided Python version, i.e., Python 3.6.8 on RHEL 8.10, Python 3.10 on RHEL 9.x and install python 3.10 for RHEL 10.0]

In case of error, check logs for more details or go to STEP 2 to follow manual build steps.

2. Install Dependencies

export SOURCE_ROOT=/<source_root>/
export PYTHON2_VERSION=2.7.18
export PYTHON3_VERSION=3.10.13
export NVM_DIR="$SOURCE_ROOT/.nvm"
export PACKAGE_VERSION="4.22.0.0"
export PATCH_URL="https://raw.githubusercontent.com/linux-on-ibm-z/scripts/master/CloudStack/${PACKAGE_VERSION}/patch"

2.1. Install Basic Dependencies

  • RHEL
    sudo yum groupinstall -y "Development Tools"
    sudo yum install -y --nobest git python3 python3-pip java-17-openjdk-devel maven genisoimage createrepo nfs-utils qemu-img ipmitool python3-devel python3-libvirt libvirt perl qemu-kvm rng-tools httpd syslinux-tftpboot tftp-server libffi-devel ant curl chkconfig openssl-devel bzip2-devel zlib-devel nodejs npm
    
    # only for rhel 10.0
    sudo yum install -y --nobest mariadb mariadb-server jna rpm-build rpmdevtools
    
    # only for rhel 8.x and 9.x
    sudo yum install -y --nobest mysql mysql-server dhcp-server
    
  • SLES
    sudo zypper -n install sudo wget git java-17-openjdk-devel ant ant-junit python3-libvirt-python libvirt selinux-tools dhcp-server qemu-img qemu-kvm dhcp python3 python2 ipmitool python3-pip unzip cryptsetup ethtool ipset python3-setuptools mkisofs tftp mariadb mysql httpd qemu-tools timezone-java nfs-utils libffi-devel libopenssl-devel rpm-build python3-devel
    
  • Ubuntu
    sudo apt-get install -y dpkg-dev debhelper openjdk-17-jdk genisoimage build-essential python3 python3-setuptools python3-mysql.connector maven ant libjna-java nodejs npm mysql-client augeas-tools mysql-client qemu-utils rng-tools python3-dnspython qemu-kvm libvirt-daemon-system ebtables vlan ipset python3-libvirt ethtool iptables cpu-checker libffi-dev jq
    

2.2. Install Required Python Version

  • Ubuntu 24.x
    curl -O https://www.python.org/ftp/python/${PYTHON2_VERSION}/Python-${PYTHON2_VERSION}.tgz
    sudo tar -xvf Python-${PYTHON2_VERSION}.tgz
    cd Python-${PYTHON2_VERSION} || exit
    sudo bash configure && sudo make && sudo make install
    cd ..
    sudo rm /usr/local/bin/python
    sudo ln -s /usr/bin/python3 /usr/local/bin/python
    sudo apt-get install -y python3-pip |& tee -a "$LOG_FILE"
    
  • RHEL 10.x
    wget https://www.python.org/ftp/python/${PYTHON3_VERSION}/Python-${PYTHON3_VERSION}.tgz                                       
    tar -xvzf Python-${PYTHON3_VERSION.tgz
    cd Python-${PYTHON3_VERSION}                                 
    ./configure --prefix=$SOURCE_ROOT/python3.10 --enable-optimizations
    make
    make -j$(nproc)
    make install
    export PATH=$SOURCE_ROOT/python3.10/bin:$PATH
    export PYTHON=$(which python3.10)
    

2.3. Install Nodejs

  • RHEL 9.x, 10.x
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash

[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install and use Node.js version 14
nvm install 14
nvm use 14

NVM_BIN=$(nvm which current | xargs dirname)
sudo ln -sf "$NVM_BIN/node" /usr/bin/node
sudo ln -sf "$NVM_BIN/npm" /usr/bin/npm
export PATH="$HOME/.nvm/versions/node/v14.*/bin:$PATH"
  • RHEL 8.10, Ubuntu, SLES
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.4/install.sh | bash

[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Install and use Node.js version 10
nvm install 10
nvm use 10

NVM_BIN=$(nvm which current | xargs dirname)
sudo ln -sf "$NVM_BIN/node" /usr/local/bin/node
sudo ln -sf "$NVM_BIN/npm" /usr/local/bin/np

2.4. Install Java

  • RHEL 8.x and 9.x
    sudo yum -y install java-17-openjdk java-17-openjdk-devel
    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk
    
  • RHEL 10.x
    sudo mkdir -p /opt/java
    cd "$SOURCE_ROOT"
    sudo wget -O temurin17.tar.gz https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.14%2B7/OpenJDK17U-jdk_s390x_linux_hotspot_17.0.14_7.tar.gz
    sudo tar -C /opt/java -xzf temurin17.tar.gz --strip 1
    export JAVA_HOME=/opt/java
    
  • SLES
    sudo zypper -y install java-17-openjdk java-17-openjdk-devel
    export JAVA_HOME=/usr/lib64/jvm/java-17-openjdk
    
  • Ubuntu
    sudo apt -y install openjdk-17-jdk
    export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-s390x
    

Set path and update alterantives for all distributions

export PATH="${JAVA_HOME}/bin:${PATH}"

sudo update-alternatives --install /usr/bin/java java $JAVA_HOME/bin/java 40
sudo update-alternatives --set java $JAVA_HOME/bin/java
sudo update-alternatives --install /usr/bin/javac javac $JAVA_HOME/bin/javac 40
sudo update-alternatives --set javac $JAVA_HOME/bin/javac

java -version
javac -version

2.5. Install Maven

  • RHEL 8.x
    wget https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
    tar -xvzf apache-maven-3.6.3-bin.tar.gz
    export PATH=${SOURCE_ROOT}/apache-maven-3.6.3/bin:$PATH
    
  • SLES
    wget https://archive.apache.org/dist/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-bin.tar.gz
    tar -xvzf apache-maven-3.8.8-bin.tar.gz
    sudo mv apache-maven-3.8.8 /opt/maven
    echo -e "\nexport M2_HOME=/opt/maven\nexport MAVEN_HOME=/opt/maven\nexport PATH=\$PATH:\$M2_HOME/bin" | sudo tee -a /etc/environment > /dev/null
    source /etc/environment
    

2.6. Build and Install libvirt-java

  • Clone libvirt-java

    mkdir -p /${SOURCE_ROOT}/.m2/repository/org/libvirt/libvirt/0.5.3/
    cd $SOURCE_ROOT
    
    git clone -b v0.5.3 https://github.com/libvirt/libvirt-java.git
    cd libvirt-java
    
  • Only for SLES

    mkdir -p lib && cd lib
    wget -O jna.jar https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.5.0/jna-5.5.0.jar
    wget -O junit.jar https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar
    cd ..
    sed -i '0,/\${jar.dir}/s/\${jar.dir}/lib/; 0,/\${jar.dir}/s/\${jar.dir}/lib/' build.xml
    
  • Apply patch and build libvirt-jar

    curl -sSL $PATCH_URL/libvirt_0_5_3_java_s390x.patch | git apply -
    sudo bash autobuild.sh
    
    sudo cp -f target/libvirt-0.5.3.jar /${SOURCE_ROOT}/.m2/repository/org/libvirt/libvirt/0.5.3/
    

3. Installation

3.1. Clone and apply patch

cd $SOURCE_ROOT
git clone -b $PACKAGE_VERSION https://github.com/apache/cloudstack.git
cd cloudstack
curl -sSL $PATCH_URL/master.patch | git apply -

3.2 Modify Build Config

replace_line_in_file() {
    if [[ ! -f "$1" ]]; then
        echo "Error: File '$1' not found!"
        return 1
    fi

    sed -i.bak "/$2/c\\$3" "$1"
    if [[ $? -eq 0 ]]; then
        echo "Line replaced successfully in $1."
        rm -f "$1.bak"
    else
        echo "Error: Failed to replace the line in $1."
    fi
}
  • RHEL, SLES

    replacement_line='cd ui && sudo rm -rf /${SOURCE_ROOT}/cloudstack/dist/rpmbuild/BUILD/cloudstack-${PACKAGE_VERSION}/ui/node_modules && npm install --force && NODE_OPTIONS="--max-old-space-size=4096" npm run build && cd ..'
    search_line='${SOURCE_ROOT}/cloudstack/packaging/centos8/cloud.spec'
    
    replace_line_in_file centos8/cloud.spec "$search_line" "$replacement_line"
    
  • SLES

    replace_line_in_file '${SOURCE_ROOT}/cloudstack/packaging/centos8/cloud.spec' "BuildRequires: nodejs" "#BuildRequires: nodejs"
    
  • Ubuntu

    replacement_line="$(printf '\t')cd ui && npm install --force && NODE_OPTIONS=\"--max-old-space-size=4096\" npm run build && cd .."
    search="Depends: \${misc:Depends}, \${python3:Depends}, genisoimage, nfs-common, python3-pip, python3-distutils \| python3-distutils-extra, python3-netaddr, uuid-runtime"
    
    replace_line_in_file debian/control " nodejs (>= 12), lsb-release, dh-systemd | debhelper (>= 13)" " lsb-release, dh-systemd | debhelper (>= 13)"
    replace_line_in_file debian/control " python (>= 2.7) | python2 (>= 2.7), python3 (>= 3), python-setuptools, python3-setuptools," " python3 (>= 3), python3-setuptools,"
    replace_line_in_file debian/control "$search" "Depends: \${misc:Depends}, \${python3:Depends}, genisoimage, nfs-common, python3-netaddr"
    replace_line_in_file debian/control "Depends: \${misc:Depends}, python3-pip, python3-dev, libffi-dev" "Depends: \${misc:Depends}, libffi-dev"
    replace_line_in_file debian/rules "$(printf '\t')cd ui && npm install && npm run build && cd .." "$replacement_line"
    
    # Ubuntu-24.10
    sed -i '/mkdir -p $(DESTDIR)\/usr\/share\/$(PACKAGE)-marvin/s/$/ \&\& cp tools\/marvin\/dist\/marvin-\*.tar.gz tools\/marvin\/dist\/Marvin-\*.tar.gz/' debian/rules
    

3.3. Build and Install

  • RHEL, SLES

    cd ${SOURCE_ROOT}/cloudstack/packaging/
    sudo ./package.sh -d centos8
    cd ${SOURCE_ROOT}/cloudstack/dist/rpmbuild/RPMS/s390x/
    
    • Host Machine
      sudo rpm --nodeps -i cloudstack-common-${PACKAGE_VERSION}-1.noarch.rpm cloudstack-agent-${PACKAGE_VERSION}-1.noarch.rpm
      
    • Management Server
      sudo rpm --nodeps -i cloudstack-common-${PACKAGE_VERSION}-1.noarch.rpm cloudstack-management-${PACKAGE_VERSION}-1.noarch.rpm cloudstack-ui-${PACKAGE_VERSION}-1.noarch.rpm cloudstack-usage-${PACKAGE_VERSION}-1.noarch.rpm
      
  • Ubuntu

    nvm exec 10 sudo -E dpkg-buildpackage -d
    cd $SOURCE_ROOT
    
    • Host Machine
      sudo dpkg -i ./cloudstack-common_${PACKAGE_VERSION}_all.deb cloudstack-agent_${PACKAGE_VERSION}_all.deb
      
    • Management Server
      sudo dpkg -i ./cloudstack-common_${PACKAGE_VERSION}_all.deb ./cloudstack-management_${PACKAGE_VERSION}_all.deb ./cloudstack-ui_${PACKAGE_VERSION}_all.deb ./cloudstack-usage_${PACKAGE_VERSION}_all.deb
      

Note: Apache CloudStack build is resource intensive and will take time to build

4. Verification (optional)

  • RHEL, SLES
    version=$(echo "$(rpm -qa cloudstack-agent*)" | grep -oP '\d+\.\d+\.\d+\.\d+')
    if [ "$version" == "${PACKAGE_VERSION}" ]; then
        printf -- "CloudStack ${version} Successfully Installed .\n"
    fi
    
  • Ubuntu
    installed_version=$(dpkg -l | grep cloudstack-agent)
    version=$(echo "$installed_version" | grep -oP '\d+\.\d+\.\d+\.\d+')
    if [ "$version" == "${PACKAGE_VERSION}" ]; then
        printf -- "CloudStack ${version} Successfully Installed .\n"
    fi
    

Notes:

  • Follow this quick installation guide for setup
  • Make sure sql server is setup before installation of cloudstack-management
  • Once installed check status of cloudstack-management using systemctl status cloudstack-management
  • Verify UI on <management-server-ip:8080> login and add Host Machine in Hosts

5. SystemVM Image Setup

5.1. Create a VM on KVM Hypervisor

# Create disk image
cd $SOURCE_ROOT
qemu-img create -f qcow2 <systemvm-image-name.img> 20G

# wget -q https://cdimage.debian.org/mirror/cdimage/archive/11.10.0/s390x/iso-cd/debian-11.10.0-s390x-netinst.iso 
wget -q <s390x-based-image.iso>

virt-install --name=<systemvm-template-name> --ram=2048 --vcpus=2 --disk path=<systemvm-image-name.img>,size=20 --network bridge=<bridge-name> --console pty,target_type=serial --location <s390x-based-image.iso> --import

Note:

  • Create user cloud during installation. SystemVM template build script requires it.

5.2. Copy Tools and SystemVM

virsh console <systemvm-template-name>
# login as root
scp -r <user>@<host-ip>:/path-to-cloudstack-repo-home/tools .
scp -r <user>@<host-ip>:/path-to-cloudstack-repo-home/systemvm .

5.3. Configure SystemVM

cd tools/appliance/systemvmtemplate/scripts
chmod +x build_s390x_systemvm.sh
./build_s390x_systemvm.sh

5.4. Convert Image

virsh shutdown <systemvm-template-name>
cd <image-path>
qemu-img convert -O qcow2 <systemvm-image-name.img> /<output-path>/<systemvm-template-name.qcow2>

Notes:

  • Output .qcow2 file is system vm template for s390x and can be registered on CloudStack UI > Images > Templates
  • Follow the steps mentioned under KVM in this link to configure this template as default systemvm template
  • For creating Guest Templates go through this link

6. CloudStack Simulator Image

CloudStack Simulator is an all in one CloudStack Build including the simulator that mimic Hypervisor.

6.1. Environment setup

  • The build environment must have Docker installed, and the Docker service must be running. Docker packages are provided for RHEL, SLES and Ubuntu in their respective repositories. More information about Docker CE can be found here.

6.2. Clone Source Code and Apply Patches

  • Follow steps 3.1 and 3.2, and then apply the dockerfile patch:
cd ${SOURCE_ROOT}/cloudstack/tools/docker
xcurl -sSL $PATCH_URL/cloudstack_simulator.patch | git apply -

6.3. Build Image and create a container

docker build -f Dockerfile -t cloudstack/simulator ../..

6.4. Start a Container

docker run --name simulator -p 8080:5050 -d cloudstack/simulator

Note: For detailed instructions on using and managing this CloudStack Simulator setup, refer here.

7. Cleanup

sudo rm -rf $SOURCE_ROOT/libvirt-java
sudo rm -rf $SOURCE_ROOT/rpmbuild
sudo rm -rf $SOURCE_ROOT/cloudstack/master.patch
sudo rm -rf $SOURCE_ROOT/temurin17.tar.gz
sudo rm -rf $SOURCE_ROOT/Python-${PYTHON2_VERSION}
sudo rm -rf $SOURCE_ROOT/Python-${PYTHON2_VERSION}.tgz
sudo rm -rf $SOURCE_ROOT/Python-${PYTHON3_VERSION}
sudo rm -rf $SOURCE_ROOT/Python-${PYTHON3_VERSION}.tgz

References:

⚠️ **GitHub.com Fallback** ⚠️