Project

General

Profile

« Previous | Next » 

Revision e83c8c6d

Added by Marek Hulán over 10 years ago

Kafoized version of foreman-installer

Foreman installer is now based on kafo gem
Submodules moved to modules/
Updated spec for new version
Update puppet, foreman, foreman-proxy modules
Don't include helper scripts into RPM

View differences:

.gitignore
*.swp
tags
## RUBYMINE
.idea
pkg/
foreman_installer/pkg/
foreman_installer/generate_answers.rb
.gitmodules
[submodule "tftp"]
path = tftp
path = modules/tftp
url = https://github.com/theforeman/puppet-tftp.git
[submodule "apache"]
path = apache
path = modules/apache
url = https://github.com/theforeman/puppet-apache.git
[submodule "foreman"]
path = foreman
path = modules/foreman
url = https://github.com/theforeman/puppet-foreman.git
[submodule "foreman_proxy"]
path = foreman_proxy
path = modules/foreman_proxy
url = https://github.com/theforeman/puppet-foreman_proxy.git
[submodule "passenger"]
path = passenger
path = modules/passenger
url = https://github.com/theforeman/puppet-passenger.git
[submodule "puppet"]
path = puppet
path = modules/puppet
url = https://github.com/theforeman/puppet-puppet.git
[submodule "xinetd"]
path = xinetd
path = modules/xinetd
url = https://github.com/puppetlabs/puppetlabs-xinetd.git
[submodule "git"]
path = git
path = modules/git
url = https://github.com/theforeman/puppet-git.git
[submodule "dhcp"]
path = dhcp
path = modules/dhcp
url = https://github.com/theforeman/puppet-dhcp
[submodule "dns"]
path = dns
path = modules/dns
url = https://github.com/theforeman/puppet-dns
[submodule "concat_native"]
path = concat_native
path = modules/concat_native
url = https://github.com/theforeman/puppet-concat.git
[submodule "mysql"]
path = mysql
path = modules/mysql
url = https://github.com/puppetlabs/puppetlabs-mysql.git
[submodule "postgresql"]
path = postgresql
path = modules/postgresql
url = https://github.com/puppetlabs/puppet-postgresql.git
[submodule "stdlib"]
path = stdlib
path = modules/stdlib
url = https://github.com/puppetlabs/puppetlabs-stdlib.git
[submodule "concat"]
path = concat
path = modules/concat
url = https://github.com/ripienaar/puppet-concat.git
[submodule "create_resources"]
path = create_resources
path = modules/create_resources
url = https://github.com/puppetlabs/puppetlabs-create_resources.git
README.md
# Setup
Please review the "answers" or setup file: foreman_installer/answers.yaml. This file allows
Please review the "answers" or setup file: /etc/foreman/foreman-installer-answers.yaml. This file allows
you to override any of the default parameters (as specified in <module>/manifests/params.pp)
Once you have created your answer file, install it with this command:
Once you are fine with your answer file, install it with this command:
foreman-install
or if you prefer interactive mode
foreman-install -i
echo include foreman_installer | puppet apply --modulepath /path_to/extracted_tarball
The answer file is a yaml format. For a module just using the defaults, simply put
"modulename: true" to include, or false to exclude. For a module which you wish to
apache
Subproject commit f6c5aa7aef976059610e3febd8a4d643ed7fefe5
bin/foreman-install
#!/usr/bin/env ruby
require 'rubygems'
require 'kafo'
CONFIG_FILE = "config/foreman-installer.yaml"
KafoConfigure.run
concat
Subproject commit 57ce1c70c822ae96b2fe17512913981485160539
concat_native
Subproject commit 4e487684786df0865b86c8809a9c0d6c58227739
config/answers.yaml
# Format:
# <classname>: false - don't include this class
# <classname>: true - include and use the defaults
# <classname>:
# <param>: <value> - include and override the default(s)
#
# See params.pp in each class for what options are available
---
foreman: true
foreman_proxy: true
puppet:
server: true
config/config_header.txt
# Format:
# <classname>: false - don't include this class
# <classname>: true - include and use the defaults
# <classname>:
# <param>: <value> - include and override the default(s)
#
# See params.pp in each class for what options are available
config/foreman-installer.yaml
# foreman-installer main configuration file
# note current configuration is written to foreman-installer.yaml every time foreman-install is run
## Installer configuration
# Path to answer file
:answer_file: ./config/answers.yaml
:installer_dir: .
# Uncomment if you want to load puppet modules from a specific path, $pwd/modules is used by default
:modules_dir: .
## Kafo tuning, customization of core functionality
# :no_prefix: false
# :mapping:
:order:
- foreman
- foreman_proxy
- puppet
## Useful for development, e.g. when you want to move log files to local directory
:log_dir: '/var/log/foreman-installer'
:log_level: :debug
# Change if you want to debug default answers for you modules, this directory holds default answers
# :default_values_dir: /tmp
## Advanced configuration - if not set it's ignored
# :log_owner: root
# :log_group: root
# :config_header_file:
# :dont_save_answers:
create_resources
Subproject commit 326ed04e261768af415652628f3bf767e2ad0389
dhcp
Subproject commit 1b51667018abc9909ec7c54669c3fdd4463c6049
dns
Subproject commit d4cbde4cf29fa7bc800162637a4c9727005a1efb
foreman
Subproject commit 680e65847d4668c1e3017fb1d4ce4383144c0133
foreman-installer.spec
Name: foreman-installer
Epoch: 1
Version: 1.2.9999
Release: 2%{?dotalphatag}%{?dist}
Release: 3%{?dotalphatag}%{?dist}
Summary: Puppet-based installer for The Foreman
Group: Applications/System
License: GPLv3+ and ASL 2.0
......
BuildArch: noarch
Requires: %{?scl_prefix}puppet >= 0.24.4
Requires: %{?scl_prefix}rubygem-kafo
Requires: %{?scl_prefix}rubygem-foreman_api >= 0.1.4
%if %{?skip_generator:0}%{!?skip_generator:1}
......
echo "%{version}" > VERSION
#replace shebangs for SCL
%if %{?scl:1}%{!?scl:0}
sed -ri '1sX(/usr/bin/ruby|/usr/bin/env ruby)X%{scl_ruby}X' generate_answers.rb
sed -ri '1sX(/usr/bin/ruby|/usr/bin/env ruby)X%{scl_ruby}X' bin/foreman-install
%endif
#modify foreman-installer.yaml paths according to platform
sed -i 's#\(.*answer_file:\).*#\1 %{_sysconfdir}/foreman/%{name}-answers.yaml#' config/%{name}.yaml
sed -i 's#\(.*installer_dir:\).*#\1 %{_datadir}/%{name}#' config/%{name}.yaml
sed -i 's#\(.*CONFIG_FILE\).*#\1 = "%{_sysconfdir}/foreman/%{name}.yaml"#' bin/foreman-install
%install
mkdir -p %{buildroot}/%{_datadir}/%{name}
cp -dpR * %{buildroot}/%{_datadir}/%{name}
%if %{?skip_generator:0}%{!?skip_generator:1}
mkdir -p %{buildroot}/%{_sbindir}
ln -sf %{_datadir}/%{name}/generate_answers.rb %{buildroot}/%{_sbindir}/foreman-generate-answers
ln -svf %{_datadir}/%{name}/bin/foreman-install %{buildroot}/%{_sbindir}/foreman-install
%endif
install -d -m0755 %{buildroot}%{_sysconfdir}/foreman
cp %{buildroot}/%{_datadir}/%{name}/config/%{name}.yaml %{buildroot}/%{_sysconfdir}/foreman/%{name}.yaml
cp %{buildroot}/%{_datadir}/%{name}/config/answers.yaml %{buildroot}/%{_sysconfdir}/foreman/%{name}-answers.yaml
%if 0%{?rhel} && 0%{?rhel} == 5
%clean
%{__rm} -rf $RPM_BUILD_ROOT
......
%files
%defattr(-,root,root,-)
%doc README.*
%exclude %{_datadir}/%{name}/build_modules
%exclude %{_datadir}/%{name}/release
%exclude %{_datadir}/%{name}/update_submodules
%exclude %{_datadir}/%{name}/foreman-installer.spec
%attr(600, root, root) %{_sysconfdir}/foreman/%{name}.yaml
%attr(600, root, root) %{_sysconfdir}/foreman/%{name}-answers.yaml
%{_sbindir}/foreman-install
%{_datadir}/%{name}
%if %{?skip_generator:0}%{!?skip_generator:1}
%{_sbindir}/foreman-generate-answers
%endif
%changelog
* Mon Jul 22 2013 Marek Hulan <mhulan[@]redhat.com> - 1.2.9999-3
- new files structure for a installer based on kafo
* Mon Jul 22 2013 Lukas Zapletal <lzap+rpm[@]redhat.com> - 1.2.9999-2
- adding foreman_api as a dependency
foreman_installer/Modulefile
name 'theforeman-foreman_installer'
version '1.2.0'
source 'git://github.com/theforeman/foreman-installer'
author 'theforeman'
license 'GPLv3+'
summary 'Complete Foreman server configuration'
description 'Module for configuring Foreman and related services'
project_page 'http://github.com/theforeman/foreman-installer'
dependency 'theforeman/foreman', '>= 1.2.0'
dependency 'theforeman/foreman_proxy', '>= 1.2.0'
# Doesn't exist on the Forge
#dependency 'puppetlabs/create_resources'
foreman_installer/answers.yaml
# Format:
# <classname>: false - don't include this class
# <classname>: true - include and use the defaults
# <classname>:
# <param>: <value> - include and override the default(s)
#
# See params.pp in each class for what options are available
---
foreman: true
foreman_proxy: true
puppet:
server: true
foreman_installer/lib/puppet/parser/functions/is_hash.rb
#
# is_hash.rb
#
module Puppet::Parser::Functions
newfunction(:is_hash, :type => :rvalue, :doc => <<-EOS
Returns true if the variable passed to this function is a hash.
EOS
) do |arguments|
raise(Puppet::ParseError, "is_hash(): Wrong number of arguments " +
"given (#{arguments.size} for 1)") if arguments.size != 1
type = arguments[0]
result = type.is_a?(Hash)
return result
end
end
# vim: set ts=2 sw=2 et :
foreman_installer/lib/puppet/parser/functions/loadanyyaml.rb
module Puppet::Parser::Functions
newfunction(:loadanyyaml, :type => :rvalue, :doc => <<-'ENDHEREDOC') do |args|
Load a YAML file containing an array, string, or hash, and return the data
in the corresponding native data type.
For example:
$myhash = loadanyyaml('/etc/puppet/data/myhash.yaml')
ENDHEREDOC
args.delete_if { |filename| not File.exist? filename }
if args.length == 0
raise Puppet::ParseError, ("loadanyyaml(): No files to load")
end
YAML.load_file(args[0])
end
end
foreman_installer/manifests/init.pp
# This class is called from the foreman install script (or Vagrantfile)
# and expects a yaml file to exist at either:
# optional $answers class parameter
# $modulepath/foreman_installer/answers.yaml
# /etc/foreman_installer/answers.yaml
#
class foreman_installer(
$answers = undef
) {
if empty($::fqdn) {
fail ("An FQDN is required for Foreman to install cleanly. Please ensure 'facter fqdn' returns the correct value before running this installer")
}
$params=loadanyyaml($answers,
"/etc/foreman-installer/answers.yaml",
"${settings::modulepath}/${module_name}/answers.yaml")
foreman_installer::yaml_to_class { ['foreman', 'foreman_proxy', 'puppet']: }
}
foreman_installer/manifests/yaml_to_class.pp
# Takes a key to lookup in the installation answers file
# - If it's a hash, declare a class with those parameters
# - If it's true or "true" declare the default parameters for that class
# - If it's false or "false" ignore it
# - Otherwise fail with error
#
define foreman_installer::yaml_to_class (
$classname = ''
) {
if $classname == '' {
$realname = $name
} else {
$realname = $classname
}
if is_hash($foreman_installer::params[$name]) {
# The quotes around $realname seem to matter to puppet's parser...
$params = { "${realname}" => $foreman_installer::params[$name] }
create_resources( 'class', $params )
} elsif $foreman_installer::params[$name] == true {
$params = { "${realname}" => {} }
create_resources( 'class', $params )
} elsif ! $foreman_installer::params[$name] or $foreman_installer::params[$name] == "false" {
debug("${::hostname}: not including $name")
} else {
fail("${::hostname}: unknown type of answers data for $name")
}
}
foreman_proxy
Subproject commit 90ed8e590ea8f533b64c4778cd52fd79cf5b8b3d
generate_answers.rb
#!/usr/bin/ruby
require 'rubygems'
require 'yaml'
require 'highline/import'
$workdir = File.dirname( File.symlink?(__FILE__) ? File.readlink(__FILE__) : __FILE__ )
$terminal = $terminal || Highline.new
# Bonus, per-module, questions defined up top where they're easy to find :)
def foreman_questions
{
"Should Foreman require SSL to be enabled? (default: true) " \
=> 'menu_helper("agree", "foreman", "ssl")',
"Should Foreman run under apache & passenger? (default: true) " \
=> 'menu_helper("agree", "foreman", "passenger")',
# This is a non-boolean example. Note we can't do validations easily here...
"Should Foreman be installed from the stable,rc, or nightly repo? (default: stable) " \
=> 'menu_helper("string", "foreman", "repo")',
"Should the database be installed and configured for Foreman? (default: true) " \
=> 'menu_helper("agree", "foreman", "db_manage")',
"Which database should be used for Foreman: postgresql (default), mysql or sqlite? " \
=> 'menu_helper("string", "foreman", "db_type")',
}
end
def foreman_proxy_questions
{
"Should Foreman_proxy be installed from the stable,rc, or nightly repo? (default: stable) " \
=> 'menu_helper("string", "foreman_proxy", "repo")',
"Should Foreman_proxy manage Puppet (needed for puppet classes)? (default: true) " \
=> 'menu_helper("agree", "foreman_proxy", "puppetrun")',
"Should Foreman_proxy manage PuppetCA (needed for certificates)? (default: true) " \
=> 'menu_helper("agree", "foreman_proxy", "puppetca")',
"Should Foreman_proxy manage TFTP? (default: true) " \
=> 'menu_helper("agree", "foreman_proxy", "tftp")',
"Should Foreman_proxy manage DNS? (default: false) " \
=> 'menu_helper("agree", "foreman_proxy", "dns")',
"Should Foreman_proxy manage DHCP? (default: false) " \
=> 'menu_helper("agree", "foreman_proxy", "dhcp")',
}
end
def puppet_questions
{
"Should a Puppetmaster be installed on this host? (default: true) " \
=> 'menu_helper("agree", "puppet", "server")',
"Should Puppetmaster use Git for dynamic environments? (default: false) " \
=> 'menu_helper("agree", "puppet", "server_git_repo")',
"Should Puppetmaster run under apache & passenger? (default: true) " \
=> 'menu_helper("agree", "puppet", "server_passenger")',
}
end
# colour scheme for prompts
HighLine.color_scheme = HighLine::ColorScheme.new do |cs|
cs[:headline] = [ :bold, :yellow, :on_black ]
cs[:horizontal_line] = [ :bold, :white, :on_black]
cs[:question] = [ :bold, :green, :on_black]
cs[:info] = [ :bold, :cyan, :on_black]
end
# Line wrapping - don't go over 80 chars even if the terminal is huge...
data = HighLine::SystemExtensions.terminal_size
$terminal.wrap_at = data.first > 80 ? 80 : data.first
$terminal.page_at = data.last
# default output
$outfile = "#{$workdir}/foreman_installer/answers.yaml"
$output = {
"foreman" => true,
"foreman_proxy" => true,
"puppet" => { "server" => true },
}
# helper methods
def save_or_run_and_exit
File.open($outfile, 'w') {|f| f.write(YAML.dump($output)) }
# If the foreman_installer module exists then just use it. Otherwise, ask.
$modulepath = File.exists?("#{$workdir}/foreman_installer") ? $workdir : ask("<%= color('Where are the installer Puppet modules?', :question) %>")
if Process::UID.eid == 0 && agree("\n<%= color('Do you want to run Puppet now with these settings?', :question) %> (y/n)", false)
system("echo include foreman_installer | puppet apply --detailed-exitcodes --modulepath #{$modulepath} -v")
if [1,4,6].include? $?.exitstatus
parting_error
else
parting_message
end
else
parting_message
end
end
def parting_message
say("\n Okay, you're all set! Check <%= color('#{$outfile}', :cyan) %> for your config.")
say("\n You can apply it in the future as root with:")
say(" echo include foreman_installer | puppet apply --modulepath #{$modulepath} -v")
exit 0
end
def parting_error
say("\n <%= color('There was an error!', :red) %>")
say("\n Check the puppet error messages above, and <%= color('#{$outfile}', :cyan) %> for your config.")
say("\n Once you have fixed the problem, you can re-run it in the future as root with:")
say(" echo include foreman_installer | puppet apply --modulepath #{$modulepath} -v")
exit 1
end
def display_hash modulename = nil
stat = if modulename.nil?
"\n#{YAML.dump($output)}"
elsif $output[modulename] == true
"#{modulename.capitalize} is enabled with defaults\n"
elsif $output[modulename] == false
"#{modulename.capitalize} is disabled\n"
else
"#{modulename.capitalize} is enabled with overrides:\n#{YAML.dump($output[modulename])}"
end
say("\n<%= color('Current config is:\n#{stat}', :info) %>")
end
def menu_helper type,name,key=nil,value=nil
case type
when "agree"
add_keyvalue_pair(name, key, agree("y/n?",true))
when "string"
add_keyvalue_pair(name, key, ask("?"))
end
end
def configure_module modulename
while true do
choose do |menu|
display_hash modulename
say("\n<%= color('#{modulename.capitalize} Config Menu', :headline) %>")
menu.prompt = "Choose an option from the menu... "
menu.choice "Enable #{modulename} with all defaults" do
if modulename == 'puppet'
$output[modulename] = { 'server' => true }
else
$output[modulename] = true
end
end
menu.choice "Disable #{modulename} completely" do $output[modulename] = false end
eval("#{modulename}_questions").each do |question, code|
menu.choice question do eval(code) end
end
menu.choice "Add other key/value pair to the config" do add_keyvalue_pair(modulename) end
menu.choice "Go up to main menu" do return end
end
end
end
def add_keyvalue_pair modulename, key=nil, value=nil
$output[modulename] = Hash.new if [true,false].include?($output[modulename])
key = key.nil? ? ask("<%= color('Key name? ', :question) %>") : key
value = value.nil? ? ask("<%= color('Value? ', :question) %>") : value
# fix some simple cases
value = true if value == "true"
value = false if value == "false"
value = Integer(value) rescue value
$output[modulename][key] = value
end
# Usage statement
say("<%= color('Welcome to the Foreman Installer!', :headline) %>")
say("<%= color('---------------------------------', :horizontal_line) %>")
say(<<END)
This installer will help you set up Foreman and the associated extra configuration necessary to get you up and running. There is an interactive shell which will ask you questions, but if you just want to get up and running as fast as possible, answer 'yes' to the all-in-one install at the beginning
END
exit 0 unless agree("\n<%= color('Ready to start?', :question) %> (y/n)",false)
# Start with the basics
if agree("\n<%= color('Do you want to use the default all-in-one setup?', :question) %>\nThis will configure Foreman, Foreman-Proxy, Puppet (including a puppetmaster), several puppet environments, TFTP (for provisioning) and sudo (for puppet certificate management) (y/n)",false)
save_or_run_and_exit
end
while true do
say("\n<%= color('Main Config Menu', :headline) %>")
choose do |menu|
menu.prompt = 'Choose an option from the menu... '
["foreman","foreman_proxy","puppet"].each do |name|
menu.choice "Configure #{name.capitalize} settings" do configure_module name end
end
menu.choice "Display current config" do display_hash end
menu.choice "Save and Exit" do save_or_run_and_exit end
menu.choice "Exit without Saving" do say("Bye!") ; exit 0 end
end
end
git
Subproject commit bf100c0f9adda42c43dd1219bd5a1df7411cb4d5
modules/apache
Subproject commit f6c5aa7aef976059610e3febd8a4d643ed7fefe5
modules/concat
Subproject commit 57ce1c70c822ae96b2fe17512913981485160539
modules/concat_native
Subproject commit 4e487684786df0865b86c8809a9c0d6c58227739
modules/create_resources
Subproject commit 326ed04e261768af415652628f3bf767e2ad0389
modules/dhcp
Subproject commit 1b51667018abc9909ec7c54669c3fdd4463c6049
modules/dns
Subproject commit d4cbde4cf29fa7bc800162637a4c9727005a1efb
modules/foreman
Subproject commit 8a49f473b85a436c83cb73bfee6d4ff2c1ad1401
modules/foreman_proxy
Subproject commit 90ed8e590ea8f533b64c4778cd52fd79cf5b8b3d
modules/git
Subproject commit bf100c0f9adda42c43dd1219bd5a1df7411cb4d5
modules/mysql
Subproject commit 8000041e9f08d94fff237e5cbf37d7e547aabb3c
modules/passenger
Subproject commit 9302e3f87af963d03c7292bff568b1daf41340dd
modules/postgresql
Subproject commit 80d44718e93ea1417f1c84cd730c41a2187bd39c
modules/puppet
Subproject commit f2687c8001c1c1721860acf75951ecdcf12bd72d
modules/stdlib
Subproject commit f90c54e2df6e8cbd8490a59c7429938072dc1b8d
modules/tftp
Subproject commit cd78b452e24ab2faf2b4ce12be9c738dc3072cc2
modules/xinetd
Subproject commit d26f884ffa75f8e0bb7f6087f94dad814c38f49d
mysql
Subproject commit 8000041e9f08d94fff237e5cbf37d7e547aabb3c
passenger
Subproject commit 9302e3f87af963d03c7292bff568b1daf41340dd
postgresql
Subproject commit 80d44718e93ea1417f1c84cd730c41a2187bd39c
puppet
Subproject commit 3c158112a749d2d96345cbe4cfbce95cd1692b2a
stdlib
Subproject commit f90c54e2df6e8cbd8490a59c7429938072dc1b8d
tftp
Subproject commit cd78b452e24ab2faf2b4ce12be9c738dc3072cc2
xinetd
Subproject commit d26f884ffa75f8e0bb7f6087f94dad814c38f49d

Also available in: Unified diff