krates-plugin-vagrant 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.gitmodules +3 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +22 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +214 -0
- data/README.md +77 -0
- data/krates-plugin-vagrant.gemspec +26 -0
- data/lib/kontena/machine/vagrant.rb +12 -0
- data/lib/kontena/machine/vagrant/Vagrantfile.master.rb.erb +113 -0
- data/lib/kontena/machine/vagrant/Vagrantfile.node.rb.erb +38 -0
- data/lib/kontena/machine/vagrant/cloudinit.yml +92 -0
- data/lib/kontena/machine/vagrant/common.rb +21 -0
- data/lib/kontena/machine/vagrant/master_destroyer.rb +21 -0
- data/lib/kontena/machine/vagrant/master_provisioner.rb +96 -0
- data/lib/kontena/machine/vagrant/node_destroyer.rb +35 -0
- data/lib/kontena/machine/vagrant/node_provisioner.rb +82 -0
- data/lib/kontena/plugin/vagrant.rb +7 -0
- data/lib/kontena/plugin/vagrant/master/create_command.rb +44 -0
- data/lib/kontena/plugin/vagrant/master/restart_command.rb +17 -0
- data/lib/kontena/plugin/vagrant/master/ssh_command.rb +24 -0
- data/lib/kontena/plugin/vagrant/master/start_command.rb +16 -0
- data/lib/kontena/plugin/vagrant/master/stop_command.rb +16 -0
- data/lib/kontena/plugin/vagrant/master/terminate_command.rb +13 -0
- data/lib/kontena/plugin/vagrant/master_command.rb +19 -0
- data/lib/kontena/plugin/vagrant/node_command.rb +19 -0
- data/lib/kontena/plugin/vagrant/nodes/create_command.rb +81 -0
- data/lib/kontena/plugin/vagrant/nodes/restart_command.rb +22 -0
- data/lib/kontena/plugin/vagrant/nodes/ssh_command.rb +28 -0
- data/lib/kontena/plugin/vagrant/nodes/start_command.rb +22 -0
- data/lib/kontena/plugin/vagrant/nodes/stop_command.rb +22 -0
- data/lib/kontena/plugin/vagrant/nodes/terminate_command.rb +26 -0
- data/lib/kontena/plugin/vagrant_command.rb +11 -0
- data/lib/kontena_cli_plugin.rb +5 -0
- metadata +119 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
5
|
+
VAGRANTFILE_API_VERSION = "2"
|
6
|
+
|
7
|
+
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
8
|
+
config.vm.provider :virtualbox do |v|
|
9
|
+
v.check_guest_additions = false
|
10
|
+
v.functional_vboxsf = false
|
11
|
+
end
|
12
|
+
|
13
|
+
if Vagrant.has_plugin?("vagrant-vbguest") then
|
14
|
+
config.vbguest.auto_update = false
|
15
|
+
end
|
16
|
+
|
17
|
+
config.vm.define "<%= name %>" do |docker|
|
18
|
+
docker.vm.box = "coreos-<%= coreos_channel %>"
|
19
|
+
docker.vm.box_url = "http://stable.release.core-os.net/amd64-usr/current/coreos_production_vagrant.json"
|
20
|
+
<% if network_address == "dhcp" %>
|
21
|
+
docker.vm.network "private_network", type: "dhcp"
|
22
|
+
<% else %>
|
23
|
+
docker.vm.network "private_network", ip: "<%= network_address %>"
|
24
|
+
<% end %>
|
25
|
+
docker.vm.hostname = "<%= name %>"
|
26
|
+
docker.vm.provider "virtualbox" do |vb|
|
27
|
+
vb.name = "<%= name %>"
|
28
|
+
vb.gui = false
|
29
|
+
vb.cpus = <%= cpus %>
|
30
|
+
vb.memory = <%= memory %>
|
31
|
+
vb.auto_nat_dns_proxy = false
|
32
|
+
vb.customize ["modifyvm", :id, "--natdnsproxy1", "off" ]
|
33
|
+
vb.customize ["modifyvm", :id, "--natdnshostresolver1", "off" ]
|
34
|
+
end
|
35
|
+
docker.vm.provision :file, :source => "<%= cloudinit %>", :destination => "/tmp/vagrantfile-user-data"
|
36
|
+
docker.vm.provision :shell, :inline => "mv /tmp/vagrantfile-user-data /var/lib/coreos-vagrant/", :privileged => true
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#cloud-config
|
2
|
+
write_files:
|
3
|
+
- path: /etc/kontena-agent.env
|
4
|
+
permissions: 0600
|
5
|
+
owner: root
|
6
|
+
content: |
|
7
|
+
KONTENA_URI=<%= master_uri %>
|
8
|
+
KONTENA_TOKEN=<%= grid_token %>
|
9
|
+
KONTENA_PEER_INTERFACE=eth1
|
10
|
+
KONTENA_VERSION=<%= version %>
|
11
|
+
- path: /etc/systemd/system/docker.service.d/50-kontena.conf
|
12
|
+
content: |
|
13
|
+
[Service]
|
14
|
+
Environment='DOCKER_OPTS=--insecure-registry="10.81.0.0/16" --bip="172.17.43.1/16" -s overlay2'
|
15
|
+
Environment='DOCKER_CGROUPS=--exec-opt native.cgroupdriver=cgroupfs'
|
16
|
+
- path: /etc/sysctl.d/99-inotify.conf
|
17
|
+
owner: root
|
18
|
+
permissions: 0644
|
19
|
+
content: |
|
20
|
+
fs.inotify.max_user_instances = 8192
|
21
|
+
coreos:
|
22
|
+
update:
|
23
|
+
reboot-strategy: off
|
24
|
+
units:
|
25
|
+
- name: 00-eth.network
|
26
|
+
runtime: true
|
27
|
+
content: |
|
28
|
+
[Match]
|
29
|
+
Name=eth*
|
30
|
+
[Network]
|
31
|
+
DHCP=yes
|
32
|
+
DNS=172.17.43.1
|
33
|
+
DNS=172.28.128.1
|
34
|
+
DNS=8.8.8.8
|
35
|
+
DOMAINS=kontena.local
|
36
|
+
[DHCP]
|
37
|
+
UseDNS=false
|
38
|
+
- name: etcd2.service
|
39
|
+
command: start
|
40
|
+
enable: true
|
41
|
+
content: |
|
42
|
+
Description=etcd 2.0
|
43
|
+
After=docker.service
|
44
|
+
[Service]
|
45
|
+
Restart=always
|
46
|
+
RestartSec=5
|
47
|
+
ExecStart=/usr/bin/docker logs --tail=10 -f kontena-etcd
|
48
|
+
- name: 50-docker.network
|
49
|
+
mask: true
|
50
|
+
- name: 50-docker-veth.network
|
51
|
+
mask: true
|
52
|
+
- name: zz-default.network
|
53
|
+
runtime: false
|
54
|
+
content: |
|
55
|
+
# default should only match real network interfaces
|
56
|
+
[Match]
|
57
|
+
Name=eth*
|
58
|
+
|
59
|
+
[Network]
|
60
|
+
DHCP=yes
|
61
|
+
|
62
|
+
[DHCP]
|
63
|
+
UseMTU=true
|
64
|
+
UseDomains=true
|
65
|
+
- name: kontena-agent.service
|
66
|
+
command: start
|
67
|
+
enable: true
|
68
|
+
content: |
|
69
|
+
[Unit]
|
70
|
+
Description=kontena-agent
|
71
|
+
After=network-online.target
|
72
|
+
After=docker.service
|
73
|
+
Description=Kontena Agent
|
74
|
+
Documentation=http://www.kontena.io/
|
75
|
+
Requires=network-online.target
|
76
|
+
Requires=docker.service
|
77
|
+
|
78
|
+
[Service]
|
79
|
+
Restart=always
|
80
|
+
RestartSec=5
|
81
|
+
TimeoutStartSec=0
|
82
|
+
EnvironmentFile=/etc/kontena-agent.env
|
83
|
+
ExecStartPre=-/usr/bin/docker stop kontena-agent
|
84
|
+
ExecStartPre=-/usr/bin/docker rm kontena-agent
|
85
|
+
ExecStartPre=/usr/bin/docker pull kontena/agent:${KONTENA_VERSION}
|
86
|
+
ExecStart=/usr/bin/docker run --name kontena-agent \
|
87
|
+
--env-file /etc/kontena-agent.env \
|
88
|
+
-v=/var/run/docker.sock:/var/run/docker.sock \
|
89
|
+
-v=/etc/kontena-agent.env:/etc/kontena.env \
|
90
|
+
--net=host \
|
91
|
+
kontena/agent:${KONTENA_VERSION}
|
92
|
+
ExecStop=/usr/bin/docker stop kontena-agent
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
require 'open3'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
module Kontena
|
7
|
+
module Machine
|
8
|
+
module Vagrant
|
9
|
+
module Common
|
10
|
+
|
11
|
+
def erb(template, vars)
|
12
|
+
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_command(cmd)
|
16
|
+
exit $?.exitstatus unless system(cmd)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Kontena
|
4
|
+
module Machine
|
5
|
+
module Vagrant
|
6
|
+
class MasterDestroyer
|
7
|
+
include Kontena::Machine::Vagrant::Common
|
8
|
+
include Kontena::Cli::ShellSpinner
|
9
|
+
|
10
|
+
def run!
|
11
|
+
vagrant_path = "#{Dir.home}/.kontena/vagrant_master"
|
12
|
+
Dir.chdir(vagrant_path) do
|
13
|
+
spinner "Triggering termination of Kontena Master from Vagrant"
|
14
|
+
run_command('vagrant destroy -f')
|
15
|
+
FileUtils.remove_entry_secure(vagrant_path)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Kontena
|
4
|
+
module Machine
|
5
|
+
module Vagrant
|
6
|
+
class MasterProvisioner
|
7
|
+
include RandomName
|
8
|
+
include Kontena::Machine::Common
|
9
|
+
include Kontena::Machine::Vagrant::Common
|
10
|
+
include Kontena::Cli::Common
|
11
|
+
include Kontena::Cli::ShellSpinner
|
12
|
+
|
13
|
+
API_URL = 'http://192.168.66.100:8080'
|
14
|
+
attr_reader :client
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@client = Excon.new(API_URL)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run!(opts)
|
21
|
+
name = opts[:name] || generate_name
|
22
|
+
version = opts[:version]
|
23
|
+
memory = opts[:memory] || 1024
|
24
|
+
vault_secret = opts[:vault_secret]
|
25
|
+
vault_iv = opts[:vault_iv]
|
26
|
+
initial_admin_code = opts[:initial_admin_code]
|
27
|
+
coreos_channel = opts[:coreos_channel]
|
28
|
+
vagrant_path = "#{Dir.home}/.kontena/vagrant_master/"
|
29
|
+
if Dir.exist?(vagrant_path)
|
30
|
+
puts "Oops... cannot create Kontena Master because installation path already exists."
|
31
|
+
puts "If you are sure that no Kontena Masters exist on this machine, remove folder: #{vagrant_path}"
|
32
|
+
abort
|
33
|
+
end
|
34
|
+
FileUtils.mkdir_p(vagrant_path)
|
35
|
+
|
36
|
+
template = File.join(__dir__ , '/Vagrantfile.master.rb.erb')
|
37
|
+
cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
|
38
|
+
vars = {
|
39
|
+
name: name,
|
40
|
+
server_name: name.sub('kontena-master-', ''),
|
41
|
+
version: version,
|
42
|
+
memory: memory,
|
43
|
+
vault_secret: vault_secret,
|
44
|
+
initial_admin_code: initial_admin_code,
|
45
|
+
vault_iv: vault_iv,
|
46
|
+
coreos_channel: coreos_channel,
|
47
|
+
cloudinit: "#{vagrant_path}/cloudinit.yml"
|
48
|
+
}
|
49
|
+
spinner "Creating Vagrant config " do
|
50
|
+
vagrant_data = erb(File.read(template), vars)
|
51
|
+
cloudinit = erb(File.read(cloudinit_template), vars)
|
52
|
+
File.write("#{vagrant_path}/Vagrantfile", vagrant_data)
|
53
|
+
File.write("#{vagrant_path}/cloudinit.yml", cloudinit)
|
54
|
+
end
|
55
|
+
|
56
|
+
Dir.chdir(vagrant_path) do
|
57
|
+
spinner "Triggering CoreOS Container Linux box update"
|
58
|
+
system('vagrant box update')
|
59
|
+
spinner "Executing 'vagrant up'"
|
60
|
+
run_command('vagrant up')
|
61
|
+
spinner "'vagrant up' executed successfully"
|
62
|
+
end
|
63
|
+
|
64
|
+
spinner "Waiting for #{name.colorize(:cyan)} to start " do
|
65
|
+
sleep 1 until master_running?
|
66
|
+
end
|
67
|
+
|
68
|
+
master_version = nil
|
69
|
+
spinner "Retrieving #{name.colorize(:cyan)} version" do
|
70
|
+
master_version = JSON.parse(client.get(path: '/'))["version"] rescue nil
|
71
|
+
end
|
72
|
+
|
73
|
+
spinner "Kontena Master #{master_version} is now running at #{API_URL}"
|
74
|
+
|
75
|
+
{
|
76
|
+
name: name.sub('kontena-master-', ''),
|
77
|
+
public_ip: API_URL.split('//').last,
|
78
|
+
provider: 'vagrant',
|
79
|
+
version: master_version,
|
80
|
+
code: opts[:initial_admin_code]
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
def master_running?
|
85
|
+
client.get(path: '/').status == 200
|
86
|
+
rescue
|
87
|
+
false
|
88
|
+
end
|
89
|
+
|
90
|
+
def generate_name
|
91
|
+
"kontena-master-#{super}-#{rand(1..99)}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
|
3
|
+
module Kontena
|
4
|
+
module Machine
|
5
|
+
module Vagrant
|
6
|
+
class NodeDestroyer
|
7
|
+
include RandomName
|
8
|
+
include Kontena::Machine::Vagrant::Common
|
9
|
+
include Kontena::Cli::ShellSpinner
|
10
|
+
|
11
|
+
attr_reader :client, :api_client
|
12
|
+
|
13
|
+
# @param [Kontena::Client] api_client Kontena api client
|
14
|
+
def initialize(api_client)
|
15
|
+
@api_client = api_client
|
16
|
+
end
|
17
|
+
|
18
|
+
def run!(grid, name)
|
19
|
+
vagrant_path = "#{Dir.home}/.kontena/#{grid}/#{name}"
|
20
|
+
Dir.chdir(vagrant_path) do
|
21
|
+
spinner "Triggering termination of Vagrant machine #{name.colorize(:cyan)}"
|
22
|
+
run_command('vagrant destroy -f')
|
23
|
+
FileUtils.remove_entry_secure(vagrant_path)
|
24
|
+
end
|
25
|
+
node = api_client.get("grids/#{grid}/nodes")['nodes'].find{|n| n['name'] == name}
|
26
|
+
if node
|
27
|
+
spinner "Removing node #{name.colorize(:cyan)} from grid #{grid.colorize(:cyan)} " do
|
28
|
+
api_client.delete("nodes/#{grid}/#{name}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative 'common'
|
2
|
+
module Kontena
|
3
|
+
module Machine
|
4
|
+
module Vagrant
|
5
|
+
class NodeProvisioner
|
6
|
+
include RandomName
|
7
|
+
include Kontena::Machine::Vagrant::Common
|
8
|
+
include Kontena::Cli::ShellSpinner
|
9
|
+
|
10
|
+
attr_reader :client, :api_client
|
11
|
+
|
12
|
+
# @param [Kontena::Client] api_client Kontena api client
|
13
|
+
def initialize(api_client)
|
14
|
+
@api_client = api_client
|
15
|
+
end
|
16
|
+
|
17
|
+
def run!(opts)
|
18
|
+
grid = opts[:grid]
|
19
|
+
if opts[:name]
|
20
|
+
name = "#{opts[:name]}-#{opts[:instance_number]}"
|
21
|
+
else
|
22
|
+
name = generate_name
|
23
|
+
end
|
24
|
+
version = opts[:version]
|
25
|
+
vagrant_path = "#{Dir.home}/.kontena/#{grid}/#{name}"
|
26
|
+
FileUtils.mkdir_p(vagrant_path)
|
27
|
+
|
28
|
+
template = File.join(__dir__ , '/Vagrantfile.node.rb.erb')
|
29
|
+
cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
|
30
|
+
vars = {
|
31
|
+
name: name,
|
32
|
+
version: version,
|
33
|
+
cpus: opts[:cpus] || 1,
|
34
|
+
memory: opts[:memory] || 1024,
|
35
|
+
network_address: opts[:network_address],
|
36
|
+
master_uri: opts[:master_uri],
|
37
|
+
grid_token: opts[:grid_token],
|
38
|
+
coreos_channel: opts[:coreos_channel],
|
39
|
+
cloudinit: "#{vagrant_path}/cloudinit.yml"
|
40
|
+
}
|
41
|
+
spinner "Generating Vagrant config" do
|
42
|
+
vagrant_data = erb(File.read(template), vars)
|
43
|
+
cloudinit = erb(File.read(cloudinit_template), vars)
|
44
|
+
File.write("#{vagrant_path}/Vagrantfile", vagrant_data)
|
45
|
+
File.write("#{vagrant_path}/cloudinit.yml", cloudinit)
|
46
|
+
end
|
47
|
+
|
48
|
+
node = nil
|
49
|
+
Dir.chdir(vagrant_path) do
|
50
|
+
spinner "Triggering CoreOS Container Linux box update"
|
51
|
+
system('vagrant box update')
|
52
|
+
spinner "Executing 'vagrant up'"
|
53
|
+
run_command('vagrant up')
|
54
|
+
spinner "'vagrant up' executed successfully"
|
55
|
+
spinner "Waiting for node #{name.colorize(:cyan)} to join grid #{grid.colorize(:cyan)} " do
|
56
|
+
sleep 1 until node = node_exists_in_grid?(grid, name)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
set_labels(
|
60
|
+
node,
|
61
|
+
[
|
62
|
+
"provider=vagrant"
|
63
|
+
]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_name
|
68
|
+
"#{super}-#{rand(1..99)}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def node_exists_in_grid?(grid, name)
|
72
|
+
api_client.get("grids/#{grid}/nodes")['nodes'].find{|n| n['name'] == name}
|
73
|
+
end
|
74
|
+
|
75
|
+
def set_labels(node, labels)
|
76
|
+
data = {labels: labels}
|
77
|
+
api_client.put("nodes/#{node['id']}", data, {}, {'Kontena-Grid-Token' => node['grid']['token']})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Kontena::Plugin::Vagrant::Master
|
4
|
+
class CreateCommand < Kontena::Command
|
5
|
+
include Kontena::Cli::Common
|
6
|
+
|
7
|
+
option "--name", "NAME", "Set master name"
|
8
|
+
option "--memory", "MEMORY", "How much memory node has"
|
9
|
+
option "--version", "VERSION", "Define installed Kontena version", default: 'latest'
|
10
|
+
option "--vault-secret", "VAULT_SECRET", "Secret key for Vault"
|
11
|
+
option "--vault-iv", "VAULT_IV", "Initialization vector for Vault"
|
12
|
+
option "--coreos-channel", "CHANNEL", "CoreOS release channel", default: 'stable'
|
13
|
+
|
14
|
+
def execute
|
15
|
+
require_relative '../../../machine/vagrant'
|
16
|
+
mem = ask_instance_memory
|
17
|
+
provisioner.run!(
|
18
|
+
name: name,
|
19
|
+
memory: mem,
|
20
|
+
version: version,
|
21
|
+
vault_secret: vault_secret || SecureRandom.hex(24),
|
22
|
+
vault_iv: vault_iv || SecureRandom.hex(24),
|
23
|
+
initial_admin_code: SecureRandom.hex(16),
|
24
|
+
coreos_channel: coreos_channel
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def ask_instance_memory
|
29
|
+
if self.memory.nil?
|
30
|
+
prompt.select("Choose a size") do |menu|
|
31
|
+
%w(512 1024 2048).each do |mem|
|
32
|
+
menu.choice "#{mem}MB", mem
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
self.memory
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def provisioner
|
41
|
+
Kontena::Machine::Vagrant::MasterProvisioner.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|