cookbooks/mu-master/recipes/init.rb in cloud-mu-3.4.0 vs cookbooks/mu-master/recipes/init.rb in cloud-mu-3.5.0

- old
+ new

@@ -33,24 +33,24 @@ # from us. ENV['PATH'] = ENV['PATH']+":/bin:/opt/opscode/embedded/bin" # XXX We want to be able to override these things when invoked from chef-apply, # but, like, how? -CHEF_SERVER_VERSION="12.17.15-1" -CHEF_CLIENT_VERSION="14.13.11" +CHEF_SERVER_VERSION="14.0.65-1" +CHEF_CLIENT_VERSION="16.9.29" KNIFE_WINDOWS="1.9.0" MU_BASE="/opt/mu" -MU_BRANCH="master" # GIT HOOK EDITABLE DO NOT TOUCH -realbranch=`cd #{MU_BASE}/lib && git rev-parse --abbrev-ref HEAD` # ~FC048 -if ENV.key?('MU_BRANCH') - MU_BRANCH = ENV['MU_BRANCH'] +MU_BRANCH = if ENV.key?('MU_BRANCH') + ENV['MU_BRANCH'] elsif $?.exitstatus == 0 - MU_BRANCH=realbranch.chomp + realbranch=`cd #{MU_BASE}/lib && git rev-parse --abbrev-ref HEAD` # ~FC048 + realbranch.chomp else - MU_BRANCH="master" + "master" end + begin resources('service[sshd]') rescue Chef::Exceptions::ResourceNotFound service "sshd" do action :nothing @@ -75,10 +75,16 @@ ignore_failure true action :nothing only_if "( /bin/systemctl -l --no-pager | grep iptables.service ) || ( /sbin/chkconfig --list | grep ^iptables )" end +service "firewalld" do + ignore_failure true + action :nothing + only_if "/bin/systemctl -l --no-pager | grep firewalld.service" +end + # These guys are a workaround for Opscode bugs that seems to affect some Chef # Server upgrades. directory "/var/run/postgresql" do mode 0755 # owner "opscode-pgsql" @@ -124,32 +130,43 @@ notifies :create, "remote_file[back up /etc/hosts]", :before only_if { RUNNING_STANDALONE } not_if { ::Dir.exist?("#{MU_BASE}/lib/.git") } end +execute "modprobe br_netfilter" do + action :nothing +end + execute "reconfigure Chef server" do - command "/opt/opscode/bin/chef-server-ctl reconfigure" + command "CHEF_LICENSE=\"accept\" /opt/opscode/bin/chef-server-ctl reconfigure" action :nothing notifies :stop, "service[iptables]", :before + notifies :stop, "service[firewalld]", :before # notifies :create, "link[/tmp/.s.PGSQL.5432]", :before notifies :create, "link[/var/run/postgresql/.s.PGSQL.5432]", :before notifies :restart, "service[chef-server]", :immediately if !RUNNING_STANDALONE notifies :start, "service[iptables]", :immediately + notifies :start, "service[firewalld]", :immediately + else + notifies :run, "execute[Chef Server rabbitmq workaround]", :before end only_if { RUNNING_STANDALONE } end execute "upgrade Chef server" do - command "/opt/opscode/bin/chef-server-ctl upgrade" + command "CHEF_LICENSE=\"accept\" /opt/opscode/bin/chef-server-ctl upgrade" action :nothing timeout 1200 # this can take a while notifies :stop, "service[iptables]", :before + notifies :stop, "service[firewalld]", :before + notifies :run, "execute[modprobe br_netfilter]", :before notifies :run, "execute[Chef Server rabbitmq workaround]", :before # notifies :create, "link[/tmp/.s.PGSQL.5432]", :before notifies :create, "link[/var/run/postgresql/.s.PGSQL.5432]", :before if !RUNNING_STANDALONE notifies :start, "service[iptables]", :immediately + notifies :start, "service[firewalld]", :immediately end only_if { RUNNING_STANDALONE } end service "chef-server" do restart_command "/opt/opscode/bin/chef-server-ctl restart" @@ -158,12 +175,14 @@ pattern "/opt/opscode/embedded/sbin/nginx" action :nothing # notifies :create, "link[/tmp/.s.PGSQL.5432]", :before # notifies :create, "link[/var/run/postgresql/.s.PGSQL.5432]", :before notifies :stop, "service[iptables]", :before + notifies :stop, "service[firewalld]", :before if !RUNNING_STANDALONE notifies :start, "service[iptables]", :immediately + notifies :start, "service[firewalld]", :immediately end only_if { RUNNING_STANDALONE } end basepackages = [] @@ -171,24 +190,24 @@ rpms = {} dpkgs = {} elversion = node['platform_version'].split('.')[0] -rhelbase = ["git", "curl", "diffutils", "patch", "gcc", "gcc-c++", "make", "postgresql-devel", "libyaml", "libffi-devel", "tcl", "tk"] +rhelbase = ["git", "curl", "diffutils", "patch", "gcc", "gcc-c++", "make", "postgresql-devel", "libyaml", "libffi-devel", "tcl", "tk", "xfsprogs"] case node['platform_family'] when 'rhel' basepackages = rhelbase case node['platform_version'].split('.')[0].to_i when 6 - basepackages.concat(["cryptsetup-luks", "mysql-devel", "centos-release-scl"]) + basepackages.concat(["cryptsetup-luks", "mysql-devel", "centos-release-scl", "perl-WWW-Curl"]) removepackages = ["nagios"] when 7 - basepackages.concat(['libX11', 'mariadb-devel', 'cryptsetup']) + basepackages.concat(['policycoreutils-python', 'libX11', 'mariadb-devel', 'cryptsetup', 'tcl-devel', 'gdbm-devel', 'sqlite-devel', 'tk-devel', 'perl-CGI', 'perl-DBI', 'perl-Data-Dumper', 'perl-Digest-MD5', 'perl-Git-SVN', 'perl-YAML', 'nvme-cli']) removepackages = ['nagios', 'firewalld'] when 8 raise "Mu currently does not support RHEL 8... but I assume it will in the future... But I am Bill and I am hopeful about the future." else @@ -220,12 +239,22 @@ rpms = { "epel-release" => "http://dl.fedoraproject.org/pub/epel/epel-release-latest-#{elversion}.noarch.rpm", "chef-server-core" => "https://packages.chef.io/files/stable/chef-server/#{CHEF_SERVER_VERSION.sub(/\-\d+$/, "")}/el/#{elversion}/chef-server-core-#{CHEF_SERVER_VERSION}.el#{elversion}.x86_64.rpm" } -rpms["ruby25"] = "https://s3.amazonaws.com/cloudamatic/muby-2.5.3-1.el#{elversion}.x86_64.rpm" -rpms["python27"] = "https://s3.amazonaws.com/cloudamatic/muthon-2.7.16-1.el#{elversion}.x86_64.rpm" +rpms["ruby27"] = "https://s3.amazonaws.com/cloudamatic/muby-2.7.2-1.el#{elversion}.x86_64.rpm" +if elversion.to_i == 6 + rpms["openssl"] = "https://s3.amazonaws.com/cloudamatic/mussl-1.1.1h-1.el6.x86_64.rpm" + rpms["sqlite"] = "https://s3.amazonaws.com/cloudamatic/muqlite-3.33-1.el6.x86_64.rpm" +end +if elversion.to_i == 7 + rpms["mugit"] = "https://s3.amazonaws.com/cloudamatic/mugit-2.30.0-1.el7.x86_64.rpm" +end +# this takes up a huge amount of space, save it until we're fully operational +if !RUNNING_STANDALONE + rpms["python38"] = "https://s3.amazonaws.com/cloudamatic/muthon-3.8.3-1.el#{elversion}.x86_64.rpm" +end package basepackages directory MU_BASE do recursive true @@ -296,42 +325,45 @@ notifies :run, "execute[reconfigure Chef server]", :immediately notifies :restart, "service[chef-server]", :immediately only_if { RUNNING_STANDALONE } end -# REMOVE OLD RUBYs -execute "clean up old Ruby 2.1.6" do - command "rm -rf /opt/rubies/ruby-2.1.6" - ignore_failure true - only_if { ::Dir.exist?("/opt/rubies/ruby-2.1.6") } -end - -execute "Kill ruby-2.3.1" do +execute "clean up old ruby-2.3.1 package" do command "yum erase ruby23-2.3.1-1.el7.centos.x86_64 -y; rpm -e ruby23" ignore_failure true only_if { ::Dir.exist?("/opt/rubies/ruby-2.3.1") } end - -execute "clean up old ruby-2.3.1" do - command "rm -rf /opt/rubies/ruby-2.3.1" +execute "clean up old muby-2.5.3 package" do + command "yum erase muby-2.5.3-1.el7.x86_64 -y" ignore_failure true - only_if { ::Dir.exist?("/opt/rubies/ruby-2.3.1") } + only_if "rpm -q muby-2.5.3" end +%w{2.1.6 2.3.1 2.5.3}.each { |v| + execute "clean up old ruby-#{v} directory" do + command "rm -rf /opt/rubies/ruby-#{v}" + ignore_failure true + only_if { ::Dir.exist?("/opt/rubies/ruby-#{v}") } + end +} + execute "yum makecache" do action :nothing end # Regular old rpm-based installs rpms.each_pair { |pkg, src| rpm_package pkg do source src - if pkg == "ruby25" + if pkg == "ruby27" options '--prefix=/opt/rubies/' end if pkg == "epel-release" notifies :run, "execute[yum makecache]", :immediately + if elversion.to_i == 6 + not_if "rpm -q epel-release" + end end if pkg == "chef-server-core" notifies :stop, "service[iptables]", :before if File.size?("/etc/opscode/chef-server.rb") # On a normal install this will execute when we set up chef-server.rb, @@ -350,11 +382,15 @@ package removepackages do action :remove end +if rpms["mugit"] + ENV['PATH'] = "/usr/local/git-current/bin:"+ENV['PATH'] +end + file "initial chef-server.rb" do path "/etc/opscode/chef-server.rb" content "server_name='127.0.0.1' api_fqdn server_name nginx['server_name'] = server_name @@ -362,10 +398,11 @@ nginx['non_ssl_port'] = 81 nginx['ssl_port'] = 7443 nginx['ssl_ciphers'] = 'HIGH:MEDIUM:!LOW:!kEDH:!aNULL:!ADH:!eNULL:!EXP:!SSLv2:!SEED:!CAMELLIA:!PSK' nginx['ssl_protocols'] = 'TLSv1.2' bookshelf['external_url'] = 'https://127.0.0.1:7443' +bookshelf['vip'] = server_name bookshelf['vip_port'] = 7443\n" not_if { ::File.size?("/etc/opscode/chef-server.rb") } notifies :run, "execute[reconfigure Chef server]", :immediately end @@ -404,17 +441,75 @@ remote_file "#{MU_BASE}/bin/mu-self-update" do source "file://#{MU_BASE}/lib/bin/mu-self-update" mode 0755 end -bash "install modules for our built-in Python" do - code <<-EOH - /usr/local/python-current/bin/pip install -r #{MU_BASE}/lib/requirements.txt - EOH +# Skip this during initial installs, it's space-hungry +if !RUNNING_STANDALONE + bash "install modules for our built-in Python" do + code <<-EOH + /usr/local/python-current/bin/pip install -r #{MU_BASE}/lib/requirements.txt + EOH + end end -["/usr/local/ruby-current", "/opt/chef/embedded"].each { |rubydir| +# bundle a less heavy version of our Gemfile during initial installation, so we +# can actually fit on normal root disks until we have enough code and +# credentials to roll a dedicated /opt. +TMPDIR = Dir.mktmpdir +gemfile_dir = if RUNNING_STANDALONE and !File.readlines("/etc/mtab").grep(/\s\/opt\s/).any? + ruby_block "set up alternate install-time Gemfile" do # ~FC014 + block do + exclude_gems = %w{aws-sdk azure_sdk google-api-client} + + ["/sys/hypervisor/uuid", + "/sys/devices/virtual/dmi/id/product_uuid", + "/sys/devices/virtual/dmi/id/board_asset_tag"].each { |src| + if File.exists?(src) + uuid = File.read(src).chomp + if uuid and uuid =~ /^ec2/i + exclude_gems.delete("aws-sdk") + end + break + end + } + dmiout = shell_out!(%Q{PATH=/sbin:/usr/sbin:/bin:/usr/bin dmidecode}) + if dmiout.match(/Google/) + exclude_gems.delete("google-api-client") + end + + if File.exists?("/var/log/waagent.log") and File.read("/var/log/waagent.log") =~ /added Azure fabric/ + exclude_gems.delete("azure_sdk") + end + + f = File.open("#{TMPDIR}/cloud-mu.gemspec", "w") + File.read("#{MU_BASE}/lib/cloud-mu.gemspec").each_line { |l| + skipme = false + if l=~ /s\.add_runtime_dependency/ + exclude_gems.each { |gem| + if l =~ /\b#{gem}\b/ + skipme = true + end + } + next if skipme + end + f.puts l.chomp + } + f.close + + Dir.mkdir("#{TMPDIR}/modules") + FileUtils.cp("#{MU_BASE}/lib/modules/Gemfile", "#{TMPDIR}/modules") + end + end + "#{TMPDIR}/modules" +else + "#{MU_BASE}/lib/modules" +end + +rubies = ["/usr/local/ruby-current", "/opt/chef/embedded"] + +rubies.each { |rubydir| gembin = rubydir+"/bin/gem" gemdir = Dir.glob("#{rubydir}/lib/ruby/gems/?.?.?/gems").last bundler_path = gembin.sub(/gem$/, "bundle") bash "fix #{rubydir} gem permissions" do code <<-EOH @@ -422,23 +517,28 @@ find -P #{rubydir}/lib/ruby/gems/?.?.?/ #{rubydir}/lib/ruby/site_ruby/ -type f -exec chmod go+r {} \\; find -P #{rubydir}/bin -type f -exec chmod go+rx {} \\; EOH action :nothing end - gem_package bundler_path do + + gem_package "bundler for #{rubydir}" do gem_binary gembin package_name "bundler" if rubydir == "/usr/local/ruby-current" or File.exists?(bundler_path) action :upgrade ignore_failure true end + version "~> 2.1.4" notifies :run, "bash[fix #{rubydir} gem permissions]", :delayed end - execute "#{bundler_path} install" do - cwd "#{MU_BASE}/lib/modules" - umask 0022 - not_if "#{bundler_path} check" + execute "#{bundler_path} install from #{gemfile_dir} for #{rubydir}" do + command "PATH=/usr/local/git-current/bin:/usr/local/git-current/libexec/git-core:${PATH} #{bundler_path} install" + cwd gemfile_dir + umask "0022" + if !RUNNING_STANDALONE + not_if { system("cd #{gemfile_dir} && #{bundler_path} check 2>&1"); $?.exitstatus } + end notifies :run, "bash[fix #{rubydir} gem permissions]", :delayed notifies :restart, "service[chef-server]", :delayed if rubydir == "/opt/opscode/embedded" # XXX notify mommacat if we're *not* in chef-apply... RUNNING_STANDALONE end # Expunge old versions of knife-windows @@ -461,11 +561,11 @@ } # This is mostly to make sure Berkshelf has a clean and current environment to # live with. execute "/usr/local/ruby-current/bin/bundle clean --force" do - cwd "#{MU_BASE}/lib/modules" + cwd gemfile_dir only_if { RUNNING_STANDALONE } end # Get a 'mu' Chef org in place and populate it with artifacts directory "/root/.chef" @@ -488,33 +588,35 @@ require "simple-password-gen" # XXX this would make an awesome library execute "create mu Chef user" do command "/opt/opscode/bin/chef-server-ctl user-create mu Mu Master root@example.com #{Password.pronounceable} -f #{MU_BASE}/var/users/mu/mu.user.key" - umask 0277 + umask "0277" not_if "/opt/opscode/bin/chef-server-ctl user-list | grep '^mu$'" + notifies :start, "service[chef-server]", :before end execute "create mu Chef org" do command "/opt/opscode/bin/chef-server-ctl org-create mu mu -a mu -f #{MU_BASE}/var/orgs/mu/mu.org.key" - umask 0277 + umask "0277" not_if "/opt/opscode/bin/chef-server-ctl org-list | grep '^mu$'" + notifies :start, "service[chef-server]", :before end # TODO copy in ~/.chef/mu.*.key to /opt/mu/var/users/mu if the stuff already exists file "initial root knife.rb" do path "/root/.chef/knife.rb" content " - node_name 'mu' - client_key '#{MU_BASE}/var/users/mu/mu.user.key' - validation_client_name 'mu-validator' - validation_key '#{MU_BASE}/var/orgs/mu/mu.org.key' - chef_server_url 'https://127.0.0.1:7443/organizations/mu' - chef_server_root 'https://127.0.0.1:7443/organizations/mu' - syntax_check_cache_path '/root/.chef/syntax_check_cache' - cookbook_path [ '/root/.chef/cookbooks', '/root/.chef/site_cookbooks' ] - ssl_verify_mode :verify_none - knife[:vault_mode] = 'client' - knife[:vault_admins] = ['mu']\n" +node_name 'mu' +client_key '#{MU_BASE}/var/users/mu/mu.user.key' +validation_client_name 'mu-validator' +validation_key '#{MU_BASE}/var/orgs/mu/mu.org.key' +chef_server_url 'https://127.0.0.1:7443/organizations/mu' +chef_server_root 'https://127.0.0.1:7443/organizations/mu' +syntax_check_cache_path '/root/.chef/syntax_check_cache' +cookbook_path [ '/root/.chef/cookbooks', '/root/.chef/site_cookbooks' ] +ssl_verify_mode :verify_none +knife[:vault_mode] = 'client' +knife[:vault_admins] = ['mu']\n" only_if { !::File.size?("/root/.chef/knife.rb") } notifies :run, "execute[initial Chef artifact upload]", :immediately end @@ -528,40 +630,68 @@ if SSH_DIR != ROOT_SSH_DIR directory ROOT_SSH_DIR do mode 0700 end end -bash "add localhost ssh to authorized_keys and config" do +bash "add localhost ssh to config" do code <<-EOH - cat #{ROOT_SSH_DIR}/id_rsa.pub >> #{SSH_DIR}/authorized_keys echo "Host localhost" >> #{ROOT_SSH_DIR}/config echo " IdentityFile #{ROOT_SSH_DIR}/id_rsa" >> #{ROOT_SSH_DIR}/config EOH action :nothing end execute "ssh-keygen -N '' -f #{ROOT_SSH_DIR}/id_rsa" do - umask 0177 + umask "0177" not_if { ::File.exist?("#{ROOT_SSH_DIR}/id_rsa") } - notifies :run, "bash[add localhost ssh to authorized_keys and config]", :immediately + notifies :run, "bash[add localhost ssh to config]", :immediately + notifies :run, "execute[add localhost key to authorized_keys]", :immediately end -file "/etc/chef/client.pem" do +execute "add localhost key to authorized_keys" do + command "cat #{ROOT_SSH_DIR}/id_rsa.pub >> #{SSH_DIR}/authorized_keys" + only_if { + found = false + pubkey = if File.exists?("#{SSH_DIR}/authorized_keys") + File.read("#{ROOT_SSH_DIR}/id_rsa.pub").chomp + end + if pubkey and File.exists?("#{SSH_DIR}/authorized_keys") + authfile = File.read("#{ROOT_SSH_DIR}/authorized_keys") + authfile.each_line { |l| + if l =~ /#{Regexp.quote(pubkey)}/ + found = true + end + } + end + !found + } +end +# XXX foodcritic says this is a repeat declaration, but it's... not +file "/etc/chef/client.pem" do # ~FC005 action :nothing end file "/etc/chef/validation.pem" do action :nothing end +file "/etc/chef/client.rb" do + action :nothing +end +knife_cfg = "-c /root/.chef/knife.rb" + execute "create MU-MASTER Chef client" do +# XXX I dislike --ssh-verify-host-key=never intensely, but the CLI-documented 'accept_new' doesn't actually work if SSH_USER == "root" - command "/opt/chef/bin/knife bootstrap -N MU-MASTER --no-node-verify-api-cert --node-ssl-verify-mode=none 127.0.0.1" + command "/opt/chef/bin/knife bootstrap #{knife_cfg} -N MU-MASTER --no-node-verify-api-cert --node-ssl-verify-mode=none -U #{SSH_USER} --ssh-identity-file=/root/.ssh/id_rsa --ssh-verify-host-key=never 127.0.0.1" else - command "/opt/chef/bin/knife bootstrap -N MU-MASTER --no-node-verify-api-cert --node-ssl-verify-mode=none -x #{SSH_USER} --sudo 127.0.0.1" + command "/opt/chef/bin/knife bootstrap #{knife_cfg} -N MU-MASTER --no-node-verify-api-cert --node-ssl-verify-mode=none -U #{SSH_USER} --ssh-identity-file=/root/.ssh/id_rsa --ssh-verify-host-key=never --sudo 127.0.0.1" end - not_if "/opt/chef/bin/knife node list | grep '^MU-MASTER$'" - only_if "/opt/chef/bin/knife ssl check" # make sure we don't wipe ourselves due to unrelated SSL issues + only_if "/opt/chef/bin/knife node #{knife_cfg} list" # don't do crazy stuff just because knife isn't working + not_if "/opt/chef/bin/knife node #{knife_cfg} list | grep '^MU-MASTER$'" + notifies :run, "execute[add localhost key to authorized_keys]", :before + notifies :delete, "file[/etc/chef/client.rb]", :before notifies :delete, "file[/etc/chef/client.pem]", :before notifies :delete, "file[/etc/chef/validation.pem]", :before + notifies :start, "service[chef-server]", :before only_if { RUNNING_STANDALONE } end file "#{MU_BASE}/etc/mu.rc" do content %Q{export MU_INSTALLDIR="#{MU_BASE}" @@ -573,11 +703,11 @@ not_if { ::File.size?("#{MU_BASE}/etc/mu.rc") } end # Community cookbooks keep touching gems, and none of them are smart about our # default umask. We have to clean up after them every time. -["/usr/local/ruby-current", "/opt/chef/embedded"].each { |rubydir| +rubies.each { |rubydir| execute "trigger permission fix in #{rubydir}" do command "ls /etc/motd > /dev/null" notifies :run, "bash[fix #{rubydir} gem permissions]", :delayed end } @@ -585,6 +715,11 @@ code <<-EOH find #{MU_BASE}/lib -not -path "#{MU_BASE}/.git" -type d -exec chmod go+r {} \\; find #{MU_BASE}/lib -not -path "#{MU_BASE}/.git/*" -type f -exec chmod go+r {} \\; chmod go+rx #{MU_BASE}/lib/bin/* #{MU_BASE}/lib/extras/*-stock-* #{MU_BASE}/lib/extras/vault_tools/*.sh EOH +end + +directory TMPDIR do + action :delete + recursive true end