]> git.donarmstrong.com Git - dsa-puppet.git/blob - 3rdparty/modules/concat/files/concatfragments.rb
try if downgrading to 1.2.2 solves my problem
[dsa-puppet.git] / 3rdparty / modules / concat / files / concatfragments.rb
1 #!/usr/bin/env ruby
2 # Script to concat files to a config file.
3 #
4 # Given a directory like this:
5 # /path/to/conf.d
6 # |-- fragments
7 # |   |-- 00_named.conf
8 # |   |-- 10_domain.net
9 # |   `-- zz_footer
10 #
11 # The script supports a test option that will build the concat file to a temp location and
12 # use /usr/bin/cmp to verify if it should be run or not.  This would result in the concat happening
13 # twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds.
14 #
15 # Without the test option and the unless combo your services that depend on the final file would end up
16 # restarting on each run, or in other manifest models some changes might get missed.
17 #
18 # OPTIONS:
19 #  -o   The file to create from the sources
20 #  -d   The directory where the fragments are kept
21 #  -t   Test to find out if a build is needed, basically concats the files to a temp
22 #       location and compare with what's in the final location, return codes are designed
23 #       for use with unless on an exec resource
24 #  -w   Add a shell style comment at the top of the created file to warn users that it
25 #       is generated by puppet
26 #  -f   Enables the creation of empty output files when no fragments are found
27 #  -n   Sort the output numerically rather than the default alpha sort
28 #
29 # the command:
30 #
31 #   concatfragments.rb -o /path/to/conffile.cfg -d /path/to/conf.d
32 #
33 # creates /path/to/conf.d/fragments.concat and copies the resulting
34 # file to /path/to/conffile.cfg.  The files will be sorted alphabetically
35 # pass the -n switch to sort numerically.
36 #
37 # The script does error checking on the various dirs and files to make
38 # sure things don't fail.
39 require 'optparse'
40 require 'fileutils'
41
42 settings = {
43     :outfile => "",
44     :workdir => "",
45     :test => false,
46     :force => false,
47     :warn => "",
48     :sortarg => "",
49     :newline => false
50 }
51
52 OptionParser.new do |opts|
53   opts.banner = "Usage: #{$0} [options]"
54   opts.separator "Specific options:"
55
56   opts.on("-o", "--outfile OUTFILE", String, "The file to create from the sources") do |o|
57     settings[:outfile] = o
58   end
59
60   opts.on("-d", "--workdir WORKDIR", String, "The directory where the fragments are kept") do |d|
61     settings[:workdir] = d
62   end
63
64   opts.on("-t", "--test", "Test to find out if a build is needed") do
65     settings[:test] = true
66   end
67
68   opts.separator "Other options:"
69   opts.on("-w", "--warn WARNMSG", String,
70           "Add a shell style comment at the top of the created file to warn users that it is generated by puppet") do |w|
71     settings[:warn] = w
72   end
73
74   opts.on("-f", "--force", "Enables the creation of empty output files when no fragments are found") do
75     settings[:force] = true
76   end
77
78   opts.on("-n", "--sort", "Sort the output numerically rather than the default alpha sort") do
79     settings[:sortarg] = "-n"
80   end
81
82   opts.on("-l", "--line", "Append a newline") do
83     settings[:newline] = true
84   end
85 end.parse!
86
87 # do we have -o?
88 raise 'Please specify an output file with -o' unless !settings[:outfile].empty?
89
90 # do we have -d?
91 raise 'Please specify fragments directory with -d' unless !settings[:workdir].empty?
92
93 # can we write to -o?
94 if File.file?(settings[:outfile])
95   if !File.writable?(settings[:outfile])
96     raise "Cannot write to #{settings[:outfile]}"
97   end
98 else
99   if !File.writable?(File.dirname(settings[:outfile]))
100     raise "Cannot write to dirname #{File.dirname(settings[:outfile])} to create #{settings[:outfile]}"
101   end
102 end
103
104 # do we have a fragments subdir inside the work dir?
105 if !File.directory?(File.join(settings[:workdir], "fragments")) && !File.executable?(File.join(settings[:workdir], "fragments"))
106   raise "Cannot access the fragments directory"
107 end
108
109 # are there actually any fragments?
110 if (Dir.entries(File.join(settings[:workdir], "fragments")) - %w{ . .. }).empty?
111   if !settings[:force]
112     raise "The fragments directory is empty, cowardly refusing to make empty config files"
113   end
114 end
115
116 Dir.chdir(settings[:workdir])
117
118 if settings[:warn].empty?
119   File.open("fragments.concat", 'w') { |f| f.write("") }
120 else
121   File.open("fragments.concat", 'w') { |f| f.write("#{settings[:warn]}\n") }
122 end
123
124 # find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir
125 open('fragments.concat', 'a') do |f|
126   fragments = Dir.entries("fragments").sort
127   if settings[:sortarg] == '-n'
128     fragments = fragments.sort_by { |v| v.split('_').map(&:to_i) }
129   end
130   fragments.each { |entry|
131     if File.file?(File.join("fragments", entry))
132       f << File.read(File.join("fragments", entry))
133
134       # append a newline if we were asked to (invoked with -l)
135       if settings[:newline]
136         f << "\n"
137       end
138
139     end
140   }
141 end
142
143 if !settings[:test]
144   # This is a real run, copy the file to outfile
145   FileUtils.cp 'fragments.concat', settings[:outfile]
146 else
147   # Just compare the result to outfile to help the exec decide
148   if FileUtils.cmp 'fragments.concat', settings[:outfile]
149     exit 0
150   else
151     exit 1
152   end
153 end