From f7058efad35f74148208f7dc2e2584e8c376e4bf Mon Sep 17 00:00:00 2001 From: Pat Riehecky Date: Tue, 10 Jan 2023 12:39:34 -0600 Subject: [PATCH 1/2] Add trivial `r10k` integration point. Installation and configuration of `r10k` is out of scope. This merely provides a simple way to use it with the git repo workflow. --- manifests/init.pp | 6 ++++++ manifests/params.pp | 4 ++++ manifests/server.pp | 6 ++++++ templates/server/post-receive.erb | 23 ++++++++++++++++++++++- 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/manifests/init.pp b/manifests/init.pp index e3c20204..8fcec76b 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -241,6 +241,10 @@ # # $server_git_repo_user:: Git repository user # +# $server_git_repo_r10k:: Git repository contains Puppetfile for r10k +# +# $server_git_repo_gen_types:: Generate types for environment isolation +# # $server_git_branch_map:: Git branch to puppet env mapping for the # default post receive hook # @@ -659,6 +663,8 @@ Array[String] $server_cipher_suites = $puppet::params::server_cipher_suites, Integer[0] $server_connect_timeout = $puppet::params::server_connect_timeout, Boolean $server_git_repo = $puppet::params::server_git_repo, + Boolean $server_git_repo_r10k = $puppet::params::server_git_repo_r10k, + Boolean $server_git_repo_gen_types = $puppet::params::server_git_repo_gen_types, Boolean $server_default_manifest = $puppet::params::server_default_manifest, Stdlib::Absolutepath $server_default_manifest_path = $puppet::params::server_default_manifest_path, String $server_default_manifest_content = $puppet::params::server_default_manifest_content, diff --git a/manifests/params.pp b/manifests/params.pp index 20b834b3..160b0900 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -247,6 +247,10 @@ $server_git_repo_user = $user # group of the repository $server_git_repo_group = $user + # check repositories for r10k modules + $server_git_repo_r10k = false + # generate environment specific types + $server_git_repo_gen_types = false # Override these if you need your own hooks $server_post_hook_content = 'puppet/server/post-receive.erb' $server_post_hook_name = 'post-receive' diff --git a/manifests/server.pp b/manifests/server.pp index bf4188fe..f64f5827 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -88,6 +88,10 @@ # # $git_repo_user:: Git repository user # +# $git_repo_r10k:: Git repository contains Puppetfile for r10k +# +# $git_repo_gen_types:: Generate types for environment isolation +# # $git_branch_map:: Git branch to puppet env mapping for the # default post receive hook # @@ -375,6 +379,8 @@ Integer[0] $connect_timeout = $puppet::server_connect_timeout, Integer[0] $web_idle_timeout = $puppet::server_web_idle_timeout, Boolean $git_repo = $puppet::server_git_repo, + Boolean $git_repo_r10k = $puppet::server_git_repo_r10k, + Boolean $git_repo_gen_types = $puppet::server_git_repo_gen_types, Boolean $default_manifest = $puppet::server_default_manifest, Stdlib::Absolutepath $default_manifest_path = $puppet::server_default_manifest_path, String $default_manifest_content = $puppet::server_default_manifest_content, diff --git a/templates/server/post-receive.erb b/templates/server/post-receive.erb index 1a2a9e1a..836f5c6e 100644 --- a/templates/server/post-receive.erb +++ b/templates/server/post-receive.erb @@ -100,7 +100,7 @@ $stdin.each_line do |line| Dir.chdir environment_path do_cmd("git fetch --all") do_cmd("git reset --hard 'origin/#{branchname}'") - if File.exists? "#{environment_path}/.gitmodules" + if File.exist? "#{environment_path}/.gitmodules" # ensure that we remove deleted sub modules too do_cmd("git status --short").split("\n").each do |file| # ?? old_submodule/ @@ -111,12 +111,33 @@ $stdin.each_line do |line| end do_cmd("git submodule sync") do_cmd("git submodule update --init --recursive") + <% if @git_repo_r10k -%> + if File.exist? 'Puppetfile' + puts("Installing modules using r10k") + do_cmd("r10k puppetfile install") + end + <% end -%> + <% if @git_repo_gen_types -%> + puts("Generating types for #{environment_name})" + do_cmd("puppet generate types --environmentpath #{ENVIRONMENT_BASEDIR} --environment #{environment_name}") + <% end -%> end else # Instantiate a new environment from the current repository. puts "Creating new environment #{environment_name}" do_cmd("git clone --recursive #{SOURCE_REPOSITORY} #{environment_path} --branch #{branchname}") + <% if @git_repo_r10k -%> + Dir.chdir environment_path + if File.exist? 'Puppetfile' + puts("Installing modules using r10k") + do_cmd("r10k puppetfile install") + end + <% end -%> + <% if @git_repo_gen_types -%> + puts("Generating types for #{environment_name})" + do_cmd("puppet generate types --environmentpath #{ENVIRONMENT_BASEDIR} --environment #{environment_name}") + <% end -%> end end end From cf2c0c508869e7e456f792294d56e99df08bb6a3 Mon Sep 17 00:00:00 2001 From: Pat Riehecky Date: Fri, 13 Jan 2023 13:11:00 -0600 Subject: [PATCH 2/2] Ran rubocop autofix against the script --- templates/server/post-receive.erb | 131 +++++++++++++++--------------- 1 file changed, 67 insertions(+), 64 deletions(-) mode change 100644 => 100755 templates/server/post-receive.erb diff --git a/templates/server/post-receive.erb b/templates/server/post-receive.erb old mode 100644 new mode 100755 index 836f5c6e..3ec9f369 --- a/templates/server/post-receive.erb +++ b/templates/server/post-receive.erb @@ -1,8 +1,11 @@ #!/usr/bin/env ruby +# frozen_string_literal: true + # # Managed by Puppet # +require 'English' require 'fileutils' require 'etc' @@ -10,7 +13,7 @@ $stdout.sync = true $stderr.sync = true # Set this to where you want to keep your environments -ENVIRONMENT_BASEDIR = "<%= scope.lookupvar("puppet::server::config::primary_envs_dir") %>" +ENVIRONMENT_BASEDIR = "<%= scope.lookupvar('puppet::server::config::primary_envs_dir') %>" # post-receive hooks set GIT_DIR to the current repository. If you want to # clone from a non-local repository, set this to the URL of the repository, @@ -25,7 +28,7 @@ BRANCH_MAP = { "<%= g %>" => "<%= p %>", <% end -%> <% end -%> -} +}.freeze # The git_dir environment variable will override the --git-dir, so we remove it # to allow us to create new directories cleanly. @@ -34,46 +37,46 @@ ENV.delete('GIT_DIR') # Ensure that we have the underlying directories, otherwise the later commands # may fail in somewhat cryptic manners. unless File.directory? ENVIRONMENT_BASEDIR - puts %Q{#{ENVIRONMENT_BASEDIR} does not exist, cannot create environment directories.} + puts %(#{ENVIRONMENT_BASEDIR} does not exist, cannot create environment directories.) exit 1 end # If we're running as root we change our UID to the owner of this file. -file_uid = File.stat($0).uid -if file_uid != Process.uid and Process.uid == 0 +file_uid = File.stat($PROGRAM_NAME).uid +if (file_uid != Process.uid) && Process.uid.zero? Process::UID.change_privilege(file_uid) # Set LOGNAME and HOME directories to file-owning user's values # so git can read ~/.config/git/attributes (for example) without error - file_pwuid = Etc::getpwuid(file_uid) - ENV.store('LOGNAME',file_pwuid.name) - ENV.store('HOME',file_pwuid.dir) + file_pwuid = Etc.getpwuid(file_uid) + ENV.store('LOGNAME', file_pwuid.name) + ENV.store('HOME', file_pwuid.dir) end # Run a command, return its output and abort if it fails def do_cmd(cmd) - ret = %x{#{cmd}} - if $?.exitstatus != 0 - puts("'#{cmd}' failed. Giving up.") - exit 1 - end - ret + ret = %x{#{cmd}} + if $CHILD_STATUS.exitstatus != 0 + puts("'#{cmd}' failed. Giving up.") + exit 1 + end + ret end # You can push multiple refspecs at once, like 'git push origin branch1 branch2', # so we need to handle each one. -$stdin.each_line do |line| - oldrev, newrev, refname = line.split(" ") +$stdin.each_line do |line| # rubocop:disable Metrics/BlockLength + _oldrev, newrev, refname = line.split(' ') # Determine the branch name from the refspec we're received, which is in the # format refs/heads/, and make sure that it doesn't have any possibly # dangerous characters - branchname = refname.sub(%r{^refs/heads/(.*$)}) { $1 } - if branchname =~ /[\W]/ - puts %Q{Branch "#{branchname}" contains non-word characters, ignoring it.} + branchname = refname.sub(%r{^refs/heads/(.*$)}) { Regexp.last_match(1) } + if branchname =~ /\W/ + puts %(Branch "#{branchname}" contains non-word characters, ignoring it.) next end - if BRANCH_MAP[branchname] != nil + if !BRANCH_MAP[branchname].nil? environment_name = BRANCH_MAP[branchname] environment_path = "#{ENVIRONMENT_BASEDIR}/#{BRANCH_MAP[branchname]}" else @@ -81,63 +84,63 @@ $stdin.each_line do |line| environment_path = "#{ENVIRONMENT_BASEDIR}/#{branchname}" end + # Perform one of these operations: + # - delete + # - update + # - create if newrev =~ /^0+$/ # We've received a push with a null revision, something like 000000000000, # which means that we should delete the given branch. puts "Deleting existing environment #{environment_name}" - if File.directory? environment_path - FileUtils.rm_rf environment_path, :secure => true - end - else - # We have been given a branch that needs to be created or updated. If the - # environment exists, update it. Else, create it. - - if File.directory? environment_path - # Update an existing environment. We do a fetch and then reset in the - # case that someone did a force push to a branch. - - puts "Updating existing environment #{environment_name}" - Dir.chdir environment_path - do_cmd("git fetch --all") - do_cmd("git reset --hard 'origin/#{branchname}'") - if File.exist? "#{environment_path}/.gitmodules" - # ensure that we remove deleted sub modules too - do_cmd("git status --short").split("\n").each do |file| - # ?? old_submodule/ - if file =~ /\s*\?{2}\s*(\S*)/ - puts "Found a few unknown files.. deleting #{$1}" - FileUtils.rm_rf $1, :secure => true - end - end - do_cmd("git submodule sync") - do_cmd("git submodule update --init --recursive") - <% if @git_repo_r10k -%> - if File.exist? 'Puppetfile' - puts("Installing modules using r10k") - do_cmd("r10k puppetfile install") + FileUtils.rm_rf environment_path, secure: true if File.directory? environment_path + elsif File.directory? environment_path + # Update an existing environment. We do a fetch and then reset in the + # case that someone did a force push to a branch. + # We have been given a branch that needs to be updated. + + puts "Updating existing environment #{environment_name}" + Dir.chdir environment_path + do_cmd('git fetch --all') + do_cmd("git reset --hard 'origin/#{branchname}'") + if File.exist? "#{environment_path}/.gitmodules" + # ensure that we remove deleted sub modules too + do_cmd('git status --short').split("\n").each do |file| + # ?? old_submodule/ + if file =~ /\s*\?{2}\s*(\S*)/ + puts "Found a few unknown files.. deleting #{Regexp.last_match(1)}" + FileUtils.rm_rf Regexp.last_match(1), secure: true end - <% end -%> - <% if @git_repo_gen_types -%> - puts("Generating types for #{environment_name})" - do_cmd("puppet generate types --environmentpath #{ENVIRONMENT_BASEDIR} --environment #{environment_name}") - <% end -%> end - else - # Instantiate a new environment from the current repository. - - puts "Creating new environment #{environment_name}" - do_cmd("git clone --recursive #{SOURCE_REPOSITORY} #{environment_path} --branch #{branchname}") + do_cmd('git submodule sync') + do_cmd('git submodule update --init --recursive') <% if @git_repo_r10k -%> - Dir.chdir environment_path if File.exist? 'Puppetfile' - puts("Installing modules using r10k") - do_cmd("r10k puppetfile install") + puts('Installing modules using r10k') + do_cmd('r10k puppetfile install') end <% end -%> <% if @git_repo_gen_types -%> - puts("Generating types for #{environment_name})" + puts("Generating types for #{environment_name}") do_cmd("puppet generate types --environmentpath #{ENVIRONMENT_BASEDIR} --environment #{environment_name}") <% end -%> end + + else + # Instantiate a new environment from the current repository. + # We have been given a new branch that needs to be created + + puts "Creating new environment #{environment_name}" + do_cmd("git clone --recursive #{SOURCE_REPOSITORY} #{environment_path} --branch #{branchname}") + Dir.chdir environment_path + <% if @git_repo_r10k -%> + if File.exist? 'Puppetfile' + puts('Installing modules using r10k') + do_cmd('r10k puppetfile install') + end + <% end -%> + <% if @git_repo_gen_types -%> + puts("Generating types for #{environment_name}") + do_cmd("puppet generate types --environmentpath #{ENVIRONMENT_BASEDIR} --environment #{environment_name}") + <% end -%> end end