kontena-cli 0.8.4 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/bin/kontena +4 -0
- data/lib/kontena/cli/app_command.rb +2 -0
- data/lib/kontena/cli/apps/build_command.rb +26 -0
- data/lib/kontena/cli/apps/common.rb +41 -12
- data/lib/kontena/cli/apps/deploy_command.rb +31 -13
- data/lib/kontena/cli/apps/docker_helper.rb +34 -0
- data/lib/kontena/cli/apps/init_command.rb +130 -10
- data/lib/kontena/cli/apps/list_command.rb +4 -2
- data/lib/kontena/cli/apps/logs_command.rb +4 -2
- data/lib/kontena/cli/apps/remove_command.rb +4 -2
- data/lib/kontena/cli/apps/start_command.rb +4 -2
- data/lib/kontena/cli/apps/stop_command.rb +4 -2
- data/lib/kontena/cli/common.rb +3 -3
- data/lib/kontena/cli/container_command.rb +3 -0
- data/lib/kontena/cli/containers/inspect_command.rb +16 -0
- data/lib/kontena/cli/deploy_command.rb +3 -0
- data/lib/kontena/cli/etcd/get_command.rb +21 -0
- data/lib/kontena/cli/etcd/list_command.rb +26 -0
- data/lib/kontena/cli/etcd/mkdir_command.rb +17 -0
- data/lib/kontena/cli/etcd/remove_command.rb +21 -0
- data/lib/kontena/cli/etcd/set_command.rb +18 -0
- data/lib/kontena/cli/etcd_command.rb +17 -0
- data/lib/kontena/cli/grid_command.rb +2 -0
- data/lib/kontena/cli/grids/logs_command.rb +71 -0
- data/lib/kontena/cli/master/aws/create_command.rb +33 -0
- data/lib/kontena/cli/master/aws_command.rb +8 -0
- data/lib/kontena/cli/master/azure/create_command.rb +33 -0
- data/lib/kontena/cli/master/azure_command.rb +13 -0
- data/lib/kontena/cli/master/digital_ocean/create_command.rb +30 -0
- data/lib/kontena/cli/master/digital_ocean_command.rb +13 -0
- data/lib/kontena/cli/master/vagrant/create_command.rb +19 -0
- data/lib/kontena/cli/master/vagrant/restart_command.rb +20 -0
- data/lib/kontena/cli/master/vagrant/ssh_command.rb +15 -0
- data/lib/kontena/cli/master/vagrant/start_command.rb +20 -0
- data/lib/kontena/cli/master/vagrant/stop_command.rb +20 -0
- data/lib/kontena/cli/master/vagrant/terminate_command.rb +13 -0
- data/lib/kontena/cli/master/vagrant_command.rb +23 -0
- data/lib/kontena/cli/master_command.rb +15 -0
- data/lib/kontena/cli/node_command.rb +4 -0
- data/lib/kontena/cli/nodes/aws/create_command.rb +39 -0
- data/lib/kontena/cli/nodes/aws/restart_command.rb +28 -0
- data/lib/kontena/cli/nodes/aws/terminate_command.rb +20 -0
- data/lib/kontena/cli/nodes/aws_command.rb +15 -0
- data/lib/kontena/cli/nodes/azure/create_command.rb +39 -0
- data/lib/kontena/cli/nodes/azure/restart_command.rb +31 -0
- data/lib/kontena/cli/nodes/azure/terminate_command.rb +20 -0
- data/lib/kontena/cli/nodes/azure_command.rb +15 -0
- data/lib/kontena/cli/nodes/digital_ocean/create_command.rb +1 -1
- data/lib/kontena/cli/nodes/vagrant/create_command.rb +1 -1
- data/lib/kontena/cli/service_command.rb +4 -0
- data/lib/kontena/cli/services/add_env_command.rb +18 -0
- data/lib/kontena/cli/services/create_command.rb +8 -0
- data/lib/kontena/cli/services/remove_env_command.rb +17 -0
- data/lib/kontena/cli/services/services_helper.rb +20 -1
- data/lib/kontena/cli/services/update_command.rb +10 -0
- data/lib/kontena/client.rb +22 -1
- data/lib/kontena/machine/aws.rb +13 -0
- data/lib/kontena/machine/aws/cloudinit.yml +66 -0
- data/lib/kontena/machine/aws/cloudinit_master.yml +105 -0
- data/lib/kontena/machine/aws/master_provisioner.rb +161 -0
- data/lib/kontena/machine/aws/node_destroyer.rb +39 -0
- data/lib/kontena/machine/aws/node_provisioner.rb +168 -0
- data/lib/kontena/machine/azure.rb +13 -0
- data/lib/kontena/machine/azure/cloudinit.yml +59 -0
- data/lib/kontena/machine/azure/cloudinit_master.yml +105 -0
- data/lib/kontena/machine/azure/logger.rb +27 -0
- data/lib/kontena/machine/azure/master_provisioner.rb +126 -0
- data/lib/kontena/machine/azure/node_destroyer.rb +53 -0
- data/lib/kontena/machine/azure/node_provisioner.rb +128 -0
- data/lib/kontena/machine/digital_ocean.rb +1 -0
- data/lib/kontena/machine/digital_ocean/cloudinit.yml +1 -0
- data/lib/kontena/machine/digital_ocean/cloudinit_master.yml +105 -0
- data/lib/kontena/machine/digital_ocean/master_provisioner.rb +94 -0
- data/lib/kontena/machine/digital_ocean/node_provisioner.rb +8 -1
- data/lib/kontena/machine/vagrant.rb +2 -0
- data/lib/kontena/machine/vagrant/Vagrantfile.master.rb.erb +101 -0
- data/lib/kontena/machine/vagrant/{Vagrantfile.coreos.rb.erb → Vagrantfile.node.rb.erb} +0 -0
- data/lib/kontena/machine/vagrant/cloudinit.yml +2 -1
- data/lib/kontena/machine/vagrant/master_destroyer.rb +37 -0
- data/lib/kontena/machine/vagrant/master_provisioner.rb +75 -0
- data/lib/kontena/machine/vagrant/node_destroyer.rb +4 -0
- data/lib/kontena/machine/vagrant/node_provisioner.rb +1 -1
- data/lib/kontena/scripts/completer +29 -3
- data/spec/kontena/cli/app/common_spec.rb +61 -0
- data/spec/kontena/cli/app/deploy_command_spec.rb +25 -6
- data/spec/kontena/cli/app/docker_helper_spec.rb +32 -0
- data/spec/kontena/cli/common_spec.rb +53 -0
- metadata +61 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'shell-spinner'
|
|
2
|
+
|
|
3
|
+
module Kontena
|
|
4
|
+
module Machine
|
|
5
|
+
module Aws
|
|
6
|
+
class NodeDestroyer
|
|
7
|
+
|
|
8
|
+
attr_reader :client, :api_client
|
|
9
|
+
|
|
10
|
+
# @param [Kontena::Client] api_client Kontena api client
|
|
11
|
+
# @param [String] access_key_id aws_access_key_id
|
|
12
|
+
# @param [String] secret_key aws_secret_access_key
|
|
13
|
+
# @param [String] region
|
|
14
|
+
def initialize(api_client, access_key_id, secret_key, region = 'eu-west-1')
|
|
15
|
+
@api_client = api_client
|
|
16
|
+
@client = Fog::Compute.new(:provider => 'AWS', :aws_access_key_id => access_key_id, :aws_secret_access_key => secret_key, :region => region)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run!(grid, name)
|
|
20
|
+
instance = client.servers.all({'tag:kontena_name' => name}).first
|
|
21
|
+
if instance
|
|
22
|
+
ShellSpinner "Terminating AWS instance #{name.colorize(:cyan)} " do
|
|
23
|
+
instance.destroy
|
|
24
|
+
sleep 2 until client.servers.get(instance.id).state == 'terminated'
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
abort "Cannot find instance #{name.colorize(:cyan)} in AWS"
|
|
28
|
+
end
|
|
29
|
+
node = api_client.get("grids/#{grid['id']}/nodes")['nodes'].find{|n| n['name'] == name}
|
|
30
|
+
if node
|
|
31
|
+
ShellSpinner "Removing node #{name.colorize(:cyan)} from grid #{grid['name'].colorize(:cyan)} " do
|
|
32
|
+
api_client.delete("grids/#{grid['id']}/nodes/#{name}")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'erb'
|
|
3
|
+
require 'open3'
|
|
4
|
+
require 'shell-spinner'
|
|
5
|
+
|
|
6
|
+
module Kontena
|
|
7
|
+
module Machine
|
|
8
|
+
module Aws
|
|
9
|
+
class NodeProvisioner
|
|
10
|
+
include RandomName
|
|
11
|
+
|
|
12
|
+
attr_reader :client, :api_client, :region
|
|
13
|
+
|
|
14
|
+
# @param [Kontena::Client] api_client Kontena api client
|
|
15
|
+
# @param [String] access_key_id aws_access_key_id
|
|
16
|
+
# @param [String] secret_key aws_secret_access_key
|
|
17
|
+
# @param [String] region
|
|
18
|
+
def initialize(api_client, access_key_id, secret_key, region)
|
|
19
|
+
@api_client = api_client
|
|
20
|
+
@client = Fog::Compute.new(:provider => 'AWS', :aws_access_key_id => access_key_id, :aws_secret_access_key => secret_key, :region => region)
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @param [Hash] opts
|
|
25
|
+
def run!(opts)
|
|
26
|
+
ami = resolve_ami(client.region)
|
|
27
|
+
abort('No valid AMI found for region') unless ami
|
|
28
|
+
|
|
29
|
+
security_group = ensure_security_group(opts[:grid], opts[:vpc])
|
|
30
|
+
name = opts[:name ] || generate_name
|
|
31
|
+
|
|
32
|
+
opts[:vpc] = default_vpc.id unless opts[:vpc]
|
|
33
|
+
if opts[:subnet].nil?
|
|
34
|
+
subnet = default_subnet(opts[:vpc], client.region+opts[:zone])
|
|
35
|
+
opts[:subnet] = subnet.subnet_id
|
|
36
|
+
else
|
|
37
|
+
subnet = client.subnets.get(opts[:subnet])
|
|
38
|
+
end
|
|
39
|
+
dns_server = aws_dns_supported?(opts[:vpc]) ? '169.254.169.253' : '8.8.8.8'
|
|
40
|
+
userdata_vars = {
|
|
41
|
+
name: name,
|
|
42
|
+
version: opts[:version],
|
|
43
|
+
master_uri: opts[:master_uri],
|
|
44
|
+
grid_token: opts[:grid_token],
|
|
45
|
+
dns_server: dns_server
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
response = client.run_instances(
|
|
49
|
+
ami,
|
|
50
|
+
1,
|
|
51
|
+
1,
|
|
52
|
+
'InstanceType' => opts[:type],
|
|
53
|
+
'SecurityGroupId' => security_group.group_id,
|
|
54
|
+
'KeyName' => opts[:key_pair],
|
|
55
|
+
'SubnetId' => opts[:subnet],
|
|
56
|
+
'UserData' => user_data(userdata_vars),
|
|
57
|
+
'BlockDeviceMapping' => [
|
|
58
|
+
{
|
|
59
|
+
'DeviceName' => '/dev/xvda',
|
|
60
|
+
'VirtualName' => 'Root',
|
|
61
|
+
'Ebs.VolumeSize' => opts[:storage],
|
|
62
|
+
'Ebs.VolumeType' => 'gp2'
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
)
|
|
67
|
+
instance_id = response.body['instancesSet'].first['instanceId']
|
|
68
|
+
|
|
69
|
+
instance = client.servers.get(instance_id)
|
|
70
|
+
ShellSpinner "Creating AWS instance #{name.colorize(:cyan)} " do
|
|
71
|
+
instance.wait_for { ready? }
|
|
72
|
+
end
|
|
73
|
+
client.create_tags(instance.id, {'kontena_name' => name, 'kontena_grid' => opts[:grid]})
|
|
74
|
+
node = nil
|
|
75
|
+
ShellSpinner "Waiting for node #{name.colorize(:cyan)} join to grid #{opts[:grid].colorize(:cyan)} " do
|
|
76
|
+
sleep 2 until node = instance_exists_in_grid?(opts[:grid], name)
|
|
77
|
+
end
|
|
78
|
+
labels = ["region=#{client.region}", "az=#{opts[:zone]}"]
|
|
79
|
+
set_labels(node, labels)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# @param [String] grid
|
|
84
|
+
# @return Fog::Compute::AWS::SecurityGroup
|
|
85
|
+
def ensure_security_group(grid, vpc_id)
|
|
86
|
+
group_name = "kontena_grid_#{grid}"
|
|
87
|
+
if vpc_id
|
|
88
|
+
client.security_groups.all({'group-name' => group_name, 'vpc-id' => vpc_id}).first || create_security_group(group_name, vpc_id)
|
|
89
|
+
else
|
|
90
|
+
client.security_groups.get(group_name) || create_security_group(group_name)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
# creates security_group and authorizes default port ranges
|
|
96
|
+
#
|
|
97
|
+
# @param [String] name
|
|
98
|
+
# @return Fog::Compute::AWS::SecurityGroup
|
|
99
|
+
def create_security_group(name, vpc_id = nil)
|
|
100
|
+
security_group = client.security_groups.new(:name => name, :description => "Kontena Node", :vpc_id => vpc_id)
|
|
101
|
+
security_group.save
|
|
102
|
+
|
|
103
|
+
security_group.authorize_port_range(80..80)
|
|
104
|
+
security_group.authorize_port_range(443..443)
|
|
105
|
+
security_group.authorize_port_range(22..22)
|
|
106
|
+
security_group.authorize_port_range(6783..6783, group: {security_group.owner_id => security_group.group_id}, ip_protocol: 'tcp')
|
|
107
|
+
security_group.authorize_port_range(6783..6783, group: {security_group.owner_id => security_group.group_id}, ip_protocol: 'udp')
|
|
108
|
+
security_group
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# @param [String] region
|
|
113
|
+
# @return String
|
|
114
|
+
def resolve_ami(region)
|
|
115
|
+
images = {
|
|
116
|
+
'eu-central-1' => 'ami-74bbba69',
|
|
117
|
+
'ap-northeast-1' => 'ami-1e77ff1e',
|
|
118
|
+
'us-gov-west-1' => 'ami-f1d1b2d2',
|
|
119
|
+
'sa-east-1' => 'ami-632ba17e',
|
|
120
|
+
'ap-southeast-2' => 'ami-83f8b4b9',
|
|
121
|
+
'ap-southeast-1' => 'ami-12060c40',
|
|
122
|
+
'us-east-1' => 'ami-f396fa96',
|
|
123
|
+
'us-west-2' => 'ami-99bfada9',
|
|
124
|
+
'us-west-1' => 'ami-dbe71d9f',
|
|
125
|
+
'eu-west-1' => 'ami-83e9c8f4'
|
|
126
|
+
}
|
|
127
|
+
images[region]
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def default_subnet(vpc, zone)
|
|
131
|
+
client.subnets.all('vpc-id' => vpc, 'availabilityZone' => zone).first
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def default_vpc
|
|
135
|
+
client.vpcs.all('isDefault' => true).first
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def user_data(vars)
|
|
139
|
+
cloudinit_template = File.join(__dir__ , '/cloudinit.yml')
|
|
140
|
+
erb(File.read(cloudinit_template), vars)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def generate_name
|
|
144
|
+
"#{super}-#{rand(1..99)}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def instance_exists_in_grid?(grid, name)
|
|
148
|
+
api_client.get("grids/#{grid}/nodes")['nodes'].find{|n| n['name'] == name}
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def erb(template, vars)
|
|
152
|
+
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def set_labels(node, labels)
|
|
156
|
+
data = {}
|
|
157
|
+
data[:labels] = labels
|
|
158
|
+
api_client.put("nodes/#{node['id']}", data, {}, {'Kontena-Grid-Token' => node['grid']['token']})
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def aws_dns_supported?(vpc_id)
|
|
162
|
+
response = client.describe_vpc_attribute(vpc_id,'enableDnsSupport')
|
|
163
|
+
response.data[:body]['enableDnsSupport']
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require "azure"
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts "It seems that you don't have Azure SDK installed."
|
|
5
|
+
puts "Install it using: gem install azure:0.7.0"
|
|
6
|
+
exit 1
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require_relative 'random_name'
|
|
10
|
+
require_relative 'azure/logger'
|
|
11
|
+
require_relative 'azure/node_provisioner'
|
|
12
|
+
require_relative 'azure/node_destroyer'
|
|
13
|
+
require_relative 'azure/master_provisioner'
|
|
@@ -0,0 +1,59 @@
|
|
|
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/19" --bip="172.17.42.1/16"'
|
|
15
|
+
- path: /etc/resolv.conf
|
|
16
|
+
permissions: 0644
|
|
17
|
+
owner: root
|
|
18
|
+
content: |
|
|
19
|
+
nameserver 172.17.42.1
|
|
20
|
+
nameserver 8.8.8.8
|
|
21
|
+
nameserver 8.8.4.4
|
|
22
|
+
coreos:
|
|
23
|
+
units:
|
|
24
|
+
- name: 10-weave.network
|
|
25
|
+
runtime: false
|
|
26
|
+
content: |
|
|
27
|
+
[Match]
|
|
28
|
+
Type=bridge
|
|
29
|
+
Name=weave*
|
|
30
|
+
|
|
31
|
+
[Network]
|
|
32
|
+
- name: kontena-agent.service
|
|
33
|
+
command: start
|
|
34
|
+
enable: true
|
|
35
|
+
content: |
|
|
36
|
+
[Unit]
|
|
37
|
+
Description=kontena-agent
|
|
38
|
+
After=network-online.target
|
|
39
|
+
After=docker.service
|
|
40
|
+
Description=Kontena Agent
|
|
41
|
+
Documentation=http://www.kontena.io/
|
|
42
|
+
Requires=network-online.target
|
|
43
|
+
Requires=docker.service
|
|
44
|
+
|
|
45
|
+
[Service]
|
|
46
|
+
Restart=always
|
|
47
|
+
RestartSec=5
|
|
48
|
+
EnvironmentFile=/etc/kontena-agent.env
|
|
49
|
+
ExecStartPre=-/usr/bin/docker stop kontena-agent
|
|
50
|
+
ExecStartPre=-/usr/bin/docker rm kontena-agent
|
|
51
|
+
ExecStartPre=/usr/bin/docker pull kontena/agent:${KONTENA_VERSION}
|
|
52
|
+
ExecStart=/usr/bin/docker run --name kontena-agent \
|
|
53
|
+
-e KONTENA_URI=${KONTENA_URI} \
|
|
54
|
+
-e KONTENA_TOKEN=${KONTENA_TOKEN} \
|
|
55
|
+
-e KONTENA_PEER_INTERFACE=${KONTENA_PEER_INTERFACE} \
|
|
56
|
+
-v=/var/run/docker.sock:/var/run/docker.sock \
|
|
57
|
+
-v=/etc/kontena-agent.env:/etc/kontena.env \
|
|
58
|
+
--net=host \
|
|
59
|
+
kontena/agent:${KONTENA_VERSION}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#cloud-config
|
|
2
|
+
write_files:
|
|
3
|
+
- path: /etc/kontena-server.env
|
|
4
|
+
permissions: 0600
|
|
5
|
+
owner: root
|
|
6
|
+
content: |
|
|
7
|
+
KONTENA_VERSION=<%= version %>
|
|
8
|
+
<% if ssl_cert %>SSL_CERT="/etc/kontena-server.pem"
|
|
9
|
+
|
|
10
|
+
- path: /etc/kontena-server.pem
|
|
11
|
+
permissions: 0600
|
|
12
|
+
owner: root
|
|
13
|
+
content: | <% ssl_cert.split(/\n/).each do |row| %>
|
|
14
|
+
<%= row %><% end %><% end %>
|
|
15
|
+
- path: /opt/bin/kontena-haproxy.sh
|
|
16
|
+
permissions: 0755
|
|
17
|
+
owner: root
|
|
18
|
+
content: |
|
|
19
|
+
#!/bin/sh
|
|
20
|
+
if [ -n "$SSL_CERT" ]; then
|
|
21
|
+
SSL_CERT=$(awk 1 ORS='\\n' $SSL_CERT)
|
|
22
|
+
else
|
|
23
|
+
SSL_CERT="**None**"
|
|
24
|
+
fi
|
|
25
|
+
/usr/bin/docker run --name=kontena-server-haproxy \
|
|
26
|
+
--link kontena-server-api:kontena-server-api \
|
|
27
|
+
-e SSL_CERT="$SSL_CERT" -e BACKEND_PORT=9292 \
|
|
28
|
+
-p 80:80 -p 443:443 kontena/haproxy:latest
|
|
29
|
+
coreos:
|
|
30
|
+
update:
|
|
31
|
+
reboot-strategy: off
|
|
32
|
+
units:
|
|
33
|
+
- name: kontena-server-mongo.service
|
|
34
|
+
command: start
|
|
35
|
+
enable: true
|
|
36
|
+
content: |
|
|
37
|
+
[Unit]
|
|
38
|
+
Description=kontena-server-mongo
|
|
39
|
+
After=network-online.target
|
|
40
|
+
After=docker.service
|
|
41
|
+
Description=Kontena Server MongoDB
|
|
42
|
+
Documentation=http://www.mongodb.org/
|
|
43
|
+
Requires=network-online.target
|
|
44
|
+
Requires=docker.service
|
|
45
|
+
|
|
46
|
+
[Service]
|
|
47
|
+
Restart=always
|
|
48
|
+
RestartSec=5
|
|
49
|
+
ExecStartPre=/usr/bin/docker pull mongo:3.0
|
|
50
|
+
ExecStartPre=-/usr/bin/docker create --name=kontena-server-mongo-data mongo:3.0
|
|
51
|
+
ExecStartPre=-/usr/bin/docker stop kontena-server-mongo
|
|
52
|
+
ExecStartPre=-/usr/bin/docker rm kontena-server-mongo
|
|
53
|
+
ExecStart=/usr/bin/docker run --name=kontena-server-mongo \
|
|
54
|
+
--volumes-from=kontena-server-mongo-data \
|
|
55
|
+
mongo:3.0 mongod --smallfiles
|
|
56
|
+
|
|
57
|
+
- name: kontena-server-api.service
|
|
58
|
+
command: start
|
|
59
|
+
enable: true
|
|
60
|
+
content: |
|
|
61
|
+
[Unit]
|
|
62
|
+
Description=kontena-server-api
|
|
63
|
+
After=network-online.target
|
|
64
|
+
After=docker.service
|
|
65
|
+
After=kontena-server-mongo.service
|
|
66
|
+
Description=Kontena Master
|
|
67
|
+
Documentation=http://www.kontena.io/
|
|
68
|
+
Requires=network-online.target
|
|
69
|
+
Requires=docker.service
|
|
70
|
+
Requires=kontena-server-mongo.service
|
|
71
|
+
|
|
72
|
+
[Service]
|
|
73
|
+
Restart=always
|
|
74
|
+
RestartSec=5
|
|
75
|
+
EnvironmentFile=/etc/kontena-server.env
|
|
76
|
+
ExecStartPre=-/usr/bin/docker stop kontena-server-api
|
|
77
|
+
ExecStartPre=-/usr/bin/docker rm kontena-server-api
|
|
78
|
+
ExecStartPre=/usr/bin/docker pull kontena/server:${KONTENA_VERSION}
|
|
79
|
+
ExecStart=/usr/bin/docker run --name kontena-server-api \
|
|
80
|
+
--link kontena-server-mongo:mongodb \
|
|
81
|
+
-e MONGODB_URI=mongodb://mongodb:27017/kontena_server \
|
|
82
|
+
<% if auth_server %>-e AUTH_API_URL=<%= auth_server %><% end %> \
|
|
83
|
+
kontena/server:${KONTENA_VERSION}
|
|
84
|
+
|
|
85
|
+
- name: kontena-server-haproxy.service
|
|
86
|
+
command: start
|
|
87
|
+
enable: true
|
|
88
|
+
content: |
|
|
89
|
+
[Unit]
|
|
90
|
+
Description=kontena-server-haproxy
|
|
91
|
+
After=network-online.target
|
|
92
|
+
After=docker.service
|
|
93
|
+
Description=Kontena Server HAProxy
|
|
94
|
+
Documentation=http://www.kontena.io/
|
|
95
|
+
Requires=network-online.target
|
|
96
|
+
Requires=docker.service
|
|
97
|
+
|
|
98
|
+
[Service]
|
|
99
|
+
Restart=always
|
|
100
|
+
RestartSec=5
|
|
101
|
+
EnvironmentFile=/etc/kontena-server.env
|
|
102
|
+
ExecStartPre=-/usr/bin/docker stop kontena-server-haproxy
|
|
103
|
+
ExecStartPre=-/usr/bin/docker rm kontena-server-haproxy
|
|
104
|
+
ExecStartPre=/usr/bin/docker pull kontena/haproxy:latest
|
|
105
|
+
ExecStart=/opt/bin/kontena-haproxy.sh
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Kontena
|
|
2
|
+
module Machine
|
|
3
|
+
module Azure
|
|
4
|
+
class Logger
|
|
5
|
+
def info(msg)
|
|
6
|
+
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def error_with_exit(msg)
|
|
10
|
+
puts msg.colorize(:red)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def warn(msg)
|
|
14
|
+
puts msg.colorize(:yellow)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def error(msg)
|
|
18
|
+
puts msg.colorize(:red)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def exception_message(msg)
|
|
22
|
+
puts msg.colorize(:red)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'erb'
|
|
3
|
+
require 'open3'
|
|
4
|
+
require 'shell-spinner'
|
|
5
|
+
|
|
6
|
+
module Kontena
|
|
7
|
+
module Machine
|
|
8
|
+
module Azure
|
|
9
|
+
class MasterProvisioner
|
|
10
|
+
include RandomName
|
|
11
|
+
|
|
12
|
+
attr_reader :client, :http_client
|
|
13
|
+
|
|
14
|
+
# @param [String] subscription_id Azure subscription id
|
|
15
|
+
# @param [String] certificate Path to Azure management certificate
|
|
16
|
+
def initialize(subscription_id, certificate)
|
|
17
|
+
|
|
18
|
+
abort('Invalid management certificate') unless File.exists?(File.expand_path(certificate))
|
|
19
|
+
|
|
20
|
+
@client = ::Azure
|
|
21
|
+
client.management_certificate = certificate
|
|
22
|
+
client.subscription_id = subscription_id
|
|
23
|
+
client.vm_management.initialize_external_logger(Logger.new) # We don't want all the output
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def run!(opts)
|
|
27
|
+
abort('Invalid ssh key') unless File.exists?(File.expand_path(opts[:ssh_key]))
|
|
28
|
+
if opts[:ssl_cert]
|
|
29
|
+
abort('Invalid ssl cert') unless File.exists?(File.expand_path(opts[:ssl_cert]))
|
|
30
|
+
ssl_cert = File.read(File.expand_path(opts[:ssl_cert]))
|
|
31
|
+
end
|
|
32
|
+
cloud_service_name = generate_cloud_service_name
|
|
33
|
+
vm_name = cloud_service_name
|
|
34
|
+
master_url = ''
|
|
35
|
+
ShellSpinner "Creating Azure Virtual Machine #{vm_name.colorize(:cyan)}" do
|
|
36
|
+
if opts[:virtual_network].nil?
|
|
37
|
+
location = opts[:location].downcase.gsub(' ', '-')
|
|
38
|
+
default_network_name = "kontena-#{location}"
|
|
39
|
+
create_virtual_network(default_network_name, opts[:location]) unless virtual_network_exist?(default_network_name)
|
|
40
|
+
opts[:virtual_network] = default_network_name
|
|
41
|
+
opts[:subnet] = 'subnet-1'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
userdata_vars = {
|
|
45
|
+
ssl_cert: ssl_cert,
|
|
46
|
+
auth_server: opts[:auth_server],
|
|
47
|
+
version: opts[:version]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
params = {
|
|
51
|
+
vm_name: vm_name,
|
|
52
|
+
vm_user: 'core',
|
|
53
|
+
location: opts[:location],
|
|
54
|
+
image: '2b171e93f07c4903bcad35bda10acf22__CoreOS-Stable-766.3.0',
|
|
55
|
+
custom_data: Base64.encode64(user_data(userdata_vars)),
|
|
56
|
+
ssh_key: opts[:ssh_key]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
options = {
|
|
60
|
+
cloud_service_name: cloud_service_name,
|
|
61
|
+
deployment_name: vm_name,
|
|
62
|
+
virtual_network_name: opts[:virtual_network],
|
|
63
|
+
subnet_name: opts[:subnet],
|
|
64
|
+
tcp_endpoints: '80,443',
|
|
65
|
+
private_key_file: opts[:ssh_key],
|
|
66
|
+
ssh_port: 22,
|
|
67
|
+
vm_size: opts[:size],
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
virtual_machine = client.vm_management.create_virtual_machine(params,options)
|
|
72
|
+
|
|
73
|
+
if opts[:ssl_cert]
|
|
74
|
+
master_url = "https://#{virtual_machine.ipaddress}"
|
|
75
|
+
else
|
|
76
|
+
master_url = "http://#{virtual_machine.ipaddress}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
Excon.defaults[:ssl_verify_peer] = false
|
|
81
|
+
@http_client = Excon.new("#{master_url}", :connect_timeout => 10)
|
|
82
|
+
|
|
83
|
+
ShellSpinner "Waiting for #{vm_name.colorize(:cyan)} to start" do
|
|
84
|
+
sleep 5 until master_running?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
puts "Kontena Master is now running at #{master_url}"
|
|
88
|
+
puts "Use #{"kontena login #{master_url}".colorize(:light_black)} to complete Kontena Master setup"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def erb(template, vars)
|
|
92
|
+
ERB.new(template).result(OpenStruct.new(vars).instance_eval { binding })
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def user_data(vars)
|
|
96
|
+
cloudinit_template = File.join(__dir__ , '/cloudinit_master.yml')
|
|
97
|
+
erb(File.read(cloudinit_template), vars)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def master_running?
|
|
101
|
+
http_client.get(path: '/').status == 200
|
|
102
|
+
rescue
|
|
103
|
+
false
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def generate_cloud_service_name
|
|
107
|
+
"kontena-master-#{generate_name}-#{rand(1..99)}"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def cloud_service(name)
|
|
111
|
+
client.cloud_service_management.get_cloud_service(name)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def virtual_network_exist?(name)
|
|
115
|
+
client.network_management.list_virtual_networks.find{|n| n.name == name}
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def create_virtual_network(name, location)
|
|
119
|
+
address_space = ['10.0.0.0/20']
|
|
120
|
+
options = {subnet: [{:name => 'subnet-1', :ip_address=>'10.0.0.0', :cidr=>23}]}
|
|
121
|
+
client.network_management.set_network_configuration(name, location, address_space, options)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|