Please review pull request #428: Feature/2.7.x/12066 windows puppet facter build opened by (jeffmccune)

Description:

This is Milestone #2 FTW.

You Win the Internet

  • 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.

Reply via email to