Add support of extend_kopts for ubuntu_bootstrap

This commit adds posibility to use different kernel boot options
if user would like to modify it. The extend_kopts.rb takes two strings,
compares them and modifies default kopts.

Implements: Blueprint modify-fuel-library
Change-Id: Iac69c8457bd0ce76a1082c98d679ff44f468bf1f
This commit is contained in:
Valeriy Sakharov 2015-11-11 20:54:56 +03:00 committed by Valyavskiy Viacheslav
parent da41cf5aa2
commit 296d26059e
4 changed files with 110 additions and 6 deletions

View File

@ -34,10 +34,14 @@ node default {
$cobbler_url = "http://${::fuel_settings['ADMIN_NETWORK']['ipaddress']}/cobbler_api"
$cobbler_user = $::fuel_settings['cobbler']['user']
$cobbler_password = $::fuel_settings['cobbler']['password']
$bootstrap_settings = pick($::fuel_settings['BOOTSTRAP'], {})
$bootstrap_flavor = pick($bootstrap_settings['flavor'], 'centos')
$bootstrap_ethdevice_timeout = pick($bootstrap_settings['ethdevice_timeout'], '120')
$nailgun_api_url = "http://${::fuel_settings['ADMIN_NETWORK']['ipaddress']}:8000/api"
$bootstrap_settings = pick($::fuel_settings['BOOTSTRAP'], {})
$bootstrap_flavor = pick($bootstrap_settings['flavor'], 'centos')
$bootstrap_path = pick($bootstrap_settings['path'], '/var/www/nailgun/bootstraps/active_bootstrap')
$bootstrap_meta = pick(loadyaml("${bootstrap_path}/metadata.yaml"), {})
$bootstrap_ethdevice_timeout = pick($bootstrap_settings['ethdevice_timeout'], '120')
if $production == "docker-build" {
$cobbler_host = $::ipaddress
$dhcp_interface = "eth0"
@ -85,6 +89,8 @@ node default {
cobbler_user => $cobbler_user,
cobbler_password => $cobbler_password,
bootstrap_flavor => $bootstrap_flavor,
bootstrap_path => $bootstrap_path,
bootstrap_meta => $bootstrap_meta,
server => $cobbler_host,
name_server => $cobbler_host,
next_server => $cobbler_host,

View File

@ -0,0 +1,60 @@
module MultipleKopts
# Transform string into hash and provide array of keys:
# Example:
# Input data: "first=21 first=12 second=44"
# Output data: [{ first => "21 12", second => "44"}, [ first, first, second]]
def self.string_to_hash_with_keys(string)
hash, option_order = {}, []
string.to_s.split(' ').each() do |e|
key, value = e.split("=", 2).map { |i| i.strip()}
hash[key] = hash.has_key?(key) ? "#{hash[key]} #{value}" : value
option_order << key
end
[hash, option_order]
end
# Transform hash into string using key's order from 'keys' array:
# Example:
# Input data: { first => "21 12", second => "44"}, [ first, second]
# Output data: "first=21 first=12 second=44"
def self.hash_to_string(hash, keys)
string = ""
keys.each() do |key|
value = hash[key]
opt_string = value.nil? ? key : value.split(' ').map { |e| "#{key}=#{e}" }.join(' ')
string = "#{string} #{opt_string}"
end
string.strip()
end
end
module Puppet::Parser::Functions
newfunction(:extend_kopts, :type => :rvalue, :doc => <<-EOS
This function changes "kopts" parameter if user modified it
and return the string. It takes two arguments: string from
metadata.yaml from "extend_kopts" option and default string
in format "key1=value1 key2=value2 key3".
For example:
$metadata = loadyaml('path/to/metadata.yaml')
extend_kopts($metadata['extend_kopts'], 'key1=a key2=b")
Function compare two strings, make changes into default option
and return it.
So, if in the /path/to/metadata.yaml in the "extend_kopts" will be
"key3=c key4 key1=not_a", we will get in the output:
"key2=b key3=c key4 key1=not_a".
EOS
) do |args|
raise Puppet::ParseError, ("extend_kopts(): wrong number of arguments - #{args.length}, must be 2") unless args.length == 2
hash_new_kopts, new_kopts_keys = MultipleKopts.string_to_hash_with_keys(args[0])
hash_default_kopts, default_kopts_keys = MultipleKopts.string_to_hash_with_keys(args[1])
keys = (new_kopts_keys + default_kopts_keys).uniq()
return MultipleKopts.hash_to_string(hash_default_kopts.merge(hash_new_kopts), keys)
end
end

View File

@ -1,8 +1,11 @@
# Install and configures cobbler
class nailgun::cobbler(
$cobbler_user = 'cobbler',
$cobbler_password = 'cobbler',
$bootstrap_flavor = 'centos',
$bootstrap_path,
$bootstrap_meta,
# network interface configuration timeout (in seconds)
$bootstrap_ethdevice_timeout = '120',
$centos_repos,
@ -165,8 +168,8 @@ class nailgun::cobbler(
}
cobbler_distro { 'ubuntu_bootstrap':
kernel => "${repo_root}/bootstrap/ubuntu/linux",
initrd => "${repo_root}/bootstrap/ubuntu/initramfs.img",
kernel => "${bootstrap_path}/vmlinuz",
initrd => "${bootstrap_path}/initrd.img",
arch => 'x86_64',
breed => 'ubuntu',
osversion => 'trusty',
@ -188,7 +191,7 @@ class nailgun::cobbler(
distro => 'ubuntu_bootstrap',
menu => true,
kickstart => '',
kopts => "console=ttyS0,9600 console=tty0 panic=60 ethdevice-timeout=${bootstrap_ethdevice_timeout} boot=live toram components fetch=http://${server}:8080/bootstrap/ubuntu/root.squashfs biosdevname=0 url=${nailgun_api_url} mco_user=${mco_user} mco_pass=${mco_pass}",
kopts => extend_kopts($bootstrap_meta['extend_kopts'], "console=ttyS0,9600 console=tty0 panic=60 ethdevice-timeout=${bootstrap_ethdevice_timeout} boot=live toram components fetch=http://${server}:8080/bootstraps/active_bootstrap/root.squashfs biosdevname=0 url=${nailgun_api_url} mco_user=${mco_user} mco_pass=${mco_pass}"),
ksmeta => '',
server => $real_server,
require => Cobbler_distro['ubuntu_bootstrap'],

View File

@ -0,0 +1,35 @@
require 'spec_helper'
describe 'extend_kopts' do
it 'number args' do
is_expected.to run.with_params('foo').and_raise_error(Puppet::ParseError, "extend_kopts(): wrong number of arguments - 1, must be 2")
end
it { should run.with_params("biosdevname=0 ifnames=1 rd.luks.uuid=30 panic=15 quiet debug udev.log-priority=2 systemd.gpt_auto=1","console=ttyS0,9600 console=tty0 console=tty1 panic=60 boot=live toram fetch=http://127.0.0.1:8080/active_bootstrap/root.squashfs biosdevname=0").and_return("biosdevname=0 ifnames=1 rd.luks.uuid=30 panic=15 quiet debug udev.log-priority=2 systemd.gpt_auto=1 console=ttyS0,9600 console=tty0 console=tty1 boot=live toram fetch=http://127.0.0.1:8080/active_bootstrap/root.squashfs") }
it 'should merge options with the same key using first argument as high priority source' do
should run.with_params("bios=0 rd.luks=30", "bios=1 rd.luks=20").and_return("bios=0 rd.luks=30")
end
it 'should combine unique options' do
should run.with_params("biosdevname=0 quit", "biosdevname=1 debug").and_return("biosdevname=0 quit debug")
end
it 'should properly merge options contain key-value separator' do
should run.with_params("abc=def=123 debug", "abc=ttt=44 quit").and_return("abc=def=123 debug quit")
end
it 'should save options order' do
should run.with_params("zx=123 ar bh=test", "").and_return("zx=123 ar bh=test")
end
it 'should use default options if new are not present' do
should run.with_params("", "ff=11 quit ko=12").and_return("ff=11 quit ko=12")
end
it 'should merge options with multiple values' do
should run.with_params("c=ttyS0,9600 c=tty0", "c=tty3 ff=11").and_return("c=ttyS0,9600 c=tty0 ff=11")
end
end