Please review pull request #428: Feature/2.7.x/12066 windows puppet facter build opened by (jeffmccune)
Description:
This is Milestone #2 FTW.
- Opened: Tue Jan 31 02:14:10 UTC 2012
- Based on: puppetlabs:2.7.x (309c09c44fb747e922917a9306909cc6f35e10f6)
- Requested merge: jeffmccune:feature/2.7.x/12066_windows_puppet_facter_build (2a5f956573e9c656d8a68386bf35e8fd9c1a4f14)
Diff follows:
diff --git a/README_DEVELOPER.md b/README_DEVELOPER.md
index f38067a..e8b784f 100644
--- a/README_DEVELOPER.md
+++ b/README_DEVELOPER.md
@@ -95,4 +95,31 @@ building MSI packages of Puppet for Windows. Please see also
[#11205](http://projects.puppetlabs.com/issues/11205) for up to date progress
on this project.
+To build a specific version:
+
+ rake windows:checkout[refs/tags/2.7.10,refs/tags/1.6.4]
+ rake clean
+ rake windows:build
+
+To build a specific integration branch:
+
+ rake windows:checkout[refs/remotes/origin/2.7.x,refs/remotes/origin/1.6.x]
+ rake clean
+ rake windows:build
+
+To build from some other repository:
+
+ rake clobber
+ rake windows:clone[git://github.com/jeffmccune/puppet.git]
+ rake windows:checkout[refs/remotes/origin/feature/2.7.x/12066_myfeature]
+ rake clean
+ rake windows:build
+
+Note that the `downloads` directory is treated as a cache of sorts. The
+version of Puppet and Facter checked out in the downloads directory will be
+copied into the staging directory and rolled into the MSI package. The build
+task will not check out a different version but the checkout task will. If a
+specific set of versions are to be built, I recommend using the checkout task
+to stage the appropriate version in the next build task.
+
EOF
diff --git a/Rakefile b/Rakefile
index e59d20a..362b29e 100644
--- a/Rakefile
+++ b/Rakefile
@@ -4,7 +4,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), 'tasks')
require 'rake'
require 'rake/packagetask'
-require 'rake/gempackagetask'
+require 'rubygems/package_task'
require 'rspec'
require "rspec/core/rake_task"
diff --git a/conf/windows/stagedir/bin/facter.bat b/conf/windows/stagedir/bin/facter.bat
new file mode 100644
index 0000000..9924ff4
--- /dev/null
+++ b/conf/windows/stagedir/bin/facter.bat
@@ -0,0 +1,23 @@
+@echo off
+SETLOCAL
+
+REM This is the parent directory of the directory containing this script.
+SET PL_BASEDIR=%~dp0..
+
+REM Avoid the nasty \..\ littering the paths.
+SET PL_BASEDIR=%PL_BASEDIR:\bin\..=%
+
+SET PUPPET_DIR=%PL_BASEDIR%\puppet
+SET FACTER_DIR=%PL_BASEDIR%\facter
+
+SET PATH=%PUPPET_DIR%\bin;%FACTER_DIR%\bin;%PL_BASEDIR%\bin;%PL_BASEDIR%\sys\ruby\bin;%PATH%
+
+REM Set the RUBY LOAD_PATH using the RUBYLIB environment variable
+SET RUBYLIB=%PUPPET_DIR%\lib;%FACTER_DIR%\lib;%RUBYLIB%
+
+REM Translate all slashes to / style to avoid issue #11930
+SET RUBYLIB=%RUBYLIB:\=/%
+
+REM %0 will be the subcommand, agent, apply, resource, etc...
+REM %* will be the positional arguments passed to this script.
+ruby -S -- %0 %*
diff --git a/conf/windows/stagedir/bin/puppet.bat b/conf/windows/stagedir/bin/puppet.bat
new file mode 100644
index 0000000..9924ff4
--- /dev/null
+++ b/conf/windows/stagedir/bin/puppet.bat
@@ -0,0 +1,23 @@
+@echo off
+SETLOCAL
+
+REM This is the parent directory of the directory containing this script.
+SET PL_BASEDIR=%~dp0..
+
+REM Avoid the nasty \..\ littering the paths.
+SET PL_BASEDIR=%PL_BASEDIR:\bin\..=%
+
+SET PUPPET_DIR=%PL_BASEDIR%\puppet
+SET FACTER_DIR=%PL_BASEDIR%\facter
+
+SET PATH=%PUPPET_DIR%\bin;%FACTER_DIR%\bin;%PL_BASEDIR%\bin;%PL_BASEDIR%\sys\ruby\bin;%PATH%
+
+REM Set the RUBY LOAD_PATH using the RUBYLIB environment variable
+SET RUBYLIB=%PUPPET_DIR%\lib;%FACTER_DIR%\lib;%RUBYLIB%
+
+REM Translate all slashes to / style to avoid issue #11930
+SET RUBYLIB=%RUBYLIB:\=/%
+
+REM %0 will be the subcommand, agent, apply, resource, etc...
+REM %* will be the positional arguments passed to this script.
+ruby -S -- %0 %*
diff --git a/install.rb b/install.rb
index 4f84692..830631c 100755
--- a/install.rb
+++ b/install.rb
@@ -44,6 +44,7 @@
end
require 'optparse'
require 'ostruct'
+require 'tempfile'
begin
require 'rdoc/rdoc'
@@ -420,22 +421,19 @@ def install_binfile(from, op_file, target)
installed_wrapper = true
end
- if not installed_wrapper
- tmp_file2 = File.join(tmp_dir, '_tmp_wrapper')
- cwv = <<-EOS
-@echo off
-setlocal
-set RUBY_BIN=%~dp0
-set RUBY_BIN=%RUBY_BIN:\\=/%
-"%RUBY_BIN%ruby.exe" -x "%RUBY_BIN%puppet" %*
-EOS
- File.open(tmp_file2, "w") { |cw| cw.puts cwv }
- FileUtils.install(tmp_file2, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
-
- File.unlink(tmp_file2)
+ if not installed_wrapper then
+ Tempfile.open([op_file, '.bat']) do |output|
+ File.open(File.join(File.dirname(__FILE__), "conf/windows/stagedir/bin/#{op_file}.bat"), 'r') do |input|
+ output.write input.read
+ end
+ # Flush the buffered writes before installing the file.
+ output.close
+ FileUtils.install(output.path, File.join(target, "#{op_file}.bat"), :mode => 0755, :verbose => true)
+ end
installed_wrapper = true
end
end
+
FileUtils.install(tmp_file, File.join(target, op_file), :mode => 0755, :verbose => true)
File.unlink(tmp_file)
end
diff --git a/tasks/windows/stagedir/etc/puppet/puppet.conf b/tasks/windows/stagedir/etc/puppet/puppet.conf
new file mode 100644
index 0000000..5152442
--- /dev/null
+++ b/tasks/windows/stagedir/etc/puppet/puppet.conf
@@ -0,0 +1,5 @@
+# Basic puppet.conf
+[main]
+ server = puppetmaster
+ report = true
+ pluginsync = true
diff --git a/tasks/windows/windows.rake b/tasks/windows/windows.rake
index ed554bc..aff55f4 100644
--- a/tasks/windows/windows.rake
+++ b/tasks/windows/windows.rake
@@ -32,6 +32,10 @@ def heat(wxs_file, stage_dir)
Dir.chdir TOPDIR do
cg_name = File.basename(wxs_file.ext(''))
dir_ref = File.basename(File.dirname(stage_dir))
+ # NOTE: The reference specified using the -dr flag MUST exist in the
+ # parent puppet.wxs file. Otherwise, WiX won't be able to graft the
+ # fragment into the right place in the package.
+ dir_ref = 'INSTALLDIR' if dir_ref == 'stagedir'
sh "heat dir #{stage_dir} -v -ke -indent 2 -cg #{cg_name} -gg -dr #{dir_ref} -var var.StageDir -out #{wxs_file}"
end
end
@@ -57,7 +61,6 @@ CLEAN.include('wix/**/*.wixobj')
CLEAN.include('pkg/*')
namespace :windows do
-
# These are file tasks that behave like mkdir -p
directory 'pkg'
directory 'downloads'
@@ -71,17 +74,76 @@ namespace :windows do
# These translate to ZIP files we'll download
# FEATURES = %w{ ruby git wix misc }
FEATURES = %w{ ruby }
+ # These are the applications we're packaging from VCS source
+ APPS = %w{ facter puppet }
+ # Thse are the pre-compiled things we need to stage and include in
+ # the packages
DOWNLOADS = FEATURES.collect { |fn| File.join("downloads", fn.ext('zip')) }
- # There is a 1:1 mapping between a wxs file and a wixobj file
+ # We do this to provide a cache of sorts, allowing rake clean to clean but
+ # preventing the build tasks from having to re-clone all of puppet and facter
+ # which usually takes ~ 3 minutes.
+ GITREPOS = APPS.collect { |fn| File.join("downloads", fn.ext('')) }
+
+ # These are the VCS repositories checked out into downloads.
+ # For example, downloads/puppet and downloads/facter
+ GITREPOS.each do |repo|
+ file repo, [:uri] => ['downloads'] do |t, args|
+ args.with_defaults(:uri => "git://github.com/puppetlabs/#{File.basename(t.name).ext('.git')}")
+ Dir.chdir File.dirname(t.name) do
+ sh "git clone #{args[:uri]} #{File.basename(t.name)}"
+ end
+ end
+
+ # These tasks are not meant to be executed every build They're meant to
+ # provide the means to checkout the reference we want prior to running the
+ # build. See the windows:checkout task for more information
+ task "checkout.#{File.basename(repo.ext(''))}", [:ref] => [repo] do |t, args|
+ repo_dir = t.name.gsub(/^.*?checkout\./, 'downloads/')
+ args.with_defaults(:ref => 'refs/remotes/origin/master')
+ Dir.chdir repo_dir do
+ sh 'git fetch origin'
+ sh 'git fetch origin --tags'
+ # We explicitly avoid using git clean -x because we rely on rake clean
+ # to clean up build artifacts. Specifically, we don't want to clone
+ # and download zip files every single build
+ sh 'git clean -f -d'
+ sh "git checkout -f #{args[:ref]}"
+ end
+ end
+ end
- # These files should be committed to VCS
+ # There is a 1:1 mapping between a wxs file and a wixobj file
+ # The wxs files in the top level of wix/ should be committed to VCS
WXSFILES = FileList['wix/*.wxs']
+ # WXS Fragments could have different types of sources and are generated
+ # during the build process by heat.exe
+ WXS_FRAGMENTS_HASH = {
+ 'ruby' => { :src ="" 'stagedir/sys/ruby' },
+ 'puppet' => { :src ="" 'stagedir/puppet' },
+ 'facter' => { :src ="" 'stagedir/facter' },
+ }
+
+ # Additional directories to stage as fragments automatically.
+ # conf/windows/stagedir/bin/ for example.
+ FileList[File.join(TOPDIR, 'conf', 'windows', 'stagedir', '*')].each do |fn|
+ my_topdir = File.basename(fn)
+ WXS_FRAGMENTS_HASH[my_topdir] = { :src ="" "stagedir/#{my_topdir}" }
+ file "stagedir/#{my_topdir}" => ["stagedir"] do |t|
+ src = "" 'conf', 'windows', t.name)
+ dst = t.name
+ FileUtils.cp_r src, dst
+ end
+ task :stage => ["stagedir/#{my_topdir}"]
+ end
+
+
# These files should be auto-generated by heat
- WXSFRAGMENTS = FEATURES.collect { |fn| File.join("wix", "fragments", fn.ext('wxs')) }
+ WXS_FRAGMENTS = WXS_FRAGMENTS_HASH.keys.collect do |fn|
+ File.join("wix", "fragments", fn.ext('wxs'))
+ end
# All of the objects we need to create
- WIXOBJS = (WXSFILES + WXSFRAGMENTS).ext('wixobj')
-
+ WIXOBJS = (WXSFILES + WXS_FRAGMENTS).ext('wixobj')
# These directories should be unpacked into stagedir/sys
SYSTOOLS = FEATURES.collect { |fn| File.join("stagedir", "sys", fn) }
@@ -97,8 +159,30 @@ namespace :windows do
desc "Download example"
task :download => DOWNLOADS
- desc "Unzip and stage sys tools"
- task :unzip => SYSTOOLS
+ # Note, other tasks may append themselves as necessary for the stage task.
+ desc "Stage everything to be built"
+ task :stage => SYSTOOLS
+
+ desc "Clone upstream repositories"
+ task :clone, [:puppet_uri, :facter_uri] => ['downloads'] do |t, args|
+ baseuri = "git://github.com/puppetlabs"
+ args.with_defaults(:puppet_uri => "#{baseuri}/puppet.git",
+ :facter_uri => "#{baseuri}/facter.git")
+ Rake::Task["downloads/puppet"].invoke(args[:puppet_uri])
+ Rake::Task["downloads/facter"].invoke(args[:facter_uri])
+ end
+
+ desc "Checkout app repositories to a specific ref"
+ task :checkout, [:puppet_ref, :facter_ref] => [:clone] do |t, args|
+ # args.with_defaults(:puppet_ref => 'refs/remotes/origin/2.7.x',
+ # :facter_ref => 'refs/remotes/origin/1.6.x')
+ args.with_defaults(:puppet_ref => 'refs/tags/2.7.9',
+ :facter_ref => 'refs/tags/1.6.4')
+ # This is an example of how to invoke other tasks that take parameters from
+ # a task that takes parameters.
+ Rake::Task["windows:checkout.facter"].invoke(args[:facter_ref])
+ Rake::Task["windows:checkout.puppet"].invoke(args[:puppet_ref])
+ end
desc "List available rake tasks"
task :help do
@@ -128,21 +212,33 @@ namespace :windows do
end
WIXOBJS.each do |wixobj|
- stagedir = File.join(TOPDIR, 'stagedir', 'sys')
+ source_dir = WXS_FRAGMENTS_HASH[File.basename(wixobj.ext(''))][:src]
file wixobj => [ wixobj.ext('wxs'), File.dirname(wixobj) ] do |t|
- candle t.name.ext('wxs'), File.join(stagedir, File.basename(t.name.ext(''))).gsub('/', File::SEPARATOR)
+ candle(t.name.ext('wxs'), source_dir)
end
end
- WXSFRAGMENTS.each do |wxs_frag|
- source_dir = File.join('stagedir', 'sys', File.basename(wxs_frag).ext(''))
+ WXS_FRAGMENTS.each do |wxs_frag|
+ source_dir = WXS_FRAGMENTS_HASH[File.basename(wxs_frag.ext(''))][:src]
file wxs_frag => [ source_dir, File.dirname(wxs_frag) ] do |t|
- heat t.name, source_dir
+ heat(t.name, source_dir)
end
end
- ####### REVISIT
+ # We stage whatever is checked out using the checkout parameterized task.
+ APPS.each do |app|
+ file "stagedir/#{app}" => ['stagedir', "downloads/#{app}"] do |t|
+ my_app = File.basename(t.name.ext(''))
+ puts "Copying downloads/#{my_app} to #{t.name} ..."
+ FileUtils.mkdir_p t.name
+ # This avoids copying hidden files like .gitignore and .git
+ FileUtils.cp_r FileList["downloads/#{my_app}/*"], t.name
+ end
+ # The stage task needs these directories to be in place.
+ task :stage => ["stagedir/#{app}"]
+ end
+ ####### REVISIT
file 'pkg/puppet.msi' => WIXOBJS do |t|
sh "light #{t.prerequisites.join(' ')} -out #{t.name}"
end
diff --git a/wix/puppet.wxs b/wix/puppet.wxs
index 48e8012..c3ff2c6 100644
--- a/wix/puppet.wxs
+++ b/wix/puppet.wxs
@@ -51,9 +51,11 @@
-->
<Feature Id="$(var.OurProductNameWord)Runtime" Title="$(var.OurProductName) Runtime" Level="1">
<ComponentGroupRef Id="ruby" />
- <!-- NOT YET IMPLEMENTED
<ComponentGroupRef Id="puppet" />
<ComponentGroupRef Id="facter" />
+ <ComponentGroupRef Id="bin" />
+ <!-- We may not need an etc directory out of the box.
+ <ComponentGroupRef Id="etc" />
-->
</Feature>
-- You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to [email protected].
For more options, visit this group at http://groups.google.com/group/puppet-dev?hl=en.
