lib/providers/lxd.rb in gogetit-0.5.2 vs lib/providers/lxd.rb in gogetit-0.5.3
- old
+ new
@@ -40,192 +40,258 @@
until get_state(name) == state
sleep 3
end
end
- def generate_args(args, options)
+ # to generate 'user.user-data'
+ def generate_user_data(args, options)
logger.info("Calling <#{__method__.to_s}>")
- args[:devices] = {}
- ifaces = check_ip_available(options['ipaddresses'], maas, logger)
- abort("There is no dns server specified for the gateway network.") \
- unless ifaces[0]['dns_servers'][0]
- abort("There is no gateway specified for the gateway network.") \
- unless ifaces[0]['gateway_ip']
- args[:ifaces] = ifaces
- args[:config][:'user.network-config'] = {
- 'version' => 1,
- 'config' => [
- {
- 'type' => 'nameserver',
- 'address' => ifaces[0]['dns_servers'][0]
- }
- ]
- }
+ args = {}
+ args[:config] = {}
- ifaces.each_with_index do |iface,index|
- if index == 0
- iface_conf = {
- 'type' => 'physical',
- 'name' => "eth#{index}",
- 'subnets' => [
- {
- 'type' => 'static',
- 'ipv4' => true,
- 'address' => iface['ip'] + '/' + iface['cidr'].split('/')[1],
- 'gateway' => iface['gateway_ip'],
- 'mtu' => iface['vlan']['mtu'],
- 'control' => 'auto'
- }
- ]
- }
- elsif index > 0
- if ifaces[0]['vlan']['name'] != 'untagged'
+ if options['no-maas']
+ args[:config][:'user.user-data'] = \
+ YAML.load_file(options['file'])[:config]['user.user-data']
+ else
+ sshkeys = maas.get_sshkeys
+ pkg_repos = maas.get_package_repos
+
+ args[:config][:'user.user-data'] = { 'ssh_authorized_keys' => [] }
+
+ sshkeys.each do |key|
+ args[:config][:'user.user-data']['ssh_authorized_keys'].push(key['key'])
+ end
+
+ pkg_repos.each do |repo|
+ if repo['name'] == 'main_archive'
+ args[:config][:'user.user-data']['apt_mirror'] = repo['url']
+ end
+ end
+
+ args[:config][:"user.user-data"]['maas'] = true
+ end
+
+ # To disable to update apt database on first boot
+ # so chef client can keep doing its job.
+ args[:config][:'user.user-data']['package_update'] = false
+
+ args[:config][:"user.user-data"] = \
+ "#cloud-config\n" + YAML.dump(args[:config][:"user.user-data"])[4..-1]
+
+ return args
+ end
+
+ def generate_network_config(args, options)
+ logger.info("Calling <#{__method__.to_s}>")
+ if options['no-maas']
+ args[:config][:'user.network-config'] = \
+ YAML.load_file(options['file'])[:config][:'user.network-config']
+
+ options['ip_to_access'] = \
+ args[:config][:"user.network-config"]['config'][1]['subnets'][0]['address']
+ .split('/')[0]
+ args[:config][:"user.network-config"] = \
+ YAML.dump(args[:config][:"user.network-config"])[4..-1]
+
+ elsif options['ipaddresses']
+ options[:ifaces] = check_ip_available(options['ipaddresses'], maas, logger)
+ abort("There is no dns server specified for the gateway network.") \
+ unless options[:ifaces][0]['dns_servers'][0]
+ abort("There is no gateway specified for the gateway network.") \
+ unless options[:ifaces][0]['gateway_ip']
+
+ args[:config][:'user.network-config'] = {
+ 'version' => 1,
+ 'config' => [
+ {
+ 'type' => 'nameserver',
+ 'address' => options[:ifaces][0]['dns_servers'][0]
+ }
+ ]
+ }
+
+ # to generate configuration for [:config][:'user.network-config']['config']
+ options[:ifaces].each_with_index do |iface,index|
+ if index == 0
iface_conf = {
'type' => 'physical',
'name' => "eth#{index}",
'subnets' => [
{
'type' => 'static',
'ipv4' => true,
'address' => iface['ip'] + '/' + iface['cidr'].split('/')[1],
+ 'gateway' => iface['gateway_ip'],
'mtu' => iface['vlan']['mtu'],
'control' => 'auto'
}
]
}
- elsif ifaces[0]['vlan']['name'] == 'untagged'
- iface_conf = {
- 'type' => 'vlan',
- 'name' => "eth0.#{iface['vlan']['vid'].to_s}",
- 'vlan_id' => iface['vlan']['vid'].to_s,
- 'vlan_link' => 'eth0',
- 'subnets' => [
- {
- 'type' => 'static',
- 'ipv4' => true,
- 'address' => iface['ip'] + '/' + iface['cidr'].split('/')[1],
- 'mtu' => iface['vlan']['mtu'],
- 'control' => 'auto'
- }
- ]
- }
+ elsif index > 0
+ if options[:ifaces][0]['vlan']['name'] != 'untagged'
+ iface_conf = {
+ 'type' => 'physical',
+ 'name' => "eth#{index}",
+ 'subnets' => [
+ {
+ 'type' => 'static',
+ 'ipv4' => true,
+ 'address' => iface['ip'] + '/' + iface['cidr'].split('/')[1],
+ 'mtu' => iface['vlan']['mtu'],
+ 'control' => 'auto'
+ }
+ ]
+ }
+ elsif options[:ifaces][0]['vlan']['name'] == 'untagged'
+ iface_conf = {
+ 'type' => 'vlan',
+ 'name' => "eth0.#{iface['vlan']['vid'].to_s}",
+ 'vlan_id' => iface['vlan']['vid'].to_s,
+ 'vlan_link' => 'eth0',
+ 'subnets' => [
+ {
+ 'type' => 'static',
+ 'ipv4' => true,
+ 'address' => iface['ip'] + '/' + iface['cidr'].split('/')[1],
+ 'mtu' => iface['vlan']['mtu'],
+ 'control' => 'auto'
+ }
+ ]
+ }
+ end
end
+
+ args[:config][:'user.network-config']['config'].push(iface_conf)
end
- args[:config][:'user.network-config']['config'].push(iface_conf)
+ args[:config][:"user.network-config"] = \
+ YAML.dump(args[:config][:"user.network-config"])[4..-1]
end
- args[:config][:"user.network-config"] = \
- YAML.dump(args[:config][:"user.network-config"])[4..-1]
+ return args
+ end
- # To configure devices
- ifaces.each_with_index do |iface,index|
- if index == 0
- if iface['vlan']['name'] == 'untagged' # or vid == 0
+ # To configure devices
+ def generate_devices(args, options)
+ args[:devices] = {}
+
+ if options['no-maas']
+ args[:devices] = \
+ YAML.load_file(options['file'])[:devices]
+
+ elsif options['ipaddresses']
+ options[:ifaces].each_with_index do |iface,index|
+ if index == 0
+ if iface['vlan']['name'] == 'untagged' # or vid == 0
+ args[:devices][:"eth#{index}"] = {
+ mtu: iface['vlan']['mtu'].to_s, #This must be string
+ name: "eth#{index}",
+ nictype: 'bridged',
+ parent: config[:default][:root_bridge],
+ type: 'nic'
+ }
+ elsif iface['vlan']['name'] != 'untagged' # or vid != 0
+ args[:devices][:"eth#{index}"] = {
+ mtu: iface['vlan']['mtu'].to_s, #This must be string
+ name: "eth#{index}",
+ nictype: 'bridged',
+ parent: config[:default][:root_bridge] + "-" + iface['vlan']['vid'].to_s,
+ type: 'nic'
+ }
+ end
+ # When options[:ifaces][0]['vlan']['name'] == 'untagged' and index > 0,
+ # it does not need to generate more devices
+ # since it will configure the IPs with tagged VLANs.
+ elsif options[:ifaces][0]['vlan']['name'] != 'untagged'
args[:devices][:"eth#{index}"] = {
mtu: iface['vlan']['mtu'].to_s, #This must be string
name: "eth#{index}",
nictype: 'bridged',
- parent: config[:default][:native_bridge],
+ parent: config[:default][:root_bridge] + "-" + iface['vlan']['vid'].to_s,
type: 'nic'
}
- elsif iface['vlan']['name'] != 'untagged' # or vid != 0
- args[:devices][:"eth#{index}"] = {
- mtu: iface['vlan']['mtu'].to_s, #This must be string
- name: "eth#{index}",
- nictype: 'bridged',
- parent: config[:default][:native_bridge] + "-" + iface['vlan']['vid'].to_s,
- type: 'nic'
- }
end
- # When ifaces[0]['vlan']['name'] == 'untagged' and index > 0,
- # it does not need to generate more devices
- # since it will configure the IPs with tagged VLANs.
- elsif ifaces[0]['vlan']['name'] != 'untagged'
- args[:devices][:"eth#{index}"] = {
- mtu: iface['vlan']['mtu'].to_s, #This must be string
- name: "eth#{index}",
- nictype: 'bridged',
- parent: config[:default][:native_bridge] + "-" + iface['vlan']['vid'].to_s,
- type: 'nic'
- }
end
- end
-
- return args
- end
-
- def generate_common_args
- logger.info("Calling <#{__method__.to_s}>")
- args = {}
- sshkeys = maas.get_sshkeys
- pkg_repos = maas.get_package_repos
-
- args[:config] = {
- 'user.user-data': { 'ssh_authorized_keys' => [] }
- }
-
- sshkeys.each do |key|
- args[:config][:'user.user-data']['ssh_authorized_keys'].push(key['key'])
- end
-
- # To disable to update apt database on first boot
- # so chef client can keep doing its job.
- args[:config][:'user.user-data']['package_update'] = false
-
- pkg_repos.each do |repo|
- if repo['name'] == 'main_archive'
- args[:config][:'user.user-data']['apt_mirror'] = repo['url']
- end
- end
-
- args[:config][:"user.user-data"] = \
- YAML.dump(args[:config][:"user.user-data"])[4..-1]
-
- args[:config][:"user.user-data"] = "#cloud-config\n" + args[:config][:"user.user-data"]
- return args
- end
-
- def create(name, options = {})
- logger.info("Calling <#{__method__.to_s}>")
- abort("Container or Hostname #{name} already exists!") \
- if container_exists?(name) or maas.domain_name_exists?(name)
-
- args = generate_common_args
-
- if options['ipaddresses']
- args = generate_args(args, options)
- elsif options[:vlans]
- #check_vlan_available(options[:vlans])
else
- abort("native_bridge #{config[:default][:native_bridge]} does not exist.") \
- unless conn.networks.include? config[:default][:native_bridge]
+ abort("root_bridge #{config[:default][:root_bridge]} does not exist.") \
+ unless conn.networks.include? config[:default][:root_bridge]
- native_bridge_mtu = nil
+ root_bridge_mtu = nil
# It assumes you only use one fabric as of now,
# since there might be more fabrics with each untagged vlans on them,
# which might make finding exact mtu fail as following process.
default_fabric = 'fabric-0'
maas.get_subnets.each do |subnet|
if subnet['vlan']['name'] == 'untagged' and subnet['vlan']['fabric'] == default_fabric
- native_bridge_mtu = subnet['vlan']['mtu']
+ root_bridge_mtu = subnet['vlan']['mtu']
break
end
end
args[:devices] = {}
args[:devices][:"eth0"] = {
- mtu: native_bridge_mtu.to_s, #This must be string
+ mtu: root_bridge_mtu.to_s, #This must be string
name: 'eth0',
nictype: 'bridged',
- parent: config[:default][:native_bridge],
+ parent: config[:default][:root_bridge],
type: 'nic'
}
end
+ return args
+ end
+
+ def reserve_ips(name, options, container)
+ # Generate params to reserve IPs
+ options[:ifaces].each_with_index do |iface,index|
+ if index == 0
+ params = {
+ 'subnet' => iface['cidr'],
+ 'ip' => iface['ip'],
+ 'hostname' => name,
+ 'mac' => container[:expanded_config][:"volatile.eth#{index}.hwaddr"]
+ }
+ elsif index > 0
+ # if dot, '.', is used as a conjunction instead of '-',
+ # it fails ocuring '404 not found'.
+ # if under score, '_', is used as a conjunction instead of '-',
+ # it breaks MAAS DNS somehow..
+ if options[:ifaces][0]['vlan']['name'] == 'untagged'
+ params = {
+ 'subnet' => iface['cidr'],
+ 'ip' => iface['ip'],
+ 'hostname' => 'eth0' + '-' + iface['vlan']['vid'].to_s + '-' + name,
+ 'mac' => container[:expanded_config][:"volatile.eth0.hwaddr"]
+ }
+ elsif options[:ifaces][0]['vlan']['name'] != 'untagged'
+ params = {
+ 'subnet' => iface['cidr'],
+ 'ip' => iface['ip'],
+ 'hostname' => "eth#{index}" + '-' + name,
+ 'mac' => container[:expanded_config][:"volatile.eth#{index}.hwaddr"]
+ }
+ end
+ end
+ maas.ipaddresses('reserve', params)
+ end
+ end
+
+ def create(name, options = {})
+ logger.info("Calling <#{__method__.to_s}>")
+
+ abort("Container #{name} already exists!") \
+ if container_exists?(name)
+
+ abort("Domain #{name}.#{maas.get_domain} already exists!") \
+ if maas.domain_name_exists?(name) unless options['no-maas']
+
+ args = generate_user_data(args, options)
+ args = generate_network_config(args, options)
+ args = generate_devices(args, options)
+
args[:alias] ||= config[:lxd][:default_alias]
args[:sync] ||= true
conn.create_container(name, args)
container = conn.container(name)
@@ -233,50 +299,32 @@
container.devices = args[:devices].merge!(container.devices.to_hash)
conn.update_container(name, container)
# Fetch container object again
container = conn.container(name)
- if options['vlans'] or options['ipaddresses']
- # Generate params to reserve IPs
- args[:ifaces].each_with_index do |iface,index|
- if index == 0
- params = {
- 'subnet' => iface['cidr'],
- 'ip' => iface['ip'],
- 'hostname' => name,
- 'mac' => container[:expanded_config][:"volatile.eth#{index}.hwaddr"]
- }
- elsif index > 0
- # if dot, '.', is used as a conjunction instead of '-',
- # it fails ocuring '404 not found'.
- # if under score, '_', is used as a conjunction instead of '-',
- # it breaks MAAS DNS somehow..
- if args[:ifaces][0]['vlan']['name'] == 'untagged'
- params = {
- 'subnet' => iface['cidr'],
- 'ip' => iface['ip'],
- 'hostname' => 'eth0' + '-' + iface['vlan']['vid'].to_s + '-' + name,
- 'mac' => container[:expanded_config][:"volatile.eth0.hwaddr"]
- }
- elsif args[:ifaces][0]['vlan']['name'] != 'untagged'
- params = {
- 'subnet' => iface['cidr'],
- 'ip' => iface['ip'],
- 'hostname' => "eth#{index}" + '-' + name,
- 'mac' => container[:expanded_config][:"volatile.eth#{index}.hwaddr"]
- }
- end
- end
- maas.ipaddresses('reserve', params)
- end
- end
+ reserve_ips(name, options, container) \
+ if options['vlans'] or options['ipaddresses'] \
+ unless options['no-maas']
conn.start_container(name, :sync=>"true")
- fqdn = name + '.' + maas.get_domain
- wait_until_available(fqdn, logger)
+ if options['no-maas']
+ ip_or_fqdn = options['ip_to_access']
+ else
+ ip_or_fqdn = name + '.' + maas.get_domain
+ end
+
+ wait_until_available(ip_or_fqdn, logger)
logger.info("#{name} has been created.")
+
+ config[:default][:user] ||= ENV['USER']
+ if options['no-maas']
+ puts "ssh #{config[:default][:user]}@#{options['ip_to_access']}"
+ else
+ puts "ssh #{config[:default][:user]}@#{name}"
+ end
+
true
end
def destroy(name, args = {})
logger.info("Calling <#{__method__.to_s}>")
@@ -287,34 +335,39 @@
if get_state(name) == 'Running'
conn.stop_container(name, args)
end
wait_until_state(name, 'Stopped')
- conn.delete_container(name, args)
- if container[:config][:"user.network-config"]
- net_conf = YAML.load(
- container[:config][:"user.network-config"]
- )['config']
- # To remove DNS configuration
- net_conf.shift
+ if YAML.load(container[:config][:"user.user-data"])['maas']
+ logger.info("This is a MAAS enabled container.")
+ if container[:config][:"user.network-config"]
+ net_conf = YAML.load(
+ container[:config][:"user.network-config"]
+ )['config']
+ # To remove DNS configuration
+ net_conf.shift
- net_conf.each do |nic|
- if nic['subnets'][0]['type'] == 'static'
- # It assumes we only assign a single subnet on a VLAN.
- # Subnets in a VLAN, VLANs in a Fabric
- ip = nic['subnets'][0]['address'].split('/')[0]
+ net_conf.each do |nic|
+ if nic['subnets'][0]['type'] == 'static'
+ # It assumes we only assign a single subnet on a VLAN.
+ # Subnets in a VLAN, VLANs in a Fabric
+ ip = nic['subnets'][0]['address'].split('/')[0]
- if maas.ipaddresses_reserved?(ip)
- maas.ipaddresses('release', { 'ip' => ip })
+ if maas.ipaddresses_reserved?(ip)
+ maas.ipaddresses('release', { 'ip' => ip })
+ end
end
end
end
+
+ maas.delete_dns_record(name)
end
+ conn.delete_container(name, args)
+
# When multiple static IPs were reserved, it will not delete anything
# since they are deleted when releasing the IPs above.
- maas.delete_dns_record(name)
logger.info("#{name} has been destroyed.")
true
end
end
end