krates-plugin-vagrant 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.gitmodules +3 -0
  4. data/.rspec +2 -0
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile +8 -0
  7. data/LICENSE.txt +214 -0
  8. data/README.md +77 -0
  9. data/krates-plugin-vagrant.gemspec +26 -0
  10. data/lib/kontena/machine/vagrant.rb +12 -0
  11. data/lib/kontena/machine/vagrant/Vagrantfile.master.rb.erb +113 -0
  12. data/lib/kontena/machine/vagrant/Vagrantfile.node.rb.erb +38 -0
  13. data/lib/kontena/machine/vagrant/cloudinit.yml +92 -0
  14. data/lib/kontena/machine/vagrant/common.rb +21 -0
  15. data/lib/kontena/machine/vagrant/master_destroyer.rb +21 -0
  16. data/lib/kontena/machine/vagrant/master_provisioner.rb +96 -0
  17. data/lib/kontena/machine/vagrant/node_destroyer.rb +35 -0
  18. data/lib/kontena/machine/vagrant/node_provisioner.rb +82 -0
  19. data/lib/kontena/plugin/vagrant.rb +7 -0
  20. data/lib/kontena/plugin/vagrant/master/create_command.rb +44 -0
  21. data/lib/kontena/plugin/vagrant/master/restart_command.rb +17 -0
  22. data/lib/kontena/plugin/vagrant/master/ssh_command.rb +24 -0
  23. data/lib/kontena/plugin/vagrant/master/start_command.rb +16 -0
  24. data/lib/kontena/plugin/vagrant/master/stop_command.rb +16 -0
  25. data/lib/kontena/plugin/vagrant/master/terminate_command.rb +13 -0
  26. data/lib/kontena/plugin/vagrant/master_command.rb +19 -0
  27. data/lib/kontena/plugin/vagrant/node_command.rb +19 -0
  28. data/lib/kontena/plugin/vagrant/nodes/create_command.rb +81 -0
  29. data/lib/kontena/plugin/vagrant/nodes/restart_command.rb +22 -0
  30. data/lib/kontena/plugin/vagrant/nodes/ssh_command.rb +28 -0
  31. data/lib/kontena/plugin/vagrant/nodes/start_command.rb +22 -0
  32. data/lib/kontena/plugin/vagrant/nodes/stop_command.rb +22 -0
  33. data/lib/kontena/plugin/vagrant/nodes/terminate_command.rb +26 -0
  34. data/lib/kontena/plugin/vagrant_command.rb +11 -0
  35. data/lib/kontena_cli_plugin.rb +5 -0
  36. 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,7 @@
1
+ module Kontena
2
+ module Plugin
3
+ module Vagrant
4
+ VERSION = "0.3.1"
5
+ end
6
+ end
7
+ 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