Merge tag 'upstream/1.6.10'
Upstream version 1.6.10
Stig Sandbeck Mathisen
11 years ago
0 | Autotest.add_discovery { "rspec2" } | |
1 | ||
2 | Autotest.add_hook :initialize do |at| | |
3 | at.clear_mappings | |
4 | ||
5 | # the libraries under lib/facter | |
6 | at.add_mapping(%r%^lib/facter/(.*)\.rb$%) { |filename, m| | |
7 | at.files_matching %r!spec/(unit|integration)/#{m[1]}.rb! | |
8 | } | |
9 | ||
10 | # the actual spec files themselves | |
11 | at.add_mapping(%r%^spec/(unit|integration)/.*\.rb$%) { |filename, _| | |
12 | filename | |
13 | } | |
14 | ||
15 | # force a complete re-run for all of these: | |
16 | ||
17 | # main facter lib | |
18 | at.add_mapping(%r!^lib/facter\.rb$!) { |filename, _| | |
19 | at.files_matching %r!spec/(unit|integration)/.*\.rb! | |
20 | } | |
21 | ||
22 | # the spec_helper | |
23 | at.add_mapping(%r!^spec/spec_helper\.rb$!) { |filename, _| | |
24 | at.files_matching %r!spec/(unit|integration)/.*\.rb! | |
25 | } | |
26 | ||
27 | # the facter spec libraries | |
28 | at.add_mapping(%r!^spec/lib/spec.*!) { |filename, _| | |
29 | at.files_matching %r!spec/(unit|integration)/.*\.rb! | |
30 | } | |
31 | ||
32 | # the monkey patches for rspec | |
33 | at.add_mapping(%r!^spec/lib/monkey_patches/.*!) { |filename, _| | |
34 | at.files_matching %r!spec/(unit|integration)/.*\.rb! | |
35 | } | |
36 | end |
0 | 1.6.10 | |
1 | === | |
2 | 35067dc Bump Facter epoch to 1 | |
3 | d6a3e91 Make package task depend on tar in Rakfile | |
4 | f42896d (#14764) Stub architecture fact when Windows facts run on Linux | |
5 | f44ca52 (maint) Fix hardware model fact for ruby 1.9 | |
6 | 964d1f0 (#12864) Close registry key | |
7 | ab025bb Revert "Revert "(#12864) Windows: get primary DNS from registry"" | |
8 | 478386d (#10261) Detect x64 architecture on Windows | |
9 | 6cc881d Use git describe in Rakefile to determine pkg ver | |
10 | 2043244 (#13678) Remove deprecation msg triggerd by the ipaddress6 fact | |
11 | d118d81 (#13678) Add filename extension on absolute paths on windows | |
12 | b050eb1 (#14582) Fix noise in LSB facts | |
13 | 85654b0 (#13678) Allow passing shell built-ins to exec method on windows | |
14 | 8f4c016 (#13678) Single quote paths on unix with spaces | |
15 | 2d164e8 (#13678) Join PATHs correctly on windows | |
16 | e7e7e8f (#13678) Extend spec tests for expand_command | |
17 | 0fea7b0 maint: Add shared context for specs to imitate windows or posix | |
18 | 60d0cd2 (#13678) Fix spec failures on windows | |
19 | 121a2ab (#13678) Fix quoting in expand_command | |
20 | 55b1125 (#13678) Add more unit tests for new methods | |
21 | 9086c0a (#13678) Add RDoc documentation for new methods | |
22 | 165ace4 (#13678) Convert command to absolute paths before executing | |
23 | ||
0 | 24 | 1.6.9 |
1 | 25 | === |
2 | 26 | b398bd8 (#14334) Fix dmidecode based facts on DragonFly BSD |
16 | 16 | require 'rake/packagetask' |
17 | 17 | require 'rake/gempackagetask' |
18 | 18 | |
19 | module Facter | |
20 | FACTERVERSION = File.read('lib/facter.rb')[/FACTERVERSION *= *'(.*)'/,1] or fail "Couldn't find FACTERVERSION" | |
21 | end | |
22 | ||
23 | 19 | FILES = FileList[ |
24 | 20 | '[A-Z]*', |
25 | 21 | 'install.rb', |
30 | 26 | 'spec/**/*' |
31 | 27 | ] |
32 | 28 | |
29 | def get_version | |
30 | `git describe`.strip | |
31 | end | |
32 | ||
33 | # :build_environment and :tar are mostly borrowed from puppet-dashboard Rakefile | |
34 | task :build_environment do | |
35 | unless ENV['FORCE'] == '1' | |
36 | modified = `git status --porcelain | sed -e '/^\?/d'` | |
37 | if modified.split(/\n/).length != 0 | |
38 | puts <<-HERE | |
39 | !! ERROR: Your git working directory is not clean. You must | |
40 | !! remove or commit your changes before you can create a package: | |
41 | ||
42 | #{`git status | grep '^#'`.chomp} | |
43 | ||
44 | !! To override this check, set FORCE=1 -- e.g. `rake package:deb FORCE=1` | |
45 | HERE | |
46 | raise | |
47 | end | |
48 | end | |
49 | end | |
50 | ||
51 | desc "Create a release .tar.gz" | |
52 | task :tar => :build_environment do | |
53 | name = "facter" | |
54 | rm_rf 'pkg/tar' | |
55 | temp=`mktemp -d -t tmpXXXXXX`.strip! | |
56 | version = get_version | |
57 | base = "#{temp}/#{name}-#{version}/" | |
58 | mkdir_p base | |
59 | sh "git checkout-index -af --prefix=#{base}" | |
60 | mkdir_p "pkg/tar" | |
61 | sh "tar -C #{temp} -pczf #{temp}/#{name}-#{version}.tar.gz #{name}-#{version}" | |
62 | mv "#{temp}/#{name}-#{version}.tar.gz", "pkg/tar" | |
63 | rm_rf temp | |
64 | puts "Tarball is pkg/tar/#{name}-#{version}.tar.gz" | |
65 | end | |
66 | ||
33 | 67 | spec = Gem::Specification.new do |spec| |
34 | 68 | spec.platform = Gem::Platform::RUBY |
35 | 69 | spec.name = 'facter' |
36 | 70 | spec.files = FILES.to_a |
37 | 71 | spec.executables = %w{facter} |
38 | spec.version = Facter::FACTERVERSION | |
72 | spec.version = get_version.split('-')[0] | |
39 | 73 | spec.summary = 'Facter, a system inventory tool' |
40 | 74 | spec.description = 'You can prove anything with facts!' |
41 | 75 | spec.author = 'Puppet Labs' |
48 | 82 | '--main' << 'README' << |
49 | 83 | '--line-numbers' |
50 | 84 | end |
51 | ||
52 | Rake::PackageTask.new("facter", Facter::FACTERVERSION) do |pkg| | |
53 | pkg.package_dir = 'pkg' | |
54 | pkg.need_tar_gz = true | |
55 | pkg.package_files = FILES.to_a | |
85 | Rake::GemPackageTask.new(spec) do |pkg| | |
56 | 86 | end |
57 | 87 | |
58 | Rake::GemPackageTask.new(spec) do |pkg| | |
59 | end | |
88 | task :package => :tar | |
60 | 89 | |
61 | 90 | task :default do |
62 | 91 | sh %{rake -T} |
0 | test_name "#7670: Facter should properly detect operatingsystem on Ubuntu after a clear" | |
1 | ||
2 | script_contents = <<-OS_DETECT | |
3 | require 'facter' | |
4 | Facter['operatingsystem'].value | |
5 | Facter.clear | |
6 | exit Facter['operatingsystem'].value == 'Ubuntu' | |
7 | OS_DETECT | |
8 | ||
9 | script_name = "/tmp/facter_os_detection_test_#{$$}" | |
10 | ||
11 | agents.each do |agent| | |
12 | next unless agent['platform'].include? 'ubuntu' | |
13 | ||
14 | create_remote_file(agent, script_name, script_contents) | |
15 | ||
16 | on(agent, "ruby #{script_name}") | |
17 | end |
0 | test_name "#7039: Facter having issue handling multiple facts in a single file" | |
1 | ||
2 | fact_file= %q{ | |
3 | Facter.add(:test_fact1) do | |
4 | setcode do | |
5 | "test fact 1" | |
6 | end | |
7 | end | |
8 | ||
9 | Facter.add(:test_fact2) do | |
10 | setcode do | |
11 | "test fact 2" | |
12 | end | |
13 | end | |
14 | } | |
15 | ||
16 | agent1=agents.first | |
17 | step "Agent: Create fact file with multiple facts" | |
18 | create_remote_file(agent1, '/tmp/test_facts.rb', fact_file ) | |
19 | ||
20 | step "Agent: Verify test_fact1 from /tmp/test_facts.rb" | |
21 | on(agent1, "export FACTERLIB=/tmp && facter --puppet test_fact1") do | |
22 | fail_test "Fact 1 not returned by facter --puppet test_fact1" unless | |
23 | stdout.include? 'test fact 1' | |
24 | end | |
25 | ||
26 | step "Agent: Verify test_fact2 from /tmp/test_facts.rb" | |
27 | on(agent1, "export FACTERLIB=/tmp && facter --puppet test_fact2") do | |
28 | fail_test "Fact 1 not returned by facter --puppet test_fact2" unless | |
29 | stdout.include? 'test fact 2' | |
30 | end |
1 | 1 | |
2 | 2 | Summary: Ruby module for collecting simple facts about a host operating system |
3 | 3 | Name: facter |
4 | Version: 1.6.9 | |
4 | Version: 1.6.10 | |
5 | 5 | Release: 1%{?dist} |
6 | #Release: 0.1rc1%{?dist} | |
6 | #Release: 0.1rc1.2%{?dist} | |
7 | Epoch: 1 | |
7 | 8 | License: Apache 2.0 |
8 | 9 | Group: System Environment/Base |
9 | 10 | URL: http://www.puppetlabs.com/puppet/related-projects/%{name} |
52 | 53 | |
53 | 54 | |
54 | 55 | %changelog |
56 | * Wed Jun 13 2012 Moses Mendoza <moses@puppetlabs.com> - 1.6.10-1 | |
57 | - Update for 1.6.10 | |
58 | ||
59 | * Fri Jun 8 2012 Moses Mendoza <moses@puppetlabs.com> - 1.6.10-0.1rc1.2 | |
60 | - Bump epoch to 1 to address errant Facter 2.0 rc release | |
61 | ||
62 | * Wed Jun 6 2012 Moses Mendoza <moses@puppetlabs.com> - 1.6.10-0.1rc1 | |
63 | - Update for 1.6.10rc1 | |
64 | ||
55 | 65 | * Thu May 17 2012 Moses Mendoza <moses@puppetlabs.com> - 1.6.9-1 |
56 | 66 | - Update for 1.6.9 |
57 | 67 |
0 | --- | |
1 | inMenu: true | |
2 | directoryName: Custom Facts | |
3 | --- | |
4 | ||
5 | Facter does everything it can to make adding custom facts easy. It will | |
6 | autoload any files it finds in a ``facter/`` directory in its search | |
7 | path, so you don't need to modify the package files. Also, Facter will | |
8 | search through your environment for any variables whose names start with | |
9 | 'FACTER_' (case insensitive) and automatically add those facts. | |
10 | ||
11 | As a simple example, here is how I publish my home directory to Puppet: | |
12 | ||
13 | Facter.add("home") do | |
14 | setcode do | |
15 | ENV['HOME'] | |
16 | end | |
17 | end | |
18 | ||
19 | I have ~/lib/ruby in my $RUBYLIB environment variable, so I just created | |
20 | ~/lib/ruby/facter and dropped the above code into a ``home.rb`` file | |
21 | within that directory. |
0 | --- | |
1 | inMenu: false | |
2 | directoryName: Facter | |
3 | --- | |
4 | ||
5 | A cross-platform Ruby library for retrieving facts from operating systems. | |
6 | Supports multiple resolution mechanisms, any of which can be restricted to | |
7 | working only on certain operating systems or environments. Facter is especially | |
8 | useful for retrieving things like operating system names, IP addresses, MAC | |
9 | addresses, and SSH keys. | |
10 | ||
11 | It is easy to extend Facter to include your own [custom facts](custom.html) or | |
12 | to include additional mechanisms for retrieving facts. | |
13 | ||
14 | * [Downloads](/downloads/facter/) | |
15 | * [Bug Tracking](/cgi-bin/facter.cgi) | |
16 | * [API Documentation](/downloads/facter/apidocs/) | |
17 | ||
18 | *$Id$* |
0 | ||
1 | #!/usr/bin/env sh | |
2 | # | |
3 | # Output the difference between a facter command run on two different versions | |
4 | # of facter. Uses unified diff format. | |
5 | ||
6 | OPTIONS_SPEC="\ | |
7 | facter-diff [options] <rev1> <rev2> [fact]... | |
8 | ||
9 | Example: | |
10 | ||
11 | ./ext/facter-diff 1.5.7 1.0.2 | |
12 | ||
13 | -- | |
14 | h,help Display this help" | |
15 | ||
16 | . "$(git --exec-path)/git-sh-setup" | |
17 | eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)" | |
18 | trap 'err=$?; cleanup; exit $err' 0 | |
19 | ||
20 | cleanup() { | |
21 | test $origin && git checkout -q "$origin" | |
22 | } | |
23 | ||
24 | facter() { | |
25 | ruby -Ilib bin/facter "$@" | |
26 | } | |
27 | ||
28 | log_facter_run() { | |
29 | local ref=$1 && shift | |
30 | local tmpfile=$1 && shift | |
31 | ||
32 | git checkout -qf "$ref" || | |
33 | die "fatal: unable to checkout $ref" | |
34 | facter "$@" > $tmpfile | |
35 | } | |
36 | ||
37 | verify_revision() { | |
38 | git rev-parse --verify --quiet "$1" > /dev/null || | |
39 | die "fatal: '$1' is not a valid revision" | |
40 | } | |
41 | ||
42 | test $1 = "--" && shift # git rev-parse seems to leave the -- in | |
43 | test $# -eq 0 && usage | |
44 | ||
45 | test $# -gt 1 || | |
46 | die "fatal: must specify two revisions" | |
47 | ||
48 | status=$(git status -s) | |
49 | test -z "$status" || | |
50 | die "fatal: $0 cannot be used with a dirty working copy" | |
51 | ||
52 | origin=$(git rev-parse --symbolic-full-name HEAD) | |
53 | test "$origin" = "HEAD" && | |
54 | origin=$(git rev-parse HEAD) | |
55 | ||
56 | test -x "bin/facter" || | |
57 | die "fatal: $0 must be run from the project root" | |
58 | ||
59 | ref1="$1" && shift | |
60 | ref2="$1" && shift | |
61 | ||
62 | verify_revision $ref1 | |
63 | verify_revision $ref2 | |
64 | ||
65 | tmpfile1="/tmp/$(basename $0).$$.1.tmp" | |
66 | tmpfile2="/tmp/$(basename $0).$$.2.tmp" | |
67 | ||
68 | log_facter_run $ref1 $tmpfile1 $@ | |
69 | log_facter_run $ref2 $tmpfile2 $@ | |
70 | ||
71 | git checkout -f "$origin" > /dev/null 2>&1 | |
72 | ||
73 | diff --label "$ref1" --label "$ref2" -u $tmpfile1 $tmpfile2 |
24 | 24 | end |
25 | 25 | when /(i[3456]86|pentium)/ |
26 | 26 | case Facter.value(:operatingsystem) |
27 | when "Gentoo" | |
27 | when "Gentoo", "windows" | |
28 | 28 | "x86" |
29 | 29 | else |
30 | 30 | "i386" |
51 | 51 | Facter.add(:domain) do |
52 | 52 | confine :kernel => :windows |
53 | 53 | setcode do |
54 | require 'facter/util/wmi' | |
54 | require 'facter/util/registry' | |
55 | 55 | domain = "" |
56 | Facter::Util::WMI.execquery("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").each { |nic| | |
57 | domain = nic.DNSDomain | |
58 | break | |
59 | } | |
56 | regvalue = Facter::Util::Registry.hklm_read('SYSTEM\CurrentControlSet\Services\Tcpip\Parameters', 'Domain') | |
57 | domain = regvalue if regvalue | |
58 | if domain == "" | |
59 | require 'facter/util/wmi' | |
60 | Facter::Util::WMI.execquery("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").each { |nic| | |
61 | domain = nic.DNSDomain | |
62 | break | |
63 | } | |
64 | end | |
60 | 65 | domain |
61 | 66 | end |
62 | 67 | end |
27 | 27 | Facter.add(:hardwaremodel) do |
28 | 28 | confine :operatingsystem => :windows |
29 | 29 | setcode do |
30 | require 'rbconfig' | |
31 | RbConfig::CONFIG['host_cpu'] | |
30 | # The cryptic windows cpu architecture models are documented in these places: | |
31 | # http://source.winehq.org/source/include/winnt.h#L568 | |
32 | # http://msdn.microsoft.com/en-us/library/windows/desktop/aa394373(v=vs.85).aspx | |
33 | # http://msdn.microsoft.com/en-us/library/windows/desktop/windows.system.processorarchitecture.aspx | |
34 | # Also, arm and neutral are included because they are valid for the upcoming | |
35 | # windows 8 release. --jeffweiss 23 May 2012 | |
36 | require 'facter/util/wmi' | |
37 | model = "" | |
38 | Facter::Util::WMI.execquery("select Architecture, Level from Win32_Processor").each do |cpu| | |
39 | model = | |
40 | case cpu.Architecture | |
41 | when 11 then 'neutral' # PROCESSOR_ARCHITECTURE_NEUTRAL | |
42 | when 10 then 'i686' # PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 | |
43 | when 9 then 'x64' # PROCESSOR_ARCHITECTURE_AMD64 | |
44 | when 8 then 'msil' # PROCESSOR_ARCHITECTURE_MSIL | |
45 | when 7 then 'alpha64' # PROCESSOR_ARCHITECTURE_ALPHA64 | |
46 | when 6 then 'ia64' # PROCESSOR_ARCHITECTURE_IA64 | |
47 | when 5 then 'arm' # PROCESSOR_ARCHITECTURE_ARM | |
48 | when 4 then 'shx' # PROCESSOR_ARCHITECTURE_SHX | |
49 | when 3 then 'powerpc' # PROCESSOR_ARCHITECTURE_PPC | |
50 | when 2 then 'alpha' # PROCESSOR_ARCHITECTURE_ALPHA | |
51 | when 1 then 'mips' # PROCESSOR_ARCHITECTURE_MIPS | |
52 | when 0 then "i#{cpu.Level}86" # PROCESSOR_ARCHITECTURE_INTEL | |
53 | else 'unknown' # PROCESSOR_ARCHITECTURE_UNKNOWN | |
54 | end | |
55 | break | |
56 | end | |
57 | ||
58 | model | |
32 | 59 | end |
33 | 60 | end |
64 | 64 | Facter.add(:ipaddress6) do |
65 | 65 | confine :kernel => :windows |
66 | 66 | setcode do |
67 | output = Facter::Util::Resolution.exec("#{ENV['SYSTEMROOT']}/system32/netsh interface ipv6 show address level=verbose") | |
67 | output = Facter::Util::Resolution.exec("#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ipv6 show address level=verbose") | |
68 | 68 | |
69 | 69 | get_address_after_token(output, 'Address', true) |
70 | 70 | end |
12 | 12 | Facter.add(:lsbdistcodename) do |
13 | 13 | confine :kernel => [ :linux, :"gnu/kfreebsd" ] |
14 | 14 | setcode do |
15 | Facter::Util::Resolution.exec('lsb_release -c -s') | |
15 | Facter::Util::Resolution.exec('lsb_release -c -s 2>/dev/null') | |
16 | 16 | end |
17 | 17 | end |
12 | 12 | Facter.add(:lsbdistdescription) do |
13 | 13 | confine :kernel => [ :linux, :"gnu/kfreebsd" ] |
14 | 14 | setcode do |
15 | if output = Facter::Util::Resolution.exec('lsb_release -d -s') | |
15 | if output = Facter::Util::Resolution.exec('lsb_release -d -s 2>/dev/null') | |
16 | 16 | # the output may be quoted (at least it is on gentoo) |
17 | 17 | output.sub(/^"(.*)"$/,'\1') |
18 | 18 | end |
12 | 12 | Facter.add(:lsbdistid) do |
13 | 13 | confine :kernel => [ :linux, :"gnu/kfreebsd" ] |
14 | 14 | setcode do |
15 | Facter::Util::Resolution.exec('lsb_release -i -s') | |
15 | Facter::Util::Resolution.exec('lsb_release -i -s 2>/dev/null') | |
16 | 16 | end |
17 | 17 | end |
12 | 12 | Facter.add(:lsbdistrelease) do |
13 | 13 | confine :kernel => [ :linux, :"gnu/kfreebsd" ] |
14 | 14 | setcode do |
15 | Facter::Util::Resolution.exec('lsb_release -r -s') | |
15 | Facter::Util::Resolution.exec('lsb_release -r -s 2>/dev/null') | |
16 | 16 | end |
17 | 17 | end |
12 | 12 | Facter.add(:lsbrelease) do |
13 | 13 | confine :kernel => [ :linux, :"gnu/kfreebsd" ] |
14 | 14 | setcode do |
15 | Facter::Util::Resolution.exec('lsb_release -v -s') | |
15 | Facter::Util::Resolution.exec('lsb_release -v -s 2>/dev/null') | |
16 | 16 | end |
17 | 17 | end |
79 | 79 | when 'HP-UX' |
80 | 80 | output = %x{/bin/netstat -in | sed -e 1d} |
81 | 81 | when 'windows' |
82 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ip show interface| | |
83 | output += %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ipv6 show interface| | |
82 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ip show interface| | |
83 | output += %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ipv6 show interface| | |
84 | 84 | end |
85 | 85 | output |
86 | 86 | end |
106 | 106 | return get_single_interface_output(interface) unless Facter.value(:kernel) == 'windows' |
107 | 107 | |
108 | 108 | if label == 'ipaddress6' |
109 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ipv6 show address \"#{interface}\"| | |
109 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ipv6 show address \"#{interface}\"| | |
110 | 110 | else |
111 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh interface ip show address \"#{interface}\"| | |
111 | output = %x|#{ENV['SYSTEMROOT']}/system32/netsh.exe interface ip show address \"#{interface}\"| | |
112 | 112 | end |
113 | 113 | output |
114 | 114 | end |
0 | module Facter::Util::Registry | |
1 | class << self | |
2 | def hklm_read(key, value) | |
3 | require 'win32/registry' | |
4 | reg = Win32::Registry::HKEY_LOCAL_MACHINE.open(key) | |
5 | rval = reg[value] | |
6 | reg.close | |
7 | rval | |
8 | end | |
9 | end | |
10 | end |
12 | 12 | |
13 | 13 | INTERPRETER = Facter::Util::Config.is_windows? ? "cmd.exe" : "/bin/sh" |
14 | 14 | |
15 | def self.have_which | |
16 | if ! defined?(@have_which) or @have_which.nil? | |
17 | if Facter::Util::Config.is_windows? | |
18 | @have_which = false | |
19 | else | |
20 | %x{which which >/dev/null 2>&1} | |
21 | @have_which = $?.success? | |
22 | end | |
23 | end | |
24 | @have_which | |
25 | end | |
15 | # Returns the locations to be searched when looking for a binary. This | |
16 | # is currently determined by the +PATH+ environment variable plus | |
17 | # <tt>/sbin</tt> and <tt>/usr/sbin</tt> when run on unix | |
18 | def self.search_paths | |
19 | if Facter::Util::Config.is_windows? | |
20 | ENV['PATH'].split(File::PATH_SEPARATOR) | |
21 | else | |
22 | # Make sure facter is usable even for non-root users. Most commands | |
23 | # in /sbin (like ifconfig) can be run as non priviledged users as | |
24 | # long as they do not modify anything - which we do not do with facter | |
25 | ENV['PATH'].split(File::PATH_SEPARATOR) + [ '/sbin', '/usr/sbin' ] | |
26 | end | |
27 | end | |
28 | ||
29 | # Determine the full path to a binary. If the supplied filename does not | |
30 | # already describe an absolute path then different locations (determined | |
31 | # by <tt>self.search_paths</tt>) will be searched for a match. | |
32 | # | |
33 | # Returns nil if no matching executable can be found otherwise returns | |
34 | # the expanded pathname. | |
35 | def self.which(bin) | |
36 | if absolute_path?(bin) | |
37 | return bin if File.executable?(bin) | |
38 | if Facter::Util::Config.is_windows? and File.extname(bin).empty? | |
39 | exts = ENV['PATHEXT'] | |
40 | exts = exts ? exts.split(File::PATH_SEPARATOR) : %w[.COM .EXE .BAT .CMD] | |
41 | exts.each do |ext| | |
42 | destext = bin + ext | |
43 | if File.executable?(destext) | |
44 | Facter.warnonce("Using Facter::Util::Resolution.which with an absolute path like #{bin} but no fileextension is deprecated. Please add the correct extension (#{ext})") | |
45 | return destext | |
46 | end | |
47 | end | |
48 | end | |
49 | else | |
50 | search_paths.each do |dir| | |
51 | dest = File.join(dir, bin) | |
52 | if Facter::Util::Config.is_windows? | |
53 | dest.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) | |
54 | if File.extname(dest).empty? | |
55 | exts = ENV['PATHEXT'] | |
56 | exts = exts ? exts.split(File::PATH_SEPARATOR) : %w[.COM .EXE .BAT .CMD] | |
57 | exts.each do |ext| | |
58 | destext = dest + ext | |
59 | return destext if File.executable?(destext) | |
60 | end | |
61 | end | |
62 | end | |
63 | return dest if File.executable?(dest) | |
64 | end | |
65 | end | |
66 | nil | |
67 | end | |
68 | ||
69 | # Determine in a platform-specific way whether a path is absolute. This | |
70 | # defaults to the local platform if none is specified. | |
71 | def self.absolute_path?(path, platform=nil) | |
72 | # Escape once for the string literal, and once for the regex. | |
73 | slash = '[\\\\/]' | |
74 | name = '[^\\\\/]+' | |
75 | regexes = { | |
76 | :windows => %r!^(([A-Z]:#{slash})|(#{slash}#{slash}#{name}#{slash}#{name})|(#{slash}#{slash}\?#{slash}#{name}))!i, | |
77 | :posix => %r!^/!, | |
78 | } | |
79 | platform ||= Facter::Util::Config.is_windows? ? :windows : :posix | |
80 | ||
81 | !! (path =~ regexes[platform]) | |
82 | end | |
83 | ||
84 | # Expand the executable of a commandline to an absolute path. The executable | |
85 | # is the first word of the commandline. If the executable contains spaces, | |
86 | # it has be but in double quotes to be properly recognized. | |
87 | # | |
88 | # Returns the commandline with the expanded binary or nil if the binary | |
89 | # can't be found. If the path to the binary contains quotes, the whole binary | |
90 | # is put in quotes. | |
91 | def self.expand_command(command) | |
92 | if match = /^"(.+?)"(?:\s+(.*))?/.match(command) | |
93 | exe, arguments = match.captures | |
94 | exe = which(exe) and [ "\"#{exe}\"", arguments ].compact.join(" ") | |
95 | elsif match = /^'(.+?)'(?:\s+(.*))?/.match(command) and not Facter::Util::Config.is_windows? | |
96 | exe, arguments = match.captures | |
97 | exe = which(exe) and [ "'#{exe}'", arguments ].compact.join(" ") | |
98 | else | |
99 | exe, arguments = command.split(/ /,2) | |
100 | if exe = which(exe) | |
101 | # the binary was not quoted which means it contains no spaces. But the | |
102 | # full path to the binary may do so. | |
103 | exe = "\"#{exe}\"" if exe =~ /\s/ and Facter::Util::Config.is_windows? | |
104 | exe = "'#{exe}'" if exe =~ /\s/ and not Facter::Util::Config.is_windows? | |
105 | [ exe, arguments ].compact.join(" ") | |
106 | end | |
107 | end | |
108 | end | |
109 | ||
26 | 110 | |
27 | 111 | # Execute a program and return the output of that program. |
28 | 112 | # |
32 | 116 | def self.exec(code, interpreter = nil) |
33 | 117 | Facter.warnonce "The interpreter parameter to 'exec' is deprecated and will be removed in a future version." if interpreter |
34 | 118 | |
35 | # Try to guess whether the specified code can be executed by looking at the | |
36 | # first word. If it cannot be found on the PATH defer on resolving the fact | |
37 | # by returning nil. | |
38 | # This only fails on shell built-ins, most of which are masked by stuff in | |
39 | # /bin or of dubious value anyways. In the worst case, "sh -c 'builtin'" can | |
40 | # be used to work around this limitation | |
41 | # | |
42 | # Windows' %x{} throws Errno::ENOENT when the command is not found, so we | |
43 | # can skip the check there. This is good, since builtins cannot be found | |
44 | # elsewhere. | |
45 | if have_which and !Facter::Util::Config.is_windows? | |
46 | path = nil | |
47 | binary = code.split.first | |
48 | if code =~ /^\// | |
49 | path = binary | |
50 | else | |
51 | path = %x{which #{binary} 2>/dev/null}.chomp | |
52 | # we don't have the binary necessary | |
53 | return nil if path == "" or path.match(/Command not found\./) | |
54 | end | |
55 | ||
56 | return nil unless FileTest.exists?(path) | |
119 | if expanded_code = expand_command(code) | |
120 | # if we can find the binary, we'll run the command with the expanded path to the binary | |
121 | code = expanded_code | |
122 | else | |
123 | # if we cannot find the binary return nil on posix. On windows we'll still try to run the | |
124 | # command in case it is a shell-builtin. In case it is not, windows will raise Errno::ENOENT | |
125 | return nil unless Facter::Util::Config.is_windows? | |
126 | return nil if absolute_path?(code) | |
57 | 127 | end |
58 | 128 | |
59 | 129 | out = nil |
60 | 130 | |
61 | 131 | begin |
62 | 132 | out = %x{#{code}}.chomp |
133 | Facter.warnonce 'Using Facter::Util::Resolution.exec with a shell built-in is deprecated. Most built-ins can be replaced with native ruby commands. If you really have to run a built-in, pass "cmd /c your_builtin" as a command' unless expanded_code | |
63 | 134 | rescue Errno::ENOENT => detail |
64 | 135 | # command not found on Windows |
65 | 136 | return nil |
24 | 24 | include Comparable |
25 | 25 | include Enumerable |
26 | 26 | |
27 | FACTERVERSION = '1.6.9' | |
27 | FACTERVERSION = '1.6.10' | |
28 | 28 | # = Facter |
29 | 29 | # Functions as a hash of 'facts' you might care about about your |
30 | 30 | # system, such as mac address, IP address, Video card, etc. |
0 | .TH "" "" "" | |
1 | .SH NAME | |
2 | \- | |
3 | .\" Man page generated from reStructeredText. | |
4 | . | |
5 | .SH SYNOPSIS | |
6 | .sp | |
7 | Collect and display facts about the system. | |
8 | .SH USAGE | |
9 | .INDENT 0.0 | |
10 | .INDENT 3.5 | |
11 | .sp | |
12 | facter [\-d|\-\-debug] [\-h|\-\-help] [\-p|\-\-puppet] [\-v|\-\-version] [\-y|\-\-yaml] [fact] [fact] [...] | |
13 | .UNINDENT | |
14 | .UNINDENT | |
15 | .SH DESCRIPTION | |
16 | .sp | |
17 | Collect and display facts about the current system. The library behind | |
18 | Facter is easy to expand, making Facter an easy way to collect | |
19 | information about a system from within the shell or within Ruby. | |
20 | .sp | |
21 | If no facts are specifically asked for, then all facts will be returned. | |
22 | .SH OPTIONS | |
23 | .sp | |
24 | debug: Enable debugging. | |
25 | .sp | |
26 | help: Print this help message | |
27 | .INDENT 0.0 | |
28 | .TP | |
29 | .B puppet: Load the Puppet libraries, thus allowing Facter to load | |
30 | . | |
31 | Puppet\-specific facts. | |
32 | .UNINDENT | |
33 | .sp | |
34 | version: Print the version and exit. | |
35 | .sp | |
36 | yaml: Emit facts in YAML format. | |
37 | .SH EXAMPLE | |
38 | .INDENT 0.0 | |
39 | .INDENT 3.5 | |
40 | .sp | |
41 | facter kernel | |
42 | .UNINDENT | |
43 | .UNINDENT | |
44 | .SH AUTHOR | |
45 | .sp | |
46 | Luke Kanies | |
47 | .SH COPYRIGHT | |
48 | .sp | |
49 | Copyright (c) 2006 Reductive Labs, LLC Licensed under the GNU Public | |
50 | License | |
51 | .\" Generated by docutils manpage writer. | |
52 | .\" | |
53 | . |
0 | # Support code for running stuff with warnings disabled. | |
1 | module Kernel | |
2 | def with_verbose_disabled | |
3 | verbose, $VERBOSE = $VERBOSE, nil | |
4 | result = yield | |
5 | $VERBOSE = verbose | |
6 | return result | |
7 | end | |
8 | end |
10 | 10 | require 'puppetlabs_spec/files' |
11 | 11 | require 'puppetlabs_spec/fixtures' |
12 | 12 | require 'puppetlabs_spec/matchers' |
13 | require 'puppetlabs_spec/verbose' | |
13 | 14 | |
14 | 15 | RSpec.configure do |config| |
15 | 16 | # Include PuppetlabsSpec helpers so they can be called at convenience |
0 | # Contexts for stubbing platforms | |
1 | # In a describe or context block, adding :as_platform => :windows or | |
2 | # :as_platform => :posix will stub the relevant facter config, as well as | |
3 | # the behavior of Ruby's filesystem methods by changing File::ALT_SEPARATOR. | |
4 | # | |
5 | # | |
6 | # | |
7 | shared_context "windows", :as_platform => :windows do | |
8 | before :each do | |
9 | Facter.fact(:operatingsystem).stubs(:value).returns('Windows') | |
10 | Facter::Util::Config.stubs(:is_windows?).returns true | |
11 | end | |
12 | ||
13 | around do |example| | |
14 | file_alt_separator = File::ALT_SEPARATOR | |
15 | file_path_separator = File::PATH_SEPARATOR | |
16 | # prevent Ruby from warning about changing a constant | |
17 | with_verbose_disabled do | |
18 | File::ALT_SEPARATOR = '\\' | |
19 | File::PATH_SEPARATOR = ';' | |
20 | end | |
21 | begin | |
22 | example.run | |
23 | ensure | |
24 | with_verbose_disabled do | |
25 | File::ALT_SEPARATOR = file_alt_separator | |
26 | File::PATH_SEPARATOR = file_path_separator | |
27 | end | |
28 | end | |
29 | end | |
30 | end | |
31 | ||
32 | shared_context "posix", :as_platform => :posix do | |
33 | before :each do | |
34 | Facter::Util::Config.stubs(:is_windows?).returns false | |
35 | end | |
36 | ||
37 | around do |example| | |
38 | file_alt_separator = File::ALT_SEPARATOR | |
39 | file_path_separator = File::PATH_SEPARATOR | |
40 | # prevent Ruby from warning about changing a constant | |
41 | with_verbose_disabled do | |
42 | File::ALT_SEPARATOR = nil | |
43 | File::PATH_SEPARATOR = ':' | |
44 | end | |
45 | begin | |
46 | example.run | |
47 | ensure | |
48 | with_verbose_disabled do | |
49 | File::ALT_SEPARATOR = file_alt_separator | |
50 | File::PATH_SEPARATOR = file_path_separator | |
51 | end | |
52 | end | |
53 | end | |
54 | end |
10 | 10 | require 'facter' |
11 | 11 | require 'fileutils' |
12 | 12 | require 'puppetlabs_spec_helper' |
13 | require 'pathname' | |
14 | ||
15 | Pathname.glob("#{dir}/shared_contexts/*.rb") do |file| | |
16 | require file.relative_path_from(Pathname.new(dir)) | |
17 | end | |
13 | 18 | |
14 | 19 | RSpec.configure do |config| |
15 | 20 | config.mock_with :mocha |
20 | 20 | ["Gentoo","i586"] => "x86", |
21 | 21 | ["Gentoo","i686"] => "x86", |
22 | 22 | ["Gentoo","pentium"] => "x86", |
23 | ["windows","i386"] => "x86", | |
24 | ["windows","x64"] => "x64", | |
23 | 25 | } |
24 | 26 | generic_archs = Hash.new |
25 | 27 | generic_archs = { |
97 | 97 | end |
98 | 98 | |
99 | 99 | describe "on Windows" do |
100 | it "should use the DNSDomain for the first nic where ip is enabled" do | |
100 | before(:each) do | |
101 | 101 | Facter.fact(:kernel).stubs(:value).returns("windows") |
102 | require 'facter/util/registry' | |
103 | end | |
104 | describe "with primary dns suffix" do | |
105 | before(:each) do | |
106 | Facter::Util::Registry.stubs(:hklm_read).returns('baz.com') | |
107 | end | |
108 | it "should get the primary dns suffix" do | |
109 | Facter.fact(:domain).value.should == 'baz.com' | |
110 | end | |
111 | it "should not execute the wmi query" do | |
112 | require 'facter/util/wmi' | |
113 | Facter::Util::WMI.expects(:execquery).never | |
114 | Facter.fact(:domain).value | |
115 | end | |
116 | end | |
117 | describe "without primary dns suffix" do | |
118 | before(:each) do | |
119 | Facter::Util::Registry.stubs(:hklm_read).returns('') | |
120 | end | |
121 | it "should use the DNSDomain for the first nic where ip is enabled" do | |
122 | nic = stubs 'nic' | |
123 | nic.stubs(:DNSDomain).returns("foo.com") | |
102 | 124 | |
103 | nic = stubs 'nic' | |
104 | nic.stubs(:DNSDomain).returns("foo.com") | |
125 | nic2 = stubs 'nic' | |
126 | nic2.stubs(:DNSDomain).returns("bar.com") | |
105 | 127 | |
106 | nic2 = stubs 'nic' | |
107 | nic2.stubs(:DNSDomain).returns("bar.com") | |
128 | require 'facter/util/wmi' | |
129 | Facter::Util::WMI.stubs(:execquery).with("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").returns([nic, nic2]) | |
108 | 130 | |
109 | require 'facter/util/wmi' | |
110 | Facter::Util::WMI.stubs(:execquery).with("select DNSDomain from Win32_NetworkAdapterConfiguration where IPEnabled = True").returns([nic, nic2]) | |
111 | ||
112 | Facter.fact(:domain).value.should == 'foo.com' | |
131 | Facter.fact(:domain).value.should == 'foo.com' | |
132 | end | |
113 | 133 | end |
114 | 134 | end |
115 | 135 | end |
73 | 73 | |
74 | 74 | describe "when provided code as a string" do |
75 | 75 | it "should execute the code in the shell" do |
76 | test_command = Facter::Util::Config.is_windows? ? 'cmd.exe /c echo yup' : 'echo yup' | |
76 | 77 | Facter.add("shell_testing") do |
77 | setcode "echo yup" | |
78 | setcode test_command | |
78 | 79 | end |
79 | 80 | |
80 | 81 | Facter["shell_testing"].value.should == "yup" |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require 'spec_helper' | |
3 | require 'facter' | |
4 | ||
5 | describe "Hardwaremodel fact" do | |
6 | it "should match uname -m by default" do | |
7 | Facter.fact(:kernel).stubs(:value).returns("Darwin") | |
8 | Facter::Util::Resolution.stubs(:exec).with("uname -m").returns("Inky") | |
9 | ||
10 | Facter.fact(:hardwaremodel).value.should == "Inky" | |
11 | end | |
12 | ||
13 | describe "on Windows" do | |
14 | require 'facter/util/wmi' | |
15 | before :each do | |
16 | Facter.fact(:kernel).stubs(:value).returns("windows") | |
17 | end | |
18 | ||
19 | it "should detect i686" do | |
20 | cpu = mock('cpu', :Architecture => 0, :Level => 6) | |
21 | Facter::Util::WMI.expects(:execquery).returns([cpu]) | |
22 | ||
23 | Facter.fact(:hardwaremodel).value.should == "i686" | |
24 | end | |
25 | ||
26 | it "should detect x64" do | |
27 | cpu = mock('cpu', :Architecture => 9) | |
28 | Facter::Util::WMI.expects(:execquery).returns([cpu]) | |
29 | ||
30 | Facter.fact(:hardwaremodel).value.should == "x64" | |
31 | end | |
32 | end | |
33 | end |
43 | 43 | Facter::Util::Config.stubs(:is_windows?).returns(true) |
44 | 44 | |
45 | 45 | fixture = netsh_fixture('windows_netsh_addresses_with_multiple_interfaces') |
46 | Facter::Util::Resolution.stubs(:exec).with('d:/windows/system32/netsh interface ipv6 show address level=verbose'). | |
46 | Facter::Util::Resolution.stubs(:exec).with('d:/windows/system32/netsh.exe interface ipv6 show address level=verbose'). | |
47 | 47 | returns(fixture) |
48 | 48 | |
49 | 49 | Facter.value(:ipaddress6).should == "2001:0:4137:9e76:2087:77a:53ef:7527" |
9 | 9 | Facter.fact(:kernel).stubs(:value).returns kernel |
10 | 10 | end |
11 | 11 | |
12 | it "should return the codename through lsb_release -c -s" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -c -s').returns 'n/a' | |
12 | it "should return the codename through lsb_release -c -s 2>/dev/null" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -c -s 2>/dev/null').returns 'n/a' | |
14 | 14 | Facter.fact(:lsbdistcodename).value.should == 'n/a' |
15 | 15 | end |
16 | 16 | |
17 | 17 | it "should return nil if lsb_release is not installed" do |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -c -s').returns nil | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -c -s 2>/dev/null').returns nil | |
19 | 19 | Facter.fact(:lsbdistcodename).value.should be_nil |
20 | 20 | end |
21 | 21 | end |
9 | 9 | Facter.fact(:kernel).stubs(:value).returns kernel |
10 | 10 | end |
11 | 11 | |
12 | it "should return the description through lsb_release -d -s" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -d -s').returns '"Gentoo Base System release 2.1"' | |
12 | it "should return the description through lsb_release -d -s 2>/dev/null" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -d -s 2>/dev/null').returns '"Gentoo Base System release 2.1"' | |
14 | 14 | Facter.fact(:lsbdistdescription).value.should == 'Gentoo Base System release 2.1' |
15 | 15 | end |
16 | 16 | |
17 | 17 | it "should return nil if lsb_release is not installed" do |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -d -s').returns nil | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -d -s 2>/dev/null').returns nil | |
19 | 19 | Facter.fact(:lsbdistdescription).value.should be_nil |
20 | 20 | end |
21 | 21 | end |
9 | 9 | Facter.fact(:kernel).stubs(:value).returns kernel |
10 | 10 | end |
11 | 11 | |
12 | it "should return the id through lsb_release -i -s" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -i -s').returns 'Gentoo' | |
12 | it "should return the id through lsb_release -i -s 2>/dev/null" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -i -s 2>/dev/null').returns 'Gentoo' | |
14 | 14 | Facter.fact(:lsbdistid).value.should == 'Gentoo' |
15 | 15 | end |
16 | 16 | |
17 | it "should return nil if lsb_release is not installed" do | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -i -s').returns nil | |
17 | it "should return nil if lsb_release is not installed 2>/dev/null" do | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -i -s 2>/dev/null').returns nil | |
19 | 19 | Facter.fact(:lsbdistid).value.should be_nil |
20 | 20 | end |
21 | 21 | end |
9 | 9 | Facter.fact(:kernel).stubs(:value).returns kernel |
10 | 10 | end |
11 | 11 | |
12 | it "should return the release through lsb_release -r -s" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -r -s').returns '2.1' | |
12 | it "should return the release through lsb_release -r -s 2>/dev/null" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -r -s 2>/dev/null').returns '2.1' | |
14 | 14 | Facter.fact(:lsbdistrelease).value.should == '2.1' |
15 | 15 | end |
16 | 16 | |
17 | 17 | it "should return nil if lsb_release is not installed" do |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -r -s').returns nil | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -r -s 2>/dev/null').returns nil | |
19 | 19 | Facter.fact(:lsbdistrelease).value.should be_nil |
20 | 20 | end |
21 | 21 | end |
9 | 9 | Facter.fact(:kernel).stubs(:value).returns kernel |
10 | 10 | end |
11 | 11 | |
12 | it "should return the release through lsb_release -v -s" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -v -s').returns 'n/a' | |
12 | it "should return the release through lsb_release -v -s 2>/dev/null" do | |
13 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -v -s 2>/dev/null').returns 'n/a' | |
14 | 14 | Facter.fact(:lsbrelease).value.should == 'n/a' |
15 | 15 | end |
16 | 16 | |
17 | 17 | it "should return nil if lsb_release is not installed" do |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -v -s').returns nil | |
18 | Facter::Util::Resolution.stubs(:exec).with('lsb_release -v -s 2>/dev/null').returns nil | |
19 | 19 | Facter.fact(:lsbrelease).value.should be_nil |
20 | 20 | end |
21 | 21 | end |
15 | 15 | def load(procs) |
16 | 16 | require 'facter/util/wmi' |
17 | 17 | Facter::Util::WMI.stubs(:execquery).with("select * from Win32_Processor").returns(procs) |
18 | # This is to workaround #14674 | |
19 | Facter.fact(:architecture).stubs(:value).returns("x64") | |
18 | 20 | |
19 | 21 | # processor facts belong to a file with a different name, |
20 | 22 | # so load the file explicitly (after stubbing kernel), |
0 | #!/usr/bin/env rspec | |
1 | require 'spec_helper' | |
2 | require 'facter/operatingsystem' | |
3 | require 'facter/util/registry' | |
4 | ||
5 | describe Facter::Util::Registry do | |
6 | describe "hklm_read", :if => Facter::Util::Config.is_windows? do | |
7 | before(:all) do | |
8 | require 'win32/registry' | |
9 | end | |
10 | describe "valid params" do | |
11 | [ {:key => "valid_key", :value => "valid_value", :expected => "valid"}, | |
12 | {:key => "valid_key", :value => "", :expected => "valid"}, | |
13 | {:key => "valid_key", :value => nil, :expected => "invalid"}, | |
14 | {:key => "", :value => "valid_value", :expected => "valid"}, | |
15 | {:key => "", :value => "", :expected => "valid"}, | |
16 | {:key => "", :value => nil, :expected => "invalid"}, | |
17 | {:key => nil, :value => "valid_value", :expected => "invalid"}, | |
18 | {:key => nil, :value => "", :expected => "invalid"}, | |
19 | {:key => nil, :value => nil, :expected => "invalid"} | |
20 | ].each do |scenario| | |
21 | describe "with key #{scenario[:key] || "nil"} and value #{scenario[:value] || "nil"}" do | |
22 | let :fake_registry_key do | |
23 | fake = {} | |
24 | fake[scenario[:value]] = scenario[:expected] | |
25 | fake | |
26 | end | |
27 | it "should return #{scenario[:expected]} value" do | |
28 | Win32::Registry::HKEY_LOCAL_MACHINE.stubs(:open).with(scenario[:key]).returns(fake_registry_key) | |
29 | fake_registry_key.stubs(:close) | |
30 | ||
31 | Facter::Util::Registry.hklm_read(scenario[:key], scenario[:value]).should == scenario[:expected] | |
32 | end | |
33 | end | |
34 | end | |
35 | end | |
36 | ||
37 | describe "invalid params" do | |
38 | [ {:key => "valid_key", :value => "invalid_value"}, | |
39 | {:key => "valid_key", :value => ""}, | |
40 | {:key => "valid_key", :value => nil}, | |
41 | ].each do |scenario| | |
42 | describe "with valid key and value #{scenario[:value] || "nil"}" do | |
43 | let :fake_registry_key do | |
44 | {} | |
45 | end | |
46 | it "should raise an error" do | |
47 | Win32::Registry::HKEY_LOCAL_MACHINE.stubs(:open).with(scenario[:key]).returns(fake_registry_key) | |
48 | fake_registry_key.stubs(:close) | |
49 | ||
50 | Facter::Util::Registry.hklm_read(scenario[:key], scenario[:value]).should raise_error | |
51 | end | |
52 | end | |
53 | end | |
54 | [ {:key => "invalid_key", :value => "valid_value"}, | |
55 | {:key => "invalid_key", :value => ""}, | |
56 | {:key => "invalid_key", :value => nil}, | |
57 | {:key => "", :value => "valid_value"}, | |
58 | {:key => "", :value => ""}, | |
59 | {:key => "", :value => nil}, | |
60 | {:key => nil, :value => "valid_value"}, | |
61 | {:key => nil, :value => ""}, | |
62 | {:key => nil, :value => nil} | |
63 | ].each do |scenario| | |
64 | describe "with invalid key #{scenario[:key] || "nil"} and value #{scenario[:value] || "nil"}" do | |
65 | it "should raise an error" do | |
66 | Win32::Registry::HKEY_LOCAL_MACHINE.stubs(:open).with(scenario[:key]).raises(Win32::Registry::Error, 2) | |
67 | expect do | |
68 | Facter::Util::Registry.hklm_read(scenario[:key], scenario[:value]) | |
69 | end.to raise_error Win32::Registry::Error | |
70 | end | |
71 | end | |
72 | end | |
73 | end | |
74 | end | |
75 | end |
283 | 283 | Facter::Util::Resolution.should respond_to(:exec) |
284 | 284 | end |
285 | 285 | |
286 | # taken from puppet: spec/unit/util_spec.rb | |
287 | describe "#absolute_path?" do | |
288 | context "when run on unix", :as_platform => :posix do | |
289 | %w[/ /foo /foo/../bar //foo //Server/Foo/Bar //?/C:/foo/bar /\Server/Foo /foo//bar/baz].each do |path| | |
290 | it "should return true for #{path}" do | |
291 | Facter::Util::Resolution.should be_absolute_path(path) | |
292 | end | |
293 | end | |
294 | ||
295 | %w[. ./foo \foo C:/foo \\Server\Foo\Bar \\?\C:\foo\bar \/?/foo\bar \/Server/foo foo//bar/baz].each do |path| | |
296 | it "should return false for #{path}" do | |
297 | Facter::Util::Resolution.should_not be_absolute_path(path) | |
298 | end | |
299 | end | |
300 | end | |
301 | ||
302 | context "when run on windows", :as_platform => :windows do | |
303 | %w[C:/foo C:\foo \\\\Server\Foo\Bar \\\\?\C:\foo\bar //Server/Foo/Bar //?/C:/foo/bar /\?\C:/foo\bar \/Server\Foo/Bar c:/foo//bar//baz].each do |path| | |
304 | it "should return true for #{path}" do | |
305 | Facter::Util::Resolution.should be_absolute_path(path) | |
306 | end | |
307 | end | |
308 | ||
309 | %w[/ . ./foo \foo /foo /foo/../bar //foo C:foo/bar foo//bar/baz].each do |path| | |
310 | it "should return false for #{path}" do | |
311 | Facter::Util::Resolution.should_not be_absolute_path(path) | |
312 | end | |
313 | end | |
314 | end | |
315 | end | |
316 | ||
317 | describe "#search_paths" do | |
318 | context "on windows", :as_platform => :windows do | |
319 | it "should use the PATH environment variable to determine locations" do | |
320 | ENV.expects(:[]).with('PATH').returns 'C:\Windows;C:\Windows\System32' | |
321 | Facter::Util::Resolution.search_paths.should == %w{C:\Windows C:\Windows\System32} | |
322 | end | |
323 | end | |
324 | ||
325 | context "on posix", :as_platform => :posix do | |
326 | it "should use the PATH environment variable plus /sbin and /usr/sbin on unix" do | |
327 | ENV.expects(:[]).with('PATH').returns "/bin:/usr/bin" | |
328 | Facter::Util::Resolution.search_paths.should == %w{/bin /usr/bin /sbin /usr/sbin} | |
329 | end | |
330 | end | |
331 | end | |
332 | ||
333 | describe "#which" do | |
334 | context "when run on posix", :as_platform => :posix do | |
335 | before :each do | |
336 | Facter::Util::Resolution.stubs(:search_paths).returns [ '/bin', '/sbin', '/usr/sbin'] | |
337 | end | |
338 | ||
339 | context "and provided with an absolute path" do | |
340 | it "should return the binary if executable" do | |
341 | File.expects(:executable?).with('/opt/foo').returns true | |
342 | Facter::Util::Resolution.which('/opt/foo').should == '/opt/foo' | |
343 | end | |
344 | ||
345 | it "should return nil if the binary is not executable" do | |
346 | File.expects(:executable?).with('/opt/foo').returns false | |
347 | Facter::Util::Resolution.which('/opt/foo').should be_nil | |
348 | end | |
349 | end | |
350 | ||
351 | context "and not provided with an absolute path" do | |
352 | it "should return the absolute path if found" do | |
353 | File.expects(:executable?).with('/bin/foo').returns false | |
354 | File.expects(:executable?).with('/sbin/foo').returns true | |
355 | File.expects(:executable?).with('/usr/sbin/foo').never | |
356 | Facter::Util::Resolution.which('foo').should == '/sbin/foo' | |
357 | end | |
358 | ||
359 | it "should return nil if not found" do | |
360 | File.expects(:executable?).with('/bin/foo').returns false | |
361 | File.expects(:executable?).with('/sbin/foo').returns false | |
362 | File.expects(:executable?).with('/usr/sbin/foo').returns false | |
363 | Facter::Util::Resolution.which('foo').should be_nil | |
364 | end | |
365 | end | |
366 | end | |
367 | ||
368 | context "when run on windows", :as_platform => :windows do | |
369 | before :each do | |
370 | Facter::Util::Resolution.stubs(:search_paths).returns ['C:\Windows\system32', 'C:\Windows', 'C:\Windows\System32\Wbem' ] | |
371 | ENV.stubs(:[]).with('PATHEXT').returns nil | |
372 | end | |
373 | ||
374 | context "and provided with an absolute path" do | |
375 | it "should return the binary if executable" do | |
376 | File.expects(:executable?).with('C:\Tools\foo.exe').returns true | |
377 | File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns true | |
378 | Facter::Util::Resolution.which('C:\Tools\foo.exe').should == 'C:\Tools\foo.exe' | |
379 | Facter::Util::Resolution.which('\\\\remote\dir\foo.exe').should == '\\\\remote\dir\foo.exe' | |
380 | end | |
381 | ||
382 | it "should return the binary with added extension if executable" do | |
383 | ['.COM', '.BAT', '.CMD', '' ].each do |ext| | |
384 | File.stubs(:executable?).with('C:\Windows\system32\netsh'+ext).returns false | |
385 | end | |
386 | File.expects(:executable?).with('C:\Windows\system32\netsh.EXE').returns true | |
387 | ||
388 | Facter.expects(:warnonce).with('Using Facter::Util::Resolution.which with an absolute path like C:\\Windows\\system32\\netsh but no fileextension is deprecated. Please add the correct extension (.EXE)') | |
389 | Facter::Util::Resolution.which('C:\Windows\system32\netsh').should == 'C:\Windows\system32\netsh.EXE' | |
390 | end | |
391 | ||
392 | it "should return nil if the binary is not executable" do | |
393 | File.expects(:executable?).with('C:\Tools\foo.exe').returns false | |
394 | File.expects(:executable?).with('\\\\remote\dir\foo.exe').returns false | |
395 | Facter::Util::Resolution.which('C:\Tools\foo.exe').should be_nil | |
396 | Facter::Util::Resolution.which('\\\\remote\dir\foo.exe').should be_nil | |
397 | end | |
398 | end | |
399 | ||
400 | context "and not provided with an absolute path" do | |
401 | it "should return the absolute path if found" do | |
402 | File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false | |
403 | File.expects(:executable?).with('C:\Windows\foo.exe').returns true | |
404 | File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').never | |
405 | Facter::Util::Resolution.which('foo.exe').should == 'C:\Windows\foo.exe' | |
406 | end | |
407 | ||
408 | it "should return the absolute path with file extension if found" do | |
409 | ['.COM', '.EXE', '.BAT', '.CMD', '' ].each do |ext| | |
410 | File.stubs(:executable?).with('C:\Windows\system32\foo'+ext).returns false | |
411 | File.stubs(:executable?).with('C:\Windows\System32\Wbem\foo'+ext).returns false | |
412 | end | |
413 | ['.COM', '.BAT', '.CMD', '' ].each do |ext| | |
414 | File.stubs(:executable?).with('C:\Windows\foo'+ext).returns false | |
415 | end | |
416 | File.stubs(:executable?).with('C:\Windows\foo.EXE').returns true | |
417 | ||
418 | Facter::Util::Resolution.which('foo').should == 'C:\Windows\foo.EXE' | |
419 | end | |
420 | ||
421 | it "should return nil if not found" do | |
422 | File.expects(:executable?).with('C:\Windows\system32\foo.exe').returns false | |
423 | File.expects(:executable?).with('C:\Windows\foo.exe').returns false | |
424 | File.expects(:executable?).with('C:\Windows\System32\Wbem\foo.exe').returns false | |
425 | Facter::Util::Resolution.which('foo.exe').should be_nil | |
426 | end | |
427 | end | |
428 | end | |
429 | ||
430 | describe "#expand_command" do | |
431 | context "on windows", :as_platform => :windows do | |
432 | it "should expand binary" do | |
433 | Facter::Util::Resolution.expects(:which).with('cmd').returns 'C:\Windows\System32\cmd' | |
434 | Facter::Util::Resolution.expand_command( | |
435 | 'cmd /c echo foo > C:\bar' | |
436 | ).should == 'C:\Windows\System32\cmd /c echo foo > C:\bar' | |
437 | end | |
438 | ||
439 | it "should expand double quoted binary" do | |
440 | Facter::Util::Resolution.expects(:which).with('my foo').returns 'C:\My Tools\my foo.exe' | |
441 | Facter::Util::Resolution.expand_command('"my foo" /a /b').should == '"C:\My Tools\my foo.exe" /a /b' | |
442 | end | |
443 | ||
444 | it "should not expand single quoted binary" do | |
445 | Facter::Util::Resolution.expects(:which).with('\'C:\My').returns nil | |
446 | Facter::Util::Resolution.expand_command('\'C:\My Tools\foo.exe\' /a /b').should be_nil | |
447 | end | |
448 | ||
449 | it "should quote expanded binary if found in path with spaces" do | |
450 | Facter::Util::Resolution.expects(:which).with('foo').returns 'C:\My Tools\foo.exe' | |
451 | Facter::Util::Resolution.expand_command('foo /a /b').should == '"C:\My Tools\foo.exe" /a /b' | |
452 | end | |
453 | ||
454 | it "should return nil if not found" do | |
455 | Facter::Util::Resolution.expects(:which).with('foo').returns nil | |
456 | Facter::Util::Resolution.expand_command('foo /a | stuff >> /dev/null').should be_nil | |
457 | end | |
458 | end | |
459 | ||
460 | context "on unix", :as_platform => :posix do | |
461 | it "should expand binary" do | |
462 | Facter::Util::Resolution.expects(:which).with('foo').returns '/bin/foo' | |
463 | Facter::Util::Resolution.expand_command('foo -a | stuff >> /dev/null').should == '/bin/foo -a | stuff >> /dev/null' | |
464 | end | |
465 | ||
466 | it "should expand double quoted binary" do | |
467 | Facter::Util::Resolution.expects(:which).with('/tmp/my foo').returns '/tmp/my foo' | |
468 | Facter::Util::Resolution.expand_command(%q{"/tmp/my foo" bar}).should == %q{"/tmp/my foo" bar} | |
469 | end | |
470 | ||
471 | it "should expand single quoted binary" do | |
472 | Facter::Util::Resolution.expects(:which).with('my foo').returns '/home/bob/my path/my foo' | |
473 | Facter::Util::Resolution.expand_command(%q{'my foo' -a}).should == %q{'/home/bob/my path/my foo' -a} | |
474 | end | |
475 | ||
476 | it "should quote expanded binary if found in path with spaces" do | |
477 | Facter::Util::Resolution.expects(:which).with('foo.sh').returns '/home/bob/my tools/foo.sh' | |
478 | Facter::Util::Resolution.expand_command('foo.sh /a /b').should == %q{'/home/bob/my tools/foo.sh' /a /b} | |
479 | end | |
480 | ||
481 | it "should return nil if not found" do | |
482 | Facter::Util::Resolution.expects(:which).with('foo').returns nil | |
483 | Facter::Util::Resolution.expand_command('foo -a | stuff >> /dev/null').should be_nil | |
484 | end | |
485 | end | |
486 | end | |
487 | ||
488 | end | |
489 | ||
286 | 490 | # It's not possible, AFAICT, to mock %x{}, so I can't really test this bit. |
287 | 491 | describe "when executing code" do |
288 | 492 | it "should deprecate the interpreter parameter" do |
291 | 495 | end |
292 | 496 | |
293 | 497 | it "should execute the binary" do |
294 | Facter::Util::Resolution.exec("echo foo").should == "foo" | |
295 | end | |
296 | end | |
297 | ||
298 | describe "have_which" do | |
299 | before :each do | |
300 | Facter::Util::Resolution.instance_variable_set(:@have_which, nil) | |
301 | ||
302 | # we do not execute anything in the following test cases itself | |
303 | # but we rely on $? to be an instance of Process::Status. So | |
304 | # just execute anything here to make sure that $? is not nil | |
305 | %x{echo foo} | |
306 | end | |
307 | ||
308 | it "on windows should always return false" do | |
309 | Facter::Util::Config.stubs(:is_windows?).returns(true) | |
310 | Facter::Util::Resolution.expects(:`). | |
311 | with('which which >/dev/null 2>&1').never | |
312 | Facter::Util::Resolution.have_which.should == false | |
313 | end | |
314 | ||
315 | it "on other platforms than windows should return true if which exists" do | |
316 | Facter::Util::Config.stubs(:is_windows?).returns(false) | |
317 | Facter::Util::Resolution.expects(:`). | |
318 | with('which which >/dev/null 2>&1').returns('') | |
319 | Process::Status.any_instance.stubs(:success?).returns true | |
320 | Facter::Util::Resolution.have_which.should == true | |
321 | end | |
322 | ||
323 | it "on other platforms than windows should return false if which returns non-zero exit code" do | |
324 | Facter::Util::Config.stubs(:is_windows?).returns(false) | |
325 | Facter::Util::Resolution.expects(:`). | |
326 | with('which which >/dev/null 2>&1').returns('') | |
327 | Process::Status.any_instance.stubs(:success?).returns false | |
328 | Facter::Util::Resolution.have_which.should == false | |
498 | test_command = Facter::Util::Config.is_windows? ? 'cmd.exe /c echo foo' : 'echo foo' | |
499 | Facter::Util::Resolution.exec(test_command).should == "foo" | |
500 | end | |
501 | ||
502 | context "when run on unix", :as_platform => :posix do | |
503 | context "binary is present" do | |
504 | it "should run the command if path to binary is absolute" do | |
505 | Facter::Util::Resolution.expects(:expand_command).with('/usr/bin/uname -m').returns('/usr/bin/uname -m') | |
506 | Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').returns 'x86_64' | |
507 | Facter::Util::Resolution.exec('/usr/bin/uname -m').should == 'x86_64' | |
508 | end | |
509 | ||
510 | it "should run the expanded command if path to binary not absolute" do | |
511 | Facter::Util::Resolution.expects(:expand_command).with('uname -m').returns('/usr/bin/uname -m') | |
512 | Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').returns 'x86_64' | |
513 | Facter::Util::Resolution.exec('uname -m').should == 'x86_64' | |
514 | end | |
515 | end | |
516 | ||
517 | context "binary is not present" do | |
518 | it "should not run the command if path to binary is absolute" do | |
519 | Facter::Util::Resolution.expects(:expand_command).with('/usr/bin/uname -m').returns nil | |
520 | Facter::Util::Resolution.expects(:`).with('/usr/bin/uname -m').never | |
521 | Facter::Util::Resolution.exec('/usr/bin/uname -m').should be_nil | |
522 | end | |
523 | it "should not run the command if path to binary is not absolute" do | |
524 | Facter::Util::Resolution.expects(:expand_command).with('uname -m').returns nil | |
525 | Facter::Util::Resolution.expects(:`).with('uname -m').never | |
526 | Facter::Util::Resolution.exec('uname -m').should be_nil | |
527 | end | |
528 | end | |
529 | end | |
530 | ||
531 | context "when run on windows", :as_platform => :windows do | |
532 | context "binary is present" do | |
533 | it "should run the command if path to binary is absolute" do | |
534 | Facter::Util::Resolution.expects(:expand_command).with(%q{C:\Windows\foo.exe /a /b}).returns(%q{C:\Windows\foo.exe /a /b}) | |
535 | Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).returns 'bar' | |
536 | Facter::Util::Resolution.exec(%q{C:\Windows\foo.exe /a /b}).should == 'bar' | |
537 | end | |
538 | ||
539 | it "should run the expanded command if path to binary not absolute" do | |
540 | Facter::Util::Resolution.expects(:expand_command).with(%q{foo.exe /a /b}).returns(%q{C:\Windows\foo.exe /a /b}) | |
541 | Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).returns 'bar' | |
542 | Facter::Util::Resolution.exec(%q{foo.exe /a /b}).should == 'bar' | |
543 | end | |
544 | end | |
545 | ||
546 | context "binary is not present" do | |
547 | it "should not run the command if path to binary is absolute" do | |
548 | Facter::Util::Resolution.expects(:expand_command).with(%q{C:\Windows\foo.exe /a /b}).returns nil | |
549 | Facter::Util::Resolution.expects(:`).with(%q{C:\Windows\foo.exe /a /b}).never | |
550 | Facter::Util::Resolution.exec(%q{C:\Windows\foo.exe /a /b}).should be_nil | |
551 | end | |
552 | it "should try to run the command and return output of a shell-builtin" do | |
553 | Facter::Util::Resolution.expects(:expand_command).with(%q{echo foo}).returns nil | |
554 | Facter::Util::Resolution.expects(:`).with(%q{echo foo}).returns 'foo' | |
555 | Facter.expects(:warnonce).with('Using Facter::Util::Resolution.exec with a shell built-in is deprecated. Most built-ins can be replaced with native ruby commands. If you really have to run a built-in, pass "cmd /c your_builtin" as a command') | |
556 | Facter::Util::Resolution.exec(%q{echo foo}).should == 'foo' | |
557 | end | |
558 | it "should try to run the command and return nil if not shell-builtin" do | |
559 | Facter::Util::Resolution.expects(:expand_command).with(%q{echo foo}).returns nil | |
560 | Facter::Util::Resolution.stubs(:`).with(%q{echo foo}).raises Errno::ENOENT, 'some_error_message' | |
561 | Facter.expects(:warnonce).never | |
562 | Facter::Util::Resolution.exec(%q{echo foo}).should be_nil | |
563 | end | |
564 | end | |
329 | 565 | end |
330 | 566 | end |
331 | 567 | end |
0 | # Title: Rake task to build Apple packages for Facter. | |
1 | # Author: Gary Larizza | |
2 | # Date: 12/5/2011 | |
3 | # Description: This task will create a DMG-encapsulated package that will | |
4 | # install Facter on OS X systems. This happens by building | |
5 | # a directory tree of files that will then be fed to the | |
6 | # packagemaker binary (can be installed by installing the | |
7 | # XCode Tools) which will create the .pkg file. | |
8 | # | |
9 | require 'fileutils' | |
10 | require 'erb' | |
11 | require 'find' | |
12 | require 'pathname' | |
13 | ||
14 | # Path to Binaries (Constants) | |
15 | TAR = '/usr/bin/tar' | |
16 | CP = '/bin/cp' | |
17 | INSTALL = '/usr/bin/install' | |
18 | DITTO = '/usr/bin/ditto' | |
19 | PACKAGEMAKER = '/Developer/usr/bin/packagemaker' | |
20 | SED = '/usr/bin/sed' | |
21 | ||
22 | # Setup task to populate all the variables | |
23 | task :setup do | |
24 | @version = `git describe`.chomp | |
25 | @title = "facter-#{@version}" | |
26 | @reverse_domain = 'com.puppetlabs.facter' | |
27 | @package_major_version = @version.split('.')[0] | |
28 | @package_minor_version = @version.split('.')[1] + | |
29 | @version.split('.')[2].split('-')[0].split('rc')[0] | |
30 | @pm_restart = 'None' | |
31 | @build_date = Time.new.strftime("%Y-%m-%dT%H:%M:%SZ") | |
32 | end | |
33 | ||
34 | # method: make_directory_tree | |
35 | # description: This method sets up the directory structure that packagemaker | |
36 | # needs to build a package. A prototype.plist file (holding | |
37 | # package-specific options) is built from an ERB template located | |
38 | # in the tasks/rake/templates directory. | |
39 | def make_directory_tree | |
40 | facter_tmp = '/tmp/facter' | |
41 | @scratch = "#{facter_tmp}/#{@title}" | |
42 | @working_tree = { | |
43 | 'scripts' => "#{@scratch}/scripts", | |
44 | 'resources' => "#{@scratch}/resources", | |
45 | 'working' => "#{@scratch}/root", | |
46 | 'payload' => "#{@scratch}/payload", | |
47 | } | |
48 | puts "Cleaning Tree: #{facter_tmp}" | |
49 | FileUtils.rm_rf(facter_tmp) | |
50 | @working_tree.each do |key,val| | |
51 | puts "Creating: #{val}" | |
52 | FileUtils.mkdir_p(val) | |
53 | end | |
54 | File.open("#{@scratch}/#{'prototype.plist'}", "w+") do |f| | |
55 | f.write(ERB.new(File.read('tasks/rake/templates/prototype.plist.erb')).result()) | |
56 | end | |
57 | end | |
58 | ||
59 | # method: build_dmg | |
60 | # description: This method builds a package from the directory structure in | |
61 | # /tmp/facter and puts it in the | |
62 | # /tmp/facter/facter-#{version}/payload directory. A DMG is | |
63 | # created, using hdiutil, based on the contents of the | |
64 | # /tmp/facter/facter-#{version}/payload directory. The resultant | |
65 | # DMG is placed in the pkg/apple directory. | |
66 | # | |
67 | def build_dmg | |
68 | # Local Variables | |
69 | dmg_format_code = 'UDZO' | |
70 | zlib_level = '9' | |
71 | dmg_format_option = "-imagekey zlib-level=#{zlib_level}" | |
72 | dmg_format = "#{dmg_format_code} #{dmg_format_option}" | |
73 | dmg_file = "#{@title}.dmg" | |
74 | package_file = "#{@title}.pkg" | |
75 | pm_extra_args = '--verbose --no-recommend --no-relocate' | |
76 | package_target_os = '10.4' | |
77 | ||
78 | # Build .pkg file | |
79 | system("sudo #{PACKAGEMAKER} --root #{@working_tree['working']} \ | |
80 | --id #{@reverse_domain} \ | |
81 | --filter DS_Store \ | |
82 | --target #{package_target_os} \ | |
83 | --title #{@title} \ | |
84 | --info #{@scratch}/prototype.plist \ | |
85 | --scripts #{@working_tree['scripts']} \ | |
86 | --resources #{@working_tree['resources']} \ | |
87 | --version #{@version} \ | |
88 | #{pm_extra_args} --out #{@working_tree['payload']}/#{package_file}") | |
89 | ||
90 | # Build .dmg file | |
91 | system("sudo hdiutil create -volname #{@title} \ | |
92 | -srcfolder #{@working_tree['payload']} \ | |
93 | -uid 99 \ | |
94 | -gid 99 \ | |
95 | -ov \ | |
96 | -format #{dmg_format} \ | |
97 | #{dmg_file}") | |
98 | ||
99 | if File.directory?("#{Pathname.pwd}/pkg/apple") | |
100 | FileUtils.mv("#{Pathname.pwd}/#{dmg_file}", "#{Pathname.pwd}/pkg/apple/#{dmg_file}") | |
101 | puts "moved: #{dmg_file} has been moved to #{Pathname.pwd}/pkg/apple/#{dmg_file}" | |
102 | else | |
103 | FileUtils.mkdir_p("#{Pathname.pwd}/pkg/apple") | |
104 | FileUtils.mv(dmg_file, "#{Pathname.pwd}/pkg/apple/#{dmg_file}") | |
105 | puts "moved: #{dmg_file} has been moved to #{Pathname.pwd}/pkg/apple/#{dmg_file}" | |
106 | end | |
107 | end | |
108 | ||
109 | # method: pack_facter_source | |
110 | # description: This method copies the facter source into a directory | |
111 | # structure in /tmp/facter/facter-#{version}/root mirroring the | |
112 | # structure on the target system for which the package will be | |
113 | # installed. Anything installed into /tmp/facter/root will be | |
114 | # installed as the package's payload. | |
115 | # | |
116 | def pack_facter_source | |
117 | work = "#{@working_tree['working']}" | |
118 | facter_source = Pathname.pwd | |
119 | ||
120 | # Make all necessary directories | |
121 | directories = ["#{work}/usr/bin", | |
122 | "#{work}/usr/share/doc/facter", | |
123 | "#{work}/usr/lib/ruby/site_ruby/1.8/facter"] | |
124 | FileUtils.mkdir_p(directories) | |
125 | ||
126 | # Install necessary files | |
127 | system("#{DITTO} #{facter_source}/bin/ #{work}/usr/bin") | |
128 | system("#{DITTO} #{facter_source}/lib/ #{work}/usr/lib/ruby/site_ruby/1.8/") | |
129 | ||
130 | # Setup a preflight script and replace variables in the files with | |
131 | # the correct paths. | |
132 | system("#{INSTALL} -o root -g wheel -m 644 #{facter_source}/conf/osx/preflight #{@working_tree['scripts']}") | |
133 | system("#{SED} -i '' \"s\#{SITELIBDIR}\#/usr/lib/ruby/site_ruby/1.8\#g\" #{@working_tree['scripts']}/preflight") | |
134 | system("#{SED} -i '' \"s\#{BINDIR}\#/usr/bin\#g\" #{@working_tree['scripts']}/preflight") | |
135 | ||
136 | # Install documentation (matching for files with capital letters) | |
137 | Dir.foreach("#{facter_source}") do |file| | |
138 | system("#{INSTALL} -o root -g wheel -m 644 #{facter_source}/#{file} #{work}/usr/share/doc/facter") if file =~ /^[A-Z][A-Z]/ | |
139 | end | |
140 | ||
141 | # Set Permissions | |
142 | executable_directories = [ "#{work}/usr/bin", ] | |
143 | FileUtils.chmod_R(0755, executable_directories) | |
144 | FileUtils.chown_R('root', 'wheel', directories) | |
145 | FileUtils.chmod_R(0644, "#{work}/usr/lib/ruby/site_ruby/1.8/") | |
146 | FileUtils.chown_R('root', 'wheel', "#{work}/usr/lib/ruby/site_ruby/1.8/") | |
147 | Find.find("#{work}/usr/lib/ruby/site_ruby/1.8/") do |dir| | |
148 | FileUtils.chmod(0755, dir) if File.directory?(dir) | |
149 | end | |
150 | end | |
151 | ||
152 | namespace :package do | |
153 | desc "Task for building an Apple Package" | |
154 | task :apple => [:setup] do | |
155 | # Test for Root and Packagemaker binary | |
156 | raise "Please run rake as root to build Apple Packages" unless Process.uid == 0 | |
157 | raise "Packagemaker must be installed. Please install XCode Tools" unless \ | |
158 | File.exists?('/Developer/usr/bin/packagemaker') | |
159 | ||
160 | make_directory_tree | |
161 | pack_facter_source | |
162 | build_dmg | |
163 | FileUtils.chmod_R(0775, "#{Pathname.pwd}/pkg") | |
164 | end | |
165 | end |
0 | desc "Create a ChangeLog based on git commits." | |
1 | task :changelog do | |
2 | begin | |
3 | gitc = %x{which git-changelog} | |
4 | rescue | |
5 | puts "This task needs the git-changelog binary - http://github.com/ReinH/git-changelog" | |
6 | end | |
7 | ||
8 | CHANGELOG_DIR = "#{Dir.pwd}" | |
9 | mkdir(CHANGELOG_DIR) unless File.directory?(CHANGELOG_DIR) | |
10 | change_body = `git-changelog --limit=99999` | |
11 | File.open(File.join(CHANGELOG_DIR, "CHANGELOG"), 'w') do |f| | |
12 | f << change_body | |
13 | end | |
14 | end |
0 | desc "Prep CI RSpec tests" | |
1 | task :ci_prep do | |
2 | require 'rubygems' | |
3 | begin | |
4 | gem 'ci_reporter' | |
5 | require 'ci/reporter/rake/rspec' | |
6 | require 'ci/reporter/rake/test_unit' | |
7 | ENV['CI_REPORTS'] = 'results' | |
8 | rescue LoadError | |
9 | puts 'Missing ci_reporter gem. You must have the ci_reporter gem installed to run the CI spec tests' | |
10 | end | |
11 | end | |
12 | ||
13 | desc "Run the CI RSpec tests" | |
14 | task :ci_spec => [:ci_prep, 'ci:setup:rspec', :spec] do | |
15 | end |
0 | desc "Create a Facter daily build" | |
1 | task :daily => :changelog do | |
2 | version = "facter" + "-" + Time.now.localtime.strftime("%Y%m%d") | |
3 | sh "git archive --format=tar --prefix=#{version}/ HEAD^{tree} >#{version}.tar" | |
4 | sh "pax -waf #{version}.tar -s ':^:#{version}/:' ChangeLog" | |
5 | sh "rm ChangeLog" | |
6 | sh "gzip -f -9 #{version}.tar" | |
7 | end |
0 | desc "Send patch information to the puppet-dev list" | |
1 | task :mail_patches do | |
2 | if Dir.glob("00*.patch").length > 0 | |
3 | raise "Patches already exist matching '00*.patch'; clean up first" | |
4 | end | |
5 | ||
6 | unless %x{git status} =~ /On branch (.+)/ | |
7 | raise "Could not get branch from 'git status'" | |
8 | end | |
9 | branch = $1 | |
10 | ||
11 | unless branch =~ %r{^([^\/]+)/([^\/]+)/([^\/]+)$} | |
12 | raise "Branch name does not follow <type>/<parent>/<name> model; cannot autodetect parent branch" | |
13 | end | |
14 | ||
15 | type, parent, name = $1, $2, $3 | |
16 | ||
17 | # Create all of the patches | |
18 | sh "git format-patch -C -M -s -n --subject-prefix='PATCH/facter' #{parent}..HEAD" | |
19 | ||
20 | # Add info to the patches | |
21 | additional_info = "Local-branch: #{branch}\n" | |
22 | files = Dir.glob("00*.patch") | |
23 | files.each do |file| | |
24 | contents = File.read(file) | |
25 | contents.sub!(/^---\n/, "---\n#{additional_info}") | |
26 | File.open(file, 'w') do |file_handle| | |
27 | file_handle.print contents | |
28 | end | |
29 | end | |
30 | ||
31 | # And then mail them out. | |
32 | ||
33 | # If we've got more than one patch, add --compose | |
34 | if files.length > 1 | |
35 | compose = "--compose" | |
36 | subject = %Q{--subject "#{type} #{name} against #{parent}"} | |
37 | else | |
38 | compose = "" | |
39 | subject = "" | |
40 | end | |
41 | ||
42 | # Now send the mail. | |
43 | sh "git send-email #{compose} #{subject} --no-signed-off-by-cc --suppress-from --to puppet-dev@googlegroups.com 00*.patch" | |
44 | ||
45 | # Finally, clean up the patches | |
46 | sh "rm 00*.patch" | |
47 | end |
0 | begin | |
1 | require 'metric_fu' | |
2 | rescue LoadError | |
3 | # Metric-fu not installed | |
4 | # http://metric-fu.rubyforge.org/ | |
5 | end |
0 | desc "Sign the package with the Puppet Labs release key" | |
1 | task :sign_packages do | |
2 | ||
3 | version = Facter::FACTERVERSION | |
4 | ||
5 | # Sign package | |
6 | ||
7 | sh "gpg --homedir $HOME/pl_release_key --detach-sign --output pkg/facter-#{version}.tar.gz.sign --armor pkg/facter-#{version}.tar.gz" | |
8 | ||
9 | # Sign gem | |
10 | ||
11 | sh "gpg --homedir $HOME/pl_release_key --detach-sign --output pkg/facter-#{version}.gem.sign --armor pkg/facter-#{version}.gem" | |
12 | ||
13 | end |
0 | <?xml version="1.0" encoding="UTF-8"?> | |
1 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
2 | <plist version="1.0"> | |
3 | <dict> | |
4 | <key>CFBundleIdentifier</key> | |
5 | <string><%= @title %></string> | |
6 | <key>CFBundleShortVersionString</key> | |
7 | <string><%= @version %></string> | |
8 | <key>IFMajorVersion</key> | |
9 | <integer><%= @package_major_version %></integer> | |
10 | <key>IFMinorVersion</key> | |
11 | <integer><%= @package_minor_version %></integer> | |
12 | <key>IFPkgBuildDate</key> | |
13 | <date><%= @build_date %></date> | |
14 | <key>IFPkgFlagAllowBackRev</key> | |
15 | <false/> | |
16 | <key>IFPkgFlagAuthorizationAction</key> | |
17 | <string>RootAuthorization</string> | |
18 | <key>IFPkgFlagDefaultLocation</key> | |
19 | <string>/</string> | |
20 | <key>IFPkgFlagFollowLinks</key> | |
21 | <true/> | |
22 | <key>IFPkgFlagInstallFat</key> | |
23 | <false/> | |
24 | <key>IFPkgFlagIsRequired</key> | |
25 | <false/> | |
26 | <key>IFPkgFlagOverwritePermissions</key> | |
27 | <false/> | |
28 | <key>IFPkgFlagRelocatable</key> | |
29 | <false/> | |
30 | <key>IFPkgFlagRestartAction</key> | |
31 | <string><%= @pm_restart %></string> | |
32 | <key>IFPkgFlagRootVolumeOnly</key> | |
33 | <true/> | |
34 | <key>IFPkgFlagUpdateInstalledLanguages</key> | |
35 | <false/> | |
36 | </dict> | |
37 | </plist> |