Manual
"Just download and run"
Manual
[~/sandbox]$ vagrant init -m centos/7
[~/sandbox]$ cat Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
end
Manual
[~/sandbox]$ vagrant up
Manual
[~/sandbox]$ vagrant ssh
[vagrant@localhost ~]$
Manual
[vagrant@localhost ~]$ curl -o distribution-karaf-0.2.3-Helium-SR3.tar.gz \
<long tarball URL>
Manual
[vagrant@localhost ~]$ sudo mkdir /opt/opendaylight
Manual
[vagrant@localhost ~]$ sudo tar -x
--strip-components=1
--directory=/opt/opendaylight
-f <long tarball name>
Manual
[vagrant@localhost ~]$ sudo /opt/opendaylight/bin/karaf server
karaf: java command not found
Manual
[vagrant@localhost ~]$ sudo yum install -y java
Manual
vagrant@localhost ~]$ sudo /opt/opendaylight/bin/karaf server &
Manual
Running as root :(
[vagrant@localhost bin]$ ps -u -p `pgrep java` | awk {'print $1'}
root
Manual
Create `odl:odl` user:group?
Manual
Want a home dir for that user?
Manual
chown ODL's dir to `odl:odl`
Manual
Restart ODL service
Manual
(if only you had systemd support)
Manual
Login and configure Karaf features?
Manual
Port configuration?
Manual
Automatic deployments?
manual
First user experience?
manual
Modern users expect better
Manual
Modern deployments need better
Puppet
We work to make contributing easy.
Puppet
Community: Ubuntu support
Puppet
Supports tarball-based installs
Puppet
class { 'opendaylight':
install_method => 'tarball',
tarball_url => '<URL to your custom tarball>',
unitfile_url => '<URL to your custom unitfile>',
}
Puppet
Major part of OPNFV
Puppet
[~/puppet-opendaylight]$ bundle exec rake test
Puppet
At a high level...
Puppet
---> syntax:manifests
---> syntax:templates
---> syntax:hiera:yaml
Puppet
Finished in 14.14 seconds (files took 0.53374 seconds to load)
537 examples, 0 failures
Total resources: 17
Touched resources: 17
Resource coverage: 100.00%
Puppet
rspec-puppet
"We're saying what we expected we said"
Puppet
metadata-json-lint metadata.json
Puppet
Deploy against real VMs
Puppet
Verify resulting state
Puppet
Repeat for various configs
Puppet
At a high level...
Puppet
Bringing machine 'centos-7' up with 'virtualbox' provider...
centos-7 12:45:09$ yum install -y puppet
Puppet
centos-7 12:45:46$ puppet apply <test manifest>
Puppet
centos-7 12:49:37$ /bin/sh -c systemctl\ is-active\ opendaylight
active
centos-7 executed in 0.04 seconds
should be running
Puppet
centos-7 12:49:37$ /bin/sh -c id\ odl
uid=1001(odl) gid=1001(odl) groups=1001(odl)
centos-7 executed in 0.04 seconds
should exist
Puppet
centos-7 executed in 0.05 seconds
should match /^featuresBoot=standard,ssh/
Puppet
Finished in 5 minutes 22 seconds (files took 1 minute 10.87 seconds to load)
51 examples, 0 failures
Puppet
Beaker is pretty great
Puppet
Example: Vagrant provisioner
Puppet
At a high level...
Puppet
# Box that installs ODL via Puppet RPM method on CentOS 7
config.vm.define "cent7_pup_rpm" do |cent7_pup_rpm|
# Build Vagrant box based on CentOS 7
cent7_pup_rpm.vm.box = "chef/centos-7.0"
# Add EPEL repo for access to Puppet et al
cent7_pup_rpm.vm.provision "shell", inline: "yum install -y epel-release"
# Install Puppet
cent7_pup_rpm.vm.provision "shell", inline: "yum install -y puppet"
# Install OpenDaylight using its Puppet module
cent7_pup_rpm.vm.provision "puppet" do |puppet|
puppet.module_path = ["modules"]
puppet.manifest_file = "odl_install.pp"
end
end
Puppet
Configure provisioner
# Install OpenDaylight using its Puppet module
cent7_pup_rpm.vm.provision "puppet" do |puppet|
puppet.module_path = ["modules"]
puppet.manifest_file = "odl_install.pp"
end
Puppet
puppet.module_path = ["modules"]
Puppet
[~/vagrant-opendaylight]$ librarian-puppet install
[~/vagrant-opendaylight]$ ls modules
archive java opendaylight stdlib
Puppet
[~/vagrant-opendaylight]$ cat Puppetfile
#!/usr/bin/env ruby
forge "https://forgeapi.puppetlabs.com"
mod 'dfarrell07-opendaylight',
:git => 'git://github.com/dfarrell07/puppet-opendaylight.git',
:ref => 'origin/master'
Puppet
puppet.manifest_file = "odl_install.pp"
Puppet
[~/vagrant-opendaylight]$ cat manifests/odl_install.pp
class { 'opendaylight':
extra_features => ['odl-ovsdb-openstack'],
}
Puppet
[~/vagrant-opendaylight]$ vagrant up cent7_pup_rpm
Puppet
ODL installed
Notice: /Stage[main]/Opendaylight::Install/Yumrepo[opendaylight]/ensure: created
Notice: /Stage[main]/Opendaylight::Install/Package[opendaylight]/ensure: created
Puppet
Features configured
/Stage[main]/Opendaylight::Config/File[org.apache.karaf.features.cfg]/content: content changed '<hash>' to '<different hash>'
Puppet
[~/vagrant-opendaylight]$ vagrant ssh cent7_pup_rpm
[vagrant@localhost ~]$
Puppet
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Puppet
[vagrant@localhost ~]$ /vagrant/scripts/connect.sh
Puppet
opendaylight-user@root>config:list | grep featuresBoot\ =
featuresBoot = <default features>,odl-ovsdb-openstack
Puppet
opendaylight-user@root>feature:list | grep odl-ovsdb-openstack
odl-ovsdb-openstack | 1.0.3-Helium-SR3 | x | ovsdb-1.0.3-Helium-SR3 <snip>
Puppet
Con: Complexity vs Ansible
(for me, not for users)
Puppet
Con: Ecosystem quality
Puppet
Future: OS support updates
Puppet
Future: Beaker using containers for speed
Puppet
Future:
Stackforge? OpenStack Puppet mods?
Ansible
[~/ansible-opendaylight]$ cat tasks/main.yml
---
- include: add_odl_yum_repo.yml
- include: install_odl_rpm.yml
- include: configure_karaf_features.yml
- include: configure_nb_rest_port.yml
- include: open_nb_rest_port.yml
- include: start_odl_systemd_service.yml
Ansible
- name: Start ODL systemd service
service:
name=opendaylight
enabled=yes
state=started
Ansible
- name: Configure ODL Karaf features
template:
src=org.apache.karaf.features.cfg
dest=/opt/opendaylight/etc/
owner=odl
group=odl
notify:
- Stop ODL
- Cleanup Karaf
- Start ODL
Ansible
[~/ansible-opendaylight]$ wc -l **/*.yml
<snip>
166 total
Ansible
Rejects Puppet's style of testing
“don’t unit test your playbook"
“Ansible believes you should not need another framework to validate basic things of your infrastructure”
Ansible
So no rspec-puppet or Beaker
Ansible
Beaker was kinda nice...
Ansible
No tears for rspec-puppet
Ansible
Fail fast and clearly
Ansible
Focus on the deployment logic
Ansible
Example: Vagrant provisioner
Ansible
At a high level...
Ansible
# Box that installs ODL via its Ansible role on CentOS 7
config.vm.define "cent7_ansible" do |cent7_ansible|
# Build Vagrant box based on CentOS 7
cent7_ansible.vm.box = "chef/centos-7.0"
# Install ODL using the Ansible provisioner
cent7_ansible.vm.provision "ansible" do |ansible|
# Path to playbook that installs ODL using ODL's Ansible role
ansible.playbook = "provisioning/playbook.yml"
end
end
Ansible
ansible.playbook = "provisioning/playbook.yml"
ansible
Provision the box
Ansible
[~/vagrant-opendaylight]$ vagrant up cent7_ansible
ansible
At a high level...
Ansible
TASK: [opendaylight | Add ODL yum repo] **********************************
changed: [cent7_ansible]
TASK: [opendaylight | Install ODL RPM] ***********************************
changed: [cent7_ansible]
Ansible
TASK: [opendaylight | Configure ODL Karaf features] **********************
changed: [cent7_ansible]
Ansible
TASK: [opendaylight | Configure ODL NB REST port] ************************
changed: [cent7_ansible]
TASK: [opendaylight | Check if FirewallD service is running] *************
ok: [cent7_ansible]
TASK: [opendaylight | Open ODL NB REST port via FirewallD] ***************
skipping: [cent7_ansible]
Ansible
TASK: [opendaylight | Start ODL systemd service] *************************
changed: [cent7_ansible]
Ansible
[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible
[vagrant@localhost ~]$
Ansible
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Ansible
Example: config change
Ansible
[~/vagrant-opendaylight]$ cat provisioning/playbook.yml
---
- hosts: all
sudo: yes
roles:
- role: opendaylight
- extra_features: ['odl-ovsdb-openstack']
ansible
At a high level...
Ansible
TASK: [opendaylight | Configure ODL Karaf features] **********************
changed: [cent7_ansible]
Ansible
NOTIFIED: [opendaylight | Stop ODL] **************************************
changed: [cent7_ansible]
NOTIFIED: [opendaylight | Cleanup Karaf] *********************************
changed: [cent7_ansible]
NOTIFIED: [opendaylight | Start ODL] *************************************
changed: [cent7_ansible]
Ansible
[~/vagrant-opendaylight]$ vagrant ssh cent7_ansible
Ansible
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Ansible
[vagrant@localhost ~]$ /vagrant/scripts/connect.sh
Ansible
opendaylight-user@root>config:list | grep odl-ovsdb-openstack
featuresBoot = config,<snip>,odl-ovsdb-openstack
Ansible
opendaylight-user@root>feature:list | grep odl-ovsdb-openstack
odl-ovsdb-openstack | 1.0.3-Helium-SR3 | x | ovsdb-1.0.3-Helium-SR3 <snip>
Ansible
Example: Remote host
Ansible
[~]$ sudo ansible-galaxy install dfarrell07.opendaylight
Ansible
[~/sandbox]$ cat /etc/ansible/hosts
odl_box ansible_ssh_host=10.3.12.87 ansible_ssh_user=centos
Ansible
[~/sandbox]$ cat install_odl.yml
---
- hosts: odl_box
sudo: yes
roles:
- opendaylight
Ansible
[~/sandbox]$ ansible-playbook install_odl.yml
ansible
At a high level...
Ansible
TASK: [opendaylight | Configure ODL Karaf features] **************************
changed: [odl_box]
Ansible
TASK: [opendaylight | Start ODL systemd service] *****************************
changed: [odl_box]
Ansible
[~/sandbox]$ ssh ansible0
Ansible
[centos@dfarrell-ansible0 ~]$ sudo systemctl is-active opendaylight
active
Ansible
[centos@dfarrell-ansible0 ~]$ /opt/opendaylight/bin/client
Ansible
Future: cluster support
Ansible
Future: Integrate ODL + OPNFV?
Ansible
Future: Wider OS support
Ansible
Future: Expanded used by Packer
Ansible
Future: Test in build system
Docker
Example: One-liner Karaf shell
Docker
[~/sandbox]$ docker run -ti dfarrell07/odl:0.2.3 ./bin/karaf
Docker
[~/sandbox]$ docker ps
CONTACONTAINER ID IMAGE COMMAND
b2869594fab3 dfarrell07/odl:0.2.3 "./bin/karaf"
Docker
Example: Build ODL's Docker image
Docker
[~/integration/packaging/docker]$ docker build -t dfarrell07/odl:0.2.3 .
Docker
At a high level...
Docker
(needs an update)
Step 0 : FROM debian:7
---> 479215127fa7
Docker
Install Java
Step 2 : RUN apt-get update && apt-get install -y openjdk-7-jre-headless wget
---> Using cache
---> 7f3f5c682c1c
Docker
Very basic tarball-based install
Step 5 : RUN wget...
Docker
Open ports
Step 6 : EXPOSE 162 179 1088 1790 1830 2400 2550 2551 2552 4189 4342 5005 5666 6633 6640 6653 7800 8000 8080 8101 8181 8383 12001
---> Running in 8625b7f32695
---> 0be36e6be661
Docker
Start ODL
(lacks systemd support)
Step 9 : CMD ./bin/karaf server
---> Running in 16cab37bf9c2
---> af863ac2de74
docker
OPNFV Fuel uses containerized ODL
Docker
Future: Examples that build on base image
Docker
Future: Docker Hub ODL org
Docker
Future: Host containers on ODL infra?
Docker
Future: Build snapshots
Docker
Future: Build containers via Packer instead?
Vagrant Base Box
Best user experience?
Vagrant Base Box
[~/sandbox]$ vagrant init -m dfarrell07/opendaylight
[~/sandbox]$ cat Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "dfarrell07/opendaylight"
end
Vagrant Base Box
[~/sandbox]$ vagrant up
Vagrant Base Box
default: URL: https://atlas.hashicorp.com/dfarrell07/opendaylight
==> default: Adding box 'dfarrell07/opendaylight' (v2.3.0)
Vagrant Base Box
[~/sandbox]$ vagrant status
Current machine states:
default running (virtualbox)
Vagrant Base Box
[~/sandbox]$ vagrant ssh
Vagrant Base Box
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Vagrant Base Box
#endexample
Vagrant Base Box
Future: Support libvirt provider
Vagrant Base Box
Future: Support other OSs
Vagrant Base Box
Future: Convert Vagrantfiles to use ODL base
Vagrant Base box
Future: Official ODL account
Vagrant Base Box
Future: Integrate with build system
(build snapshots)
Vagrant Base Box
Future: Host on ODL infra
Packer
Creates ODL's Vagrant base box
Packer
[~/integration/packaging/packer]$ packer build centos.json
Packer
At a high level...
Packer
Details...
(but quickly)
Packer
Install CentOS from ISO against VM
Packer
Basic OS config via Kickstart
Packer
Shell provisioners
"provisioners": [
{
"type": "shell",
"scripts":
[
"config_vagrant.sh",
"config_virtualbox.sh",
"config_ansible.sh"
]
},
Packer
Ansible role installs ODL
#..."provisioners": [
{
"type": "ansible-local",
"playbook_file": "install_odl.yml"
}
Packer
Package as a Vagrant box
"post-processors": [
{
"type": "vagrant",
"compression_level": "9",
"output": "opendaylight-{{ user `box_version` }}-centos-1503.box"
}
]
Packer
==> Builds finished. The artifacts of successful builds are:
--> virtualbox' provider box: opendaylight-2.3.0-centos-1503.box
Packer
[~/integration/packaging/packer]$ ls -rc | tail -n 1
opendaylight-2.3.0-centos-1503.box
Packer
[~/sandbox]$ vagrant box add --name "opendaylight" \
opendaylight-2.3.0-centos-1503.box
Packer
[~/sandbox]$ vagrant init -m opendaylight
Packer
[~/sandbox]$ cat Vagrantfile
Vagrant.configure(2) do |config|
config.vm.box = "opendaylight"
end
Packer
[~/sandbox]$ vagrant up
==> default: Importing base box 'opendaylight'...
Packer
[~/sandbox]$ vagrant ssh
Packer
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active
Packer
Everything' s in VCS
Packer
Configuration possible through Ansible
Packer
Future: Build containers
Packer
Future: Additional ODL versions
Packer
Future: Additional OS versions
Packer
Future: Integrate into build system
(build snapshots)