If this is your first encounter with CORD, we suggest you start by bringing up an Virtual Pod, which installs CORD on a set of virtual machines running on a single physical server: Installing a Virtual Pod (CORD-in-a-Box).
You can also install CORD on a physical POD, as would be done in a production environment, which involves first assembling a set of servers and switches, and then pointing the build system at that target hardware: Installing a Physical POD.
If you are interested in developing a new CORD service, working on the XOS GUI, or performing other development tasks, see Developing for CORD.
If want to know more about the CORD build process, please see Build Process Internals and Building Docker Images.
If you're having trouble installing CORD, please see Troubleshooting.
CORD has a unified build system for development and deployment which uses the following tools:
And either:
cord-bootstrap.sh
for more details *You can manually install these on your development system - see Getting the Source Code for a more detailed instructions for checking out the CORD source tree.
If you're working on an cleanly installed Ubuntu 14.04 system, you can use the cord-bootstrap.sh
script to install these tools and check out the CORD source tree to ~/cord
.
{% include "/partials/cord-bootstrap.md" %}
NOTE: Change the
master
path component in the URL to your desired version branch (ex:cord-5.0
) if required.
The bootstrap script has the following options:
Usage for ./cord-bootstrap.sh: -d Install Docker for local scenario. -h Display this help message. -p <project:change/revision> Download a patch from gerrit. Can be repeated. -t <target> Run 'make -j4 <target>' in cord/build/. Can be repeated. -v Install Vagrant for mock/virtual/physical scenarios. -x Use Xenial (16.04) in Vagrant VM's.
Using the -v
option is required to install Vagrant for running a Virtual Pod (CiaB) or Physical Pod, whereas -d
is required to install Docker for a Local Workflow.
The -p
option downloads a patch from gerrit, and the syntax for this is <project path>:<changeset>/<revision>
. It can be used multiple time. For example:
./cord-bootstrap.sh -p build/platform-install:1233/4 -p orchestration/xos:1234/2
checks out the platform-install
repo with changeset 1233, patchset 4, and xos
repo changeset 1234, revision 2.
You can find the project path in the repo
manifest file: manifest/default.xml.
You can also run make targets with the -t
option; -t build
is the same as running cd ~/cord/build ; make -j4 build
after the rest of the installations and downloads have completed.
In some cases, you may see a message like this if you install software that adds you to a group and you aren't already a member:
You are not in the group: libvirtd, please logout/login. You are not in the group: docker, please logout/login.
In such cases, please logout and login to the system to gain the proper group membership. Another way to tell if you're in the right groups:
~$ groups xos-PG0 root ~$ vagrant status Call to virConnectOpen failed: Failed to connect socket to '/var/run/libvirt/libvirt-sock': Permission denied ~$ logout ~$ ssh node_name.cloudlab.us ~$ groups xos-PG0 root libvirtd
Note that if you aren't in the right group, any patches specified by -p
will be downloaded, but no make targets specified by -t
will be run - you will need to cd ~/cord/build
and run those targets manually.
The CORD build process is designed to be modular and configurable with only a handful of YAML files.
Each CORD use-case (e.g., R-CORD, M-CORD, E-CORD) has its own repository containing configuration files for that type of POD. All of these repositories appear in the source tree under orchestration/profiles/
. For example, R-CORD's repository is [orchestration/profiles/rcord](https://github.com/opencord/rcord/tree/{{ book.branch }}).
The top level configuration for a build is the POD config file, a YAML file stored in each use-case repository's podconfig
subdirectory. Each Pod config file contains a list of variables that control how the build proceeds, and can override the configuration of the rest of the build. A minimal POD config file must define two variables:
cord_profile
- the name of a profile to use, defined as a YAML file at the top level of the use-case repository - ex: [mcord-ng40.yml](https://github.com/opencord/mcord/blob/{{ book.branch }}/mcord-ng40.yml).
cord_scenario
- the name of the scenario to use, which is defined in a directory under [build/scenarios](https://github.com/opencord/cord/tree/{{ book.branch }}/scenarios).
The naming convention for POD configs stored in the use case repository is <profile>-<scenario>.yml
- ex: [mcord-ng40-virtual.yml](https://github.com/opencord/mcord/blob/{{ book.branch }}/podconfig/mcord-ng40-virtual.yml) builds the virtual
scenario using the mcord-ng40
profile. All such POD configs can be specified during a build using the PODCONFIG
variable:
make PODCONFIG=rcord-virtual.yml config
POD configs with arbitrary paths can be specified using PODCONFIG_PATH
. This will override the PODCONFIG
variable.
make PODCONFIG_PATH=./podconfig/my-pod-config.yml config
Additionally, if you are specifying a physical installation, you need to:
Specify the inventory in your POD Config in order to tells Ansible and the build system which machines you wish to install a CORD POD on, and which ansible inventory roles map onto them.
Set headnode
(and optionally buildnode
) variables to match the inventory.
Set vagrant_vms
variable to only bring up VM's you need, which may be none, in which case you should specify the empty list: vagrant_vms: []
.
Add items to the physical_node_list for all nodes listed in the inventory.
The ONF internal pod-configs repository gives many examples of physical POD Configs that are used for testing of CORD.
The set of services that XOS on-boards into CORD -- the Service Graph, and other per-profile configuration for a CORD deployment. These are checked out by repo into the orchestration/profiles
directory. The current set of profiles is:
To handle the variety of types of deployments CORD supports, including physical deployments, development, and testing in virtual environments, the scenario mechanism was developed to allow for a common build system.
A scenario determine:
Which sets of components of CORD are installed during a build, by controlling which make targets are run, and the dependencies between them.
A virtual-specific inventory and machine definitions used with Vagrant, which is used for development and testing of the scenario with virtual machines.
A whitelist of docker images used when building this scenario.
Scenarios are subdirectories of the [build/scenarios](https://github.com/opencord/cord/tree/{{ book.branch }}/scenarios) directory, and consist of a config.yaml
configuration file and VM's specified in a Vagrantfile
.
The current set of scenarios:
local
: Minimal set of containers running locally on the development host
mock
: Creates a single Vagrant VM with containers and DNS set up, without synchronizers
single
: Creates a single Vagrant VM with containers and DNS set up, with synchronizers and optionally ElasticStack/ONOS
cord
: Physical or virtual multi-node CORD pod, with MaaS and OpenStack
controlpod
: Physical or virtual single-node CORD control-plane only POD, with XOS and ONOS, suitable for some use cases such as ecord-global
.
controlkube
: "Laptop sized" Kubernetes-enabled multi-node pod
preppedpod
: Physical or virtual multi-node CORD pod on a pre-prepared (OS installed) nodes, with ONOS and OpenStack, but lacking MaaS, for use in environments where there is an existing provisioning system for compute hardware.
preppedkube
: "Deployment/Server sized" Kubernetes-enabled multi-node pod
How these scenarios are used for development is covered in the Example Worflows section.
The primary mechanism that Scenarios use to modularize the build process by enabling Makefile and creating prerequisite targets, which in turn controls whether ansible playbooks or commands are run. make
is dependency based, and the targets to create when make build
is run is specified in the build_targets
list in the scenario.
Creating and extending scenarios is covered in the Build Process Internals.
A node inventory is defined in the inventory_groups
variable, and must be set in the scenario or overridden in the POD config.
The default inventory defined in a scenario has the settings for a virtual install which is used in testing and development. It corresponds to the machines in the Vagrantfile for that scenario.
The CORD build system defines 4 ansible inventory groups (config
, build
, head
, compute
), 3 of which (all but compute
) need to have at least one physical or virtual node assigned. The same node can be assigned to multiple groups, which is one way that build modularity is achieved.
config
: This is where the build steps are run (where make
and ansible
execute), and where the configuration of a POD is generated. It is generally is set to localhost
.build
: Where the build steps are run, for building the Docker containers for CORD. The node in this group is frequently the same as the head
node.head
: The traditional "head node", which hosts services for bootstrapping the POD.compute
: Nodes for running VNFs. This may be populated (as in the preppedpod
and related scenarios) or not (in the cord
scenario, which bootstraps these compute nodes with MaaS)For all physical installations of CORD, the POD config must override the scenario inventory. The [default physical example](https://github.com/opencord/cord/blob/{{ book.branch }}/podconfig/physical-example.yml) gives examples of how to do this, and additional POD config examples can be found in the CORD QA systems pod-config repo.
The inventory is specified using the inventory_groups
dictionary in the scenario config.yml
or the podconfig YAML file. The format is similar to the Ansible YAML inventory except without the hosts
key below the groups names. Variables can optionally be specified on a per-host basis by adding sub-keys to the host name. If the host is listed multiple times, the same variables must be specified each time.
Here is an example inventory for a podconfig using the preppedpod
scenario with a physical pod - note that the build node is the same as the head node (they have the same IP), and the variables are replicated there. The config node is the default of localhost
:
inventory_groups: config: localhost: ansible_connection: local build: head1: ansible_host: 10.1.1.40 ansible_user: cordadmin ansible_ssh_pass: cordpass head: head1: ansible_host: 10.1.1.40 ansible_user: cordadmin ansible_ssh_pass: cordpass compute: compute1: ansible_host: 10.1.1.41 ansible_user: cordcompute ansible_ssh_pass: cordpass compute2: ansible_host: 10.1.1.42 ansible_user: cordcompute ansible_ssh_pass: cordpass