Commit a3fd95f9 authored by David Seaward's avatar David Seaward
Browse files

Merge branch 'master' into 'master'


See merge request liberty/ldh_developer!1
parents 0259f393 ee75ea30
# The shipyard
The `shipyard` is a small wrapper around vagrant/libvirt that allows you to spin new vagrant vms easily, you only need to provide a name and the shipyard builds that vm for you.
## Usage
First you need to setup you machine. Use the `shipyard_setup` script [here first](../start-here).
Clone this repo `cd` into it, and launch the command:
./shipyard --name hello-world
Vagrant will start shortly and you can see the output from vagrant.
import sys
import os
import argparse
import tempfile
import subprocess
import json
import shutil
from pathlib import Path
import ipaddress
vagrant_template = """
Vagrant.configure("2") do |config|
config.vm.hostname = "{hostname}"
config.vm.define :{hostname} do |{hostname}|
{hostname} = "debian/stretch64"
{hostname}.vm.hostname = "{hostname}"
{hostname}.vm.provider :libvirt do |libvirt|
libvirt.driver = "kvm"
libvirt.memory = "{ram}"
libvirt.username = "root"
libvirt.graphics_type = "spice"
libvirt.cpus = {cpus}
XDG_CONFIG_HOME = Path(os.environ['HOME'],'.config','ldh_developer','shipyard')
def only_if_box_exist(func):
def wrapper(*args, **kwargs):
hostname = args[0]
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)
if vagrant_wd.exists():
func(*args, **kwargs)
print("Shipyard error: no vm managed by me has the hostname '{}'".format(hostname))
return wrapper
def is_ipaddress(ip_addr):
except ValueError:
return False
return True
def print_status():
Prints the status of all the virtual machines managed by shipyard
shpyrd_paths = [str(d) for d in XDG_CONFIG_HOME.iterdir() if d.is_dir()]
vgt_db = Path(
os.environ.get('VAGRANT_HOME', str(Path.home().joinpath('.vagrant.d'))),
'data', 'machine-index', 'index'
count = 0
if vgt_db.exists():
print('hostname \t State\t IP Address')
db = json.loads(
for k, v in db['machines'].items():
vagrant_wd = v['vagrantfile_path']
if vagrant_wd in shpyrd_paths:
# get the ip address
cp =
['vagrant','ssh-config'], cwd=vagrant_wd,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
if cp.returncode != 0:
ip_addr = "<N/A>"
for fld in cp.stdout.split():
if is_ipaddress(str(fld)):
ip_addr = str(fld)
print(f"{v['name']} \t {v['state']}\t {ip_addr}")
print('Total {} machine(s)'.format(count))
def create_box(hostname, ram, cpus):
This creates a box using the template
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)
if vagrant_wd.exists():
print("Shipyard error: There's already a vm with that hostname")
# Generate Vagrantfile
with vagrant_wd.joinpath('Vagrantfile').open(mode='w') as vfile:
# Execute vagrant with the generated vagrantfile['vagrant','up'], cwd=vagrant_wd)['vagrant','provision'], cwd=vagrant_wd)
def destroy_box(hostname):
Destroy a box, or all
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['vagrant','destroy'], cwd=vagrant_wd)
def run_playbook(hostname, playbook):
run a playbook against one of the boxes
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['vagrant','destroy'], cwd=vagrant_wd)
def start_vm(hostname):
Starts the vm with the provided hostname
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['vagrant','up'], cwd=vagrant_wd)
def halt(hostname):
Stops the vm with the provided hostname
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['vagrant','halt'], cwd=vagrant_wd)
def invoke_shell(hostname):
Open a SSH session to the hostname
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['vagrant','ssh'], cwd=vagrant_wd)
def which(hostname):
Print the directory of a vm by it's hostname
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)
def gio_open_vm(hostname):
Open the vm directory in nautilis or any other file manager
vagrant_wd = XDG_CONFIG_HOME.joinpath(hostname)['gio','open', vagrant_wd])
'status': "Prints the status of all the VM's managed by shipyard",
'create': 'Creates a new VM using vagrant and libvirt (KVM)',
'up': 'Start VM',
'destroy': 'Destroy the VM and do cleanup',
'ssh': 'Connect to the vm using SSH',
'playbook': 'Run a playbook against a machine',
'which': 'Print the path to the Vagrantfile',
'open': 'Show the working directory of the VM using the file manager.'
if __name__ == '__main__':
cmd_parser = argparse.ArgumentParser(
description='This utility helps you mange virtual machines with Vagrant without dealing with configuration details',
cmd_parser.add_argument('command', choices=COMMANDS,)
cmd_args = cmd_parser.parse_args(sys.argv[1:2])
# Ensure XDG_CONFIG_HOME exists
XDG_CONFIG_HOME.mkdir(parents=True, exist_ok=True)
if cmd_args.command == 'status':
sub_parser = argparse.ArgumentParser(prog='shipyard',)
if cmd_args.command == 'create':
sub_parser.usage = 'shipyard create <hostname> [--ram RAM] [--cpus CPUS]'
sub_parser.add_argument('hostname', help='This is the hostname for the new the box')
sub_parser.add_argument('--ram', help='Hoy much RAM for this box (default is 512)', default=512)
sub_parser.add_argument('--cpus', help='Hoy many CPUs for this box (default is 1)', default=1)
sub_args = sub_parser.parse_args(sys.argv[2:])
create_box(sub_args.hostname, sub_args.ram, sub_args.cpus)
sub_parser.add_argument('hostname', help='This is the hostname of the box')
if cmd_args.command == 'playbook':
sub_parser.add_argument('--playbook', help='Path to the yml file', required=True)
sub_args = sub_parser.parse_args(sys.argv[2:])
run_playbook(sub_args.hostname, sub_args.playbook)
sub_args = sub_parser.parse_args(sys.argv[2:])
if cmd_args.command == 'up':
elif cmd_args.command == 'destroy':
elif cmd_args.command == 'ssh':
elif cmd_args.command == 'which':
elif cmd_args.command == 'open':
# LDH Toolkit setup guide
## The shipyard
The first thing you need to run is the `shipyard_setup script`. From your terminal type:
wget -qnc && sudo bash shipyard_setup
It will install libraries and other system tools. It might take a few minutes until finished.
## Git configuration
You need git to download the LDH toolkit. Skip this step if you already configured git.
### Username and email
First configure your username and email (as non-root user)
git config --global "Noe Nieto"
git config --global
### Generate RSA keypair
Next we need to create a RSA keypair so we can upload the public key to gitlab. Copy the following and paste it to the terminal.
mkdir -p ~.ssh/
cd ~.ssh/
ssh-keygen -o -t rsa -b 4096 -C "My liberty developer SSH key" -f purism_gitlab
### Configure SSH
The keypair has been generated. Now configure ssh so it will use the private key we created whwn connecting to Gitlab.
mkdir -p ~.ssh/
cat << EOF > ~/.ssh/config
IdentityFile ~/.ssh/purism_gitlab
### Upload the key to Gitlab
First copy the public key:
xclip -sel clip < ~/.ssh/
Go to, paste the public key to the Key textbox and pick a name/title for the key.
Press save.
### Test access to Gitlab
Run this:
ssh -oBatchMode=yes -T
You should get a message like this
Welcome to GitLab, @noe.nieto!
If you don't see the welcome message please double check the ssh configuration.
### Get your copy of the LDH developer toolkit
Just clone the repo:
git clone
Now go to the main [](../ to see a listing of the different tools available.
# Script to setup the tools needed for LDH developers
function ldh_info()
printf "$(tput setaf 7)[info] $(tput sgr0)$@\n"
function ldh_error()
echo "$(tput setaf 1)[Error] $(tput setaf 7)$@$(tput sgr0)"
# Checking permissions
if [[ $EUID -ne 0 ]]; then
ldh_error "Root privilege required..."
ldh_info "Usage: wget -qnc && sudo bash shipyard_setup"
exit 100
ldh_info "Updating package list ..."
apt update &>> /dev/null
ldh_info "Now installing dependencies ..."
apt install -y ansible virt-manager libvirt-clients vagrant vagrant-libvirt git xclip
ldh_info "Generating Locales ..."
locale-gen en &>> /dev/null
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment