<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 -->

# Apache CloudStack Installation basics

This document describes how to develop, build, package and install Apache
CloudStack. For more information please refer to the official [documentation](https://docs.cloudstack.apache.org)
or the developer [wiki](https://cwiki.apache.org/confluence/display/CLOUDSTACK/Home).

Apache CloudStack developers use various platforms for development, this guide
was tested against a CentOS 7 x86_64 setup.

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Setting up Development Environment](#setting-up-development-environment)
  - [Using jenv and/or pyenv for Version Management](#using-jenv-andor-pyenv-for-version-management)
- [Getting the Source Code](#getting-the-source-code)
- [Building](#building)
- [To bring up CloudStack UI](#to-bring-up-cloudstack-ui)
- [Building with non-redistributable plugins](#building-with-non-redistributable-plugins)
- [Packaging and Installation](#packaging-and-installation)
  - [Debian/Ubuntu](#debianubuntu)
  - [RHEL/CentOS](#rhelcentos)
- [Notes](#notes)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Setting up Development Environment

Install tools and dependencies used for development:

    # yum -y install git java-17-openjdk java-17-openjdk-devel \
      mysql mysql-server mkisofs git gcc python MySQL-python openssh-clients wget

Set up Maven (3.9.10):

    # wget https://dlcdn.apache.org/maven/maven-3/3.9.10/binaries/apache-maven-3.9.10-bin.tar.gz
    # sudo tar -zxvf apache-maven-3.9.10-bin.tar.gz -C /usr/local
    # cd /usr/local
    # sudo ln -s apache-maven-3.9.10 maven
    # echo export M2_HOME=/usr/local/maven >> ~/.bashrc # or .zshrc or .profile
    # echo export PATH=/usr/local/maven/bin:${PATH} >> ~/.bashrc # or .zshrc or .profile
    # source ~/.bashrc

Setup up Node.js 16:

    # curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash -
    # sudo yum install nodejs
    # sudo npm install -g @vue/cli npm-check-updates

Start the MySQL service:

    $ service mysqld start
    $ mysql_secure_installation

### Using jenv and/or pyenv for Version Management

CloudStack is built using Java and Python.  To make selection of these tools versions more consistent and ease installation for developers, optional support for [jenv](http://www.jenv.be/) and [pyenv](https://github.com/yyuu/pyenv) with [virtualenv]|(https://github.com/yyuu/pyenv-virtualenv) is provided.  jenv installation instructions are available here and pyenv installation instructions are available here.  For users of [oh-my-zsh](https://ohmyz.sh/) there is a pyenv plugin available to trigger configuration of pyenv in a shell session.

Following installation, execute the following commands to configure jenv and pyenv for use with CloudStack development:

    # pyenv install 2.7.16                                          ## Install Python 2.7.16
    # pyenv virtualenv 2.7.16 cloudstack                            ## Create a cloudstack virtualenv using Python 2.7.16
    # pip install -r <root CloudStack source tree>/requirements.txt ## Install cloudstack Python dependencies
    # jenv add <path to JDK 1.8 installation>                       ## Add Java7 to jenv

*N.B.* If you are running Linux, you may need to install additional packages to allow pyenv to build Python.

Following these steps, jenv and pyenv will use .java-version and .python-version files in the root of the CloudStack source tree to switch to the correct Java version and the cloudstack Python virtualenv for CloudStack development.

## Getting the Source Code

You may get the source code from the repository hosted on Apache:

    $ git clone https://gitbox.apache.org/repos/asf/cloudstack.git

Or, you may fork the repository from the official Apache CloudStack mirror on [GitHub](https://github.com/apache/cloudstack)

To checkout a specific branch, for example 4.11, do:

    $ git fetch origin
    $ git checkout -b 4.11 origin/4.11

## Building

Clean and build:

    $ mvn clean install -P systemvm,developer

Clear old database (if any) and deploy the database schema:

    $ mvn -P developer -pl developer -Ddeploydb

Export the following variable if you need to run and debug the management server:

    $ export MAVEN_OPTS="-Xmx1024m -XX:MaxMetaspaceSize=500m -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n"

Start the management server:

    $ mvn -pl :cloud-client-ui jetty:run

If this works, you've successfully setup a single server Apache CloudStack installation.

To access the Management Server UI, follow the following procedure:

The default credentials are; user: admin, password: password and the domain
field should be left blank which is defaulted to the ROOT domain.

## To bring up CloudStack UI

Move to UI Directory

    $ cd /path/to/cloudstack/ui

To install dependencies.

    $ npm install

To build the project.

    $ npm run build

For Development Mode.

    $ npm start

Make sure to set `CS_URL=http://localhost:8080` on the `.env.local` file on UI.

You should be able to run the management server on http://localhost:5050

## Building with non-redistributable plugins

CloudStack supports several plugins that depend on libraries with distribution restrictions.
Because of this they are not included in the default build. Enable these additional plugins
activate their respective profiles. For convenience adding -Dnoredist will enable all plugins
that depend on libraries with distribution restrictions. The build procedure expects that the
required libraries are present in the maven repository.

The following procedure can be used to add the libraries to the local maven repository. Details
on obtaining the required libraries can be found in this file. Note that this will vary between
releases of CloudStack

    $ cd deps
    $ ./install-non-oss.sh

To build all non redistributable components, add the noredist flag to the build command:

    $ mvn clean install -P systemvm,developer -Dnoredist

## Packaging and Installation

Before packaging, please make sure you go through the "Building" section above. This section describes packaging and installation.

### Debian/Ubuntu

To create debs install the following extra packages:

    # apt-get -y install python-mysqldb
    # apt-get -y install debhelper

Then:

    $ mvn -P deps # -D noredist, for noredist as described in the "Building" section above
    $ dpkg-buildpackage -uc -us

All the deb packages will be located one level down.

### RHEL/CentOS

To create rpms, install the following extra packages:

    # yum -y install rpm-build
    # yum -y install ws-commons-util
    # yum -y install gcc
    # yum -y install glibc-devel
    # yum -y install MySQL-python

Then:

    $ cd packaging
    $ package.sh

To create packages for noredist add the `-p noredist` option to the package script.
All the rpm packages will be created in `dist/rpmbuild/RPMS/x86_64` directory.

## Notes

If you will be using Xen as your hypervisor, please download [vhd-util](https://download.cloudstack.org/tools/vhd-util)

If management server is installed on RHEL/CentOS, then copy vhd-util into:

    /usr/lib64/cloud/common/scripts/vm/hypervisor/xenserver/

If management server is installed on Ubuntu, then put vhd-util into:

    /usr/lib/cloud/common/scripts/vm/hypervisor/xenserver/vhd-util
