tpkg 2.0.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/Rakefile +1 -1
  2. data/bin/tpkg +28 -23
  3. data/lib/tpkg.rb +243 -233
  4. data/lib/tpkg/deployer.rb +37 -32
  5. metadata +2 -2
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ spec = Gem::Specification.new do |s|
5
5
  s.add_dependency('facter')
6
6
  s.add_dependency('net-ssh')
7
7
  s.add_dependency('ddao-kwalify')
8
- s.version = '2.0.1'
8
+ s.version = '2.1.0'
9
9
  s.authors = ['Darren Dao', 'Jason Heiss']
10
10
  s.email = 'tpkg-users@lists.sourceforge.net'
11
11
  s.homepage = 'http://tpkg.sourceforge.net'
data/bin/tpkg CHANGED
@@ -9,7 +9,6 @@ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
9
9
 
10
10
  require 'optparse'
11
11
  require 'tpkg'
12
- require 'etc'
13
12
 
14
13
  #
15
14
  # Parse the command line options
@@ -108,30 +107,36 @@ opts.on('--verify', '-V', '=NAME', 'Verify packages') do |opt|
108
107
  @action = :verify
109
108
  @action_value = opt
110
109
  end
111
- opts.on('--start', '=NAME', 'Start the init script for the specified package', Array) do |opt|
110
+ opts.on('--start', '=NAME', 'Start the init script for specified package', Array) do |opt|
112
111
  @rerun_with_sudo = true
113
112
  @action = :execute_init
114
113
  @init_options[:packages] = opt
115
114
  @init_options[:cmd] = 'start'
116
115
  end
117
- opts.on('--stop', '=NAME', 'Stop the init script for the specified package', Array) do |opt|
116
+ opts.on('--stop', '=NAME', 'Stop the init script for specified package', Array) do |opt|
118
117
  @rerun_with_sudo = true
119
118
  @action = :execute_init
120
119
  @init_options[:packages] = opt
121
120
  @init_options[:cmd] = 'stop'
122
121
  end
123
- opts.on('--restart', '=NAME', 'Restart the init script for the specified package', Array) do |opt|
122
+ opts.on('--restart', '=NAME', 'Restart the init script for specified package', Array) do |opt|
124
123
  @rerun_with_sudo = true
125
124
  @action = :execute_init
126
125
  @init_options[:packages] = opt
127
126
  @init_options[:cmd] = 'restart'
128
127
  end
129
- opts.on('--reload', '=NAME', 'Reload the init script for the specified package', Array) do |opt|
128
+ opts.on('--reload', '=NAME', 'Reload the init script for specified package', Array) do |opt|
130
129
  @rerun_with_sudo = true
131
130
  @action = :execute_init
132
131
  @init_options[:packages] = opt
133
132
  @init_options[:cmd] = 'reload'
134
133
  end
134
+ opts.on('--status', '=NAME', 'Get status from init script for specified package', Array) do |opt|
135
+ @rerun_with_sudo = true
136
+ @action = :execute_init
137
+ @init_options[:packages] = opt
138
+ @init_options[:cmd] = 'status'
139
+ end
135
140
  opts.on('--start-all', 'Start the init scripts for all packages') do |opt|
136
141
  @rerun_with_sudo = true
137
142
  @action = :execute_init
@@ -152,7 +157,7 @@ opts.on('--reload-all', 'Reload the init script for all packages') do |opt|
152
157
  @action = :execute_init
153
158
  @init_options[:cmd] = 'reload'
154
159
  end
155
- opts.on('--exec-init', '=NAME', 'Execute init scripts for the specified packages', Array) do |opt|
160
+ opts.on('--exec-init', '=NAME', 'Execute init scripts for specified packages', Array) do |opt|
156
161
  @rerun_with_sudo = true
157
162
  @init_options[:packages] = opt
158
163
  @action = :execute_init
@@ -161,7 +166,7 @@ opts.on('--init-script', '=NAME', 'What init scripts to execute', Array) do |opt
161
166
  @rerun_with_sudo = true
162
167
  @init_options[:scripts] = opt
163
168
  end
164
- opts.on('--init-cmd', '=CMD', 'Invoke the specified init script command') do |opt|
169
+ opts.on('--init-cmd', '=CMD', 'Invoke specified init script command') do |opt|
165
170
  @rerun_with_sudo = true
166
171
  @init_options[:cmd] = opt
167
172
  end
@@ -306,7 +311,7 @@ def instantiate_tpkg(options = {})
306
311
  sources = options["sources"] || []
307
312
  report_server = nil
308
313
 
309
- [File.join(Tpkg::CONFIGDIR, 'tpkg.conf'), File.join(ENV['HOME'], ".tpkg.conf")].each do |configfile|
314
+ [File.join(Tpkg::DEFAULT_CONFIGDIR, 'tpkg.conf'), File.join(ENV['HOME'], ".tpkg.conf")].each do |configfile|
310
315
  if File.exist?(configfile)
311
316
  IO.foreach(configfile) do |line|
312
317
  line.chomp!
@@ -337,23 +342,23 @@ def instantiate_tpkg(options = {})
337
342
  # if they don't realize there's an environment variable set.
338
343
  warn "Using base '#{base}' base from $TPKG_HOME"
339
344
  end
340
- if !@sudo
341
- curruid = Etc.getpwuid.uid
345
+
346
+ if !@sudo
347
+ curruid = Process.euid
342
348
  if curruid == 0
343
- puts "** ERROR **\n--no-sudo cannot be used as 'root' user or with sudo command."
344
- exit 1
345
- end
346
- if !File::exists?(File.join(ENV['HOME'], ".tpkg.conf"))
347
- puts "** ERROR **\nWhen specifying --no-sudo, #{File.join(ENV['HOME'], ".tpkg.conf")} and custom 'base' dir with write privileges is required\n" and exit 1
348
- elsif base == '/home/t'
349
- puts "** ERROR **\nWhen specifying --no-sudo, custom base dir with write privileges is required\n" and exit 1
349
+ # Besides there being no point to running with --no-sudo when root, we
350
+ # don't want users to accidentally create files/directories that can't be
351
+ # modified by other users who properly run --no-sudo as a regular user.
352
+ raise "--no-sudo cannot be used as 'root' user or via sudo"
350
353
  end
351
- baseuid = File.stat(base).uid
352
- if baseuid != curruid
353
- puts "** ERROR **\nbase dir (#{base}) not owned by you.\n"
354
- exit 1
354
+ baseuid = File.stat(base).uid
355
+ # We want to ensure that all --no-sudo usage within a given base directory
356
+ # is done under the same account.
357
+ if baseuid != curruid
358
+ raise "Base dir #{base} owned by UID #{baseuid}, not your UID #{curruid}"
355
359
  end
356
360
  end
361
+
357
362
  tpkg = Tpkg.new(:base => base, :sources => sources, :report_server => report_server, :lockforce => @lockforce, :force => @force, :sudo => @sudo)
358
363
  end
359
364
 
@@ -378,8 +383,8 @@ if @deploy
378
383
  @deploy_options["abort-on-fail"] = false
379
384
 
380
385
  # check to see if ssh-key is accessible
381
- ssh_key = @deploy_options["use-ssh-key"]
382
- if ssh_key && ssh_key.is_a?(String)
386
+ if @deploy_options["use-ssh-key"]
387
+ ssh_key = @deploy_options["ssh-key"]
383
388
  if !File.readable?(ssh_key) && Process.euid == 0
384
389
  raise "Unable to read ssh key from #{ssh_key}"
385
390
  elsif !File.readable?(ssh_key)
@@ -56,8 +56,7 @@ require 'kwalify' # for validating yaml
56
56
 
57
57
  class Tpkg
58
58
 
59
- VERSION = '2.0.1'
60
- CONFIGDIR = '/etc'
59
+ VERSION = '2.1.0'
61
60
 
62
61
  GENERIC_ERR = 1
63
62
  POSTINSTALL_ERR = 2
@@ -121,11 +120,11 @@ class Tpkg
121
120
  raise "Unable to find GNU tar or bsdtar in PATH"
122
121
  end
123
122
  end
124
- # bsdtar uses pax format by default. This format allows for vendor extensions, such
123
+ # bsdtar uses pax format by default. This format allows for vendor extensions, such
125
124
  # as the SCHILY.* extensions which were introduced by star). bsdtar actually uses
126
125
  # these extensions. These extension headers includde useful, but not vital information.
127
126
  # gnu tar should just ignore them and gives a warning. This is what the latest gnu tar
128
- # will do. However, on older gnu tar, it only threw an error at the end. The work
127
+ # will do. However, on older gnu tar, it only threw an error at the end. The work
129
128
  # around is to explicitly tell gnu tar to ignore those extensions.
130
129
  if @@tarinfo[:type] == 'gnu' && @@tarinfo[:version] != 'unknown' && @@tarinfo[:version] >= '1.15.1'
131
130
  @@taroptions = "--pax-option='delete=SCHILY.*,delete=LIBARCHIVE.*'"
@@ -286,7 +285,7 @@ class Tpkg
286
285
  # code (tar) ever touch the user's files.
287
286
  system("#{find_tar} -C #{pkgsrcdir} -cf - . | #{find_tar} -C #{tpkgdir} -xpf -") || raise("Package content copy failed")
288
287
 
289
- # check metadata file
288
+ # check metadata file
290
289
  errors = []
291
290
  metadata = Metadata::instantiate_from_dir(tpkgdir)
292
291
  if !metadata
@@ -298,14 +297,15 @@ class Tpkg
298
297
  schema_dir = File.join(File.dirname(File.dirname(__FILE__)), "schema")
299
298
  # This is the directory where we put our dtd/schema for validating
300
299
  # the metadata file
301
- elsif File.exist?(File.join(CONFIGDIR, 'tpkg', 'schema'))
302
- schema_dir = File.join(CONFIGDIR, 'tpkg', 'schema')
300
+ # FIXME: This method should become an instance method and use @configdir
301
+ elsif File.exist?(File.join(DEFAULT_CONFIGDIR, 'tpkg', 'schema'))
302
+ schema_dir = File.join(DEFAULT_CONFIGDIR, 'tpkg', 'schema')
303
303
  else
304
304
  warn "Warning: unable to find schema for tpkg.yml"
305
305
  end
306
306
 
307
307
  errors = metadata.validate(schema_dir) if schema_dir
308
- if errors && !errors.empty?
308
+ if errors && !errors.empty?
309
309
  puts "Bad metadata file. Possible error(s):"
310
310
  errors.each {|e| puts e }
311
311
  raise "Failed to create package." unless options[:force]
@@ -316,10 +316,10 @@ class Tpkg
316
316
  File.open(File.join(tpkgdir, "file_metadata.bin"), "w") do |file|
317
317
  filemetadata = get_filemetadata_from_directory(tpkgdir)
318
318
  filemetadata[:files].each do |file1|
319
- if metadata[:files] && metadata[:files][:files] &&
319
+ if metadata[:files] && metadata[:files][:files] &&
320
320
  metadata[:files][:files].any?{|file2|file2[:path] == file1[:path] && file2[:config]}
321
321
  file1[:config] = true
322
- end
322
+ end
323
323
  end
324
324
  data = filemetadata.to_hash.recursively{|h| h.stringify_keys }
325
325
  Marshal::dump(data, file)
@@ -344,7 +344,7 @@ class Tpkg
344
344
  data = {:actual_file => working_path, :metadata => metadata, :file_metadata => tpkgfile}
345
345
  perms, uid, gid = predict_file_perms_and_ownership(data)
346
346
  # crontab needs to be owned by root, and is not writable by group or others
347
- if uid != 0
347
+ if uid != 0
348
348
  warn "Warning: Your cron jobs in \"#{tpkgfile[:path]}\" might fail to run because the file is not owned by root."
349
349
  end
350
350
  if (perms & 0022) != 0
@@ -369,7 +369,7 @@ class Tpkg
369
369
  package_directory = File.join(workdir, package_filename)
370
370
  Dir.mkdir(package_directory)
371
371
 
372
- if outdir
372
+ if outdir
373
373
  pkgfile = File.join(outdir, package_filename + '.tpkg')
374
374
  else
375
375
  pkgfile = File.join(File.dirname(pkgsrcdir), package_filename + '.tpkg')
@@ -386,7 +386,7 @@ class Tpkg
386
386
  File.delete(pkgfile)
387
387
  end
388
388
 
389
- # update metadata file with the tpkg version
389
+ # update metadata file with the tpkg version
390
390
  metadata.add_tpkg_version(VERSION)
391
391
 
392
392
  # Tar up the tpkg directory
@@ -395,7 +395,7 @@ class Tpkg
395
395
 
396
396
  # Checksum the tarball
397
397
  # Older ruby version doesn't support this
398
- # digest = Digest::SHA256.file(tpkgfile).hexdigest
398
+ # digest = Digest::SHA256.file(tpkgfile).hexdigest
399
399
  digest = Digest::SHA256.hexdigest(File.read(tpkgfile))
400
400
 
401
401
  # Create checksum.xml
@@ -410,7 +410,7 @@ class Tpkg
410
410
 
411
411
  # compress if needed
412
412
  if options[:compress]
413
- tpkgfile = compress_file(tpkgfile, options[:compress])
413
+ tpkgfile = compress_file(tpkgfile, options[:compress])
414
414
  end
415
415
 
416
416
  # Tar up checksum.xml and the main tarball
@@ -494,7 +494,7 @@ class Tpkg
494
494
  return FileMetadata.new(Marshal::dump(filemetadata),'bin')
495
495
  end
496
496
 
497
- def self.verify_package_checksum(package_file, options = {})
497
+ def self.verify_package_checksum(package_file, options = {})
498
498
  topleveldir = options[:topleveldir] || package_toplevel_directory(package_file)
499
499
  # Extract checksum.xml from the package
500
500
  checksum_xml = nil
@@ -555,10 +555,10 @@ class Tpkg
555
555
  file = File.join('tpkg', "tpkg.#{format}")
556
556
 
557
557
  # use popen3 instead of popen because popen display stderr when there's an error such as
558
- # tpkg.yml not being there, which is something we want to ignore since old tpkg doesn't
558
+ # tpkg.yml not being there, which is something we want to ignore since old tpkg doesn't
559
559
  # have tpkg.yml file
560
560
  extract_tpkg_tar_command = cmd_to_extract_tpkg_tar(package_file, topleveldir)
561
- stdin, stdout, stderr = Open3.popen3("#{extract_tpkg_tar_command} | #{find_tar} -xf - -O #{file}")
561
+ stdin, stdout, stderr = Open3.popen3("#{extract_tpkg_tar_command} | #{find_tar} -xf - -O #{file}")
562
562
  filecontent = stdout.read
563
563
  if filecontent.nil? or filecontent.empty?
564
564
  next
@@ -975,33 +975,6 @@ class Tpkg
975
975
  gid.to_i
976
976
  end
977
977
 
978
- def self.gethttp(uri)
979
- if uri.scheme != 'http' && uri.scheme != 'https'
980
- # It would be possible to add support for FTP and possibly
981
- # other things if anyone cares
982
- raise "Only http/https URIs are supported, got: '#{uri}'"
983
- end
984
- http = Net::HTTP.new(uri.host, uri.port)
985
- if uri.scheme == 'https'
986
- # Eliminate the OpenSSL "using default DH parameters" warning
987
- if File.exist?(File.join(CONFIGDIR, 'tpkg', 'dhparams'))
988
- dh = OpenSSL::PKey::DH.new(IO.read(File.join(CONFIGDIR, 'tpkg', 'dhparams')))
989
- Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
990
- http.tmp_dh_callback = proc { dh }
991
- end
992
- http.use_ssl = true
993
- if File.exist?(File.join(CONFIGDIR, 'tpkg', 'ca.pem'))
994
- http.ca_file = File.join(CONFIGDIR, 'tpkg', 'ca.pem')
995
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
996
- elsif File.directory?(File.join(CONFIGDIR, 'tpkg', 'ca'))
997
- http.ca_path = File.join(CONFIGDIR, 'tpkg', 'ca')
998
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
999
- end
1000
- end
1001
- http.start
1002
- http
1003
- end
1004
-
1005
978
  # foo
1006
979
  # foo=1.0
1007
980
  # foo=1.0=1
@@ -1012,7 +985,7 @@ class Tpkg
1012
985
  parts = request.split('=')
1013
986
 
1014
987
  # upgrade/remove/query options could take package filenames
1015
- # We're assuming that the filename ends in .tpkg and has a version number that starts
988
+ # We're assuming that the filename ends in .tpkg and has a version number that starts
1016
989
  # with a digit. For example: foo-1.0.tpkg, foo-bar-1.0-1.tpkg
1017
990
  if request =~ /\.tpkg$/
1018
991
  req = {:filename => request, :name => request.split(/-\d/)[0]}
@@ -1038,10 +1011,10 @@ class Tpkg
1038
1011
 
1039
1012
  # deploy_options is used for configuration the deployer. It is a map of option_names => option_values. Possible
1040
1013
  # options are: use-ssh-key, deploy-as, worker-count, abort-on-fail
1041
- #
1014
+ #
1042
1015
  # deploy_params is an array that holds the list of paramters that is used when invoking tpkg on to the remote
1043
- # servers where we want to deploy to.
1044
- #
1016
+ # servers where we want to deploy to.
1017
+ #
1045
1018
  # servers is an array, a filename or a callback that list the remote servers where we want to deploy to
1046
1019
  def self.deploy(deploy_params, deploy_options, servers)
1047
1020
  servers.uniq!
@@ -1105,7 +1078,7 @@ class Tpkg
1105
1078
  return File.basename(filename) !~ /^\./
1106
1079
  end
1107
1080
 
1108
- # helper method for predicting the permissions and ownership of a file that
1081
+ # helper method for predicting the permissions and ownership of a file that
1109
1082
  # will be installed by tpkg. This is done by looking at:
1110
1083
  # 1) its current perms & ownership
1111
1084
  # 2) the file_defaults settings of the metadata file
@@ -1138,7 +1111,7 @@ class Tpkg
1138
1111
  perms = file_metadata[:posix][:perms] if file_metadata[:posix][:perms]
1139
1112
  end
1140
1113
  return perms, uid, gid
1141
- end
1114
+ end
1142
1115
 
1143
1116
  # Given a package file, figure out if tpkg.tar was compressed
1144
1117
  # Return what type of compression. If tpkg.tar wasn't compressed, then return nil.
@@ -1147,7 +1120,7 @@ class Tpkg
1147
1120
  IO.popen("#{find_tar} #{@@taroptions} -tf #{package_file}") do |pipe|
1148
1121
  pipe.each do |file|
1149
1122
  if file =~ /tpkg.tar.gz$/
1150
- compression = "gzip"
1123
+ compression = "gzip"
1151
1124
  elsif file =~ /tpkg.tar.bz2$/
1152
1125
  compression = "bz2"
1153
1126
  end
@@ -1170,7 +1143,7 @@ class Tpkg
1170
1143
  end
1171
1144
 
1172
1145
  # Compresses the file using the compression type
1173
- # specified by the compress flag
1146
+ # specified by the compress flag
1174
1147
  # Returns the compressed file
1175
1148
  def self.compress_file(file, compress)
1176
1149
  if compress == true or compress == "gzip"
@@ -1183,7 +1156,7 @@ class Tpkg
1183
1156
  raise "Compression #{compress} is not supported"
1184
1157
  end
1185
1158
  if !$?.success? or !File.exists?(result)
1186
- raise "Failed to compress the package"
1159
+ raise "Failed to compress the package"
1187
1160
  end
1188
1161
  return result
1189
1162
  end
@@ -1203,10 +1176,11 @@ class Tpkg
1203
1176
  #
1204
1177
 
1205
1178
  DEFAULT_BASE = '/opt/tpkg'
1179
+ DEFAULT_CONFIGDIR = '/etc'
1206
1180
 
1207
1181
  def initialize(options)
1208
1182
  # Options
1209
- @base = options[:base]
1183
+ @base = options[:base] ? options[:base] : DEFAULT_BASE
1210
1184
  # An array of filenames or URLs which point to individual package files
1211
1185
  # or directories containing packages and extracted metadata.
1212
1186
  @sources = []
@@ -1238,11 +1212,14 @@ class Tpkg
1238
1212
  @sudo = options[:sudo]
1239
1213
  end
1240
1214
 
1215
+ @configdir = DEFAULT_CONFIGDIR
1216
+
1241
1217
  @file_system_root = '/' # Not sure if this needs to be more portable
1242
1218
  # This option is only intended for use by the test suite
1243
1219
  if options[:file_system_root]
1244
1220
  @file_system_root = options[:file_system_root]
1245
1221
  @base = File.join(@file_system_root, @base)
1222
+ @configdir = File.join(@file_system_root, @configdir)
1246
1223
  end
1247
1224
 
1248
1225
  # Various external scripts that we run might need to adjust things for
@@ -1264,7 +1241,7 @@ class Tpkg
1264
1241
  if Tpkg::get_os =~ /Darwin/
1265
1242
  # Try to help our Mac OS X users, otherwise this could be
1266
1243
  # rather confusing.
1267
- warn "\nNote: /home is controlled by the automounter by default on Mac OS X.\n" +
1244
+ warn "\nNote: /home is controlled by the automounter by default on Mac OS X.\n" +
1268
1245
  "You'll either need to disable that in /etc/auto_master or configure\n" +
1269
1246
  "tpkg to use a different base via tpkg.conf.\n"
1270
1247
  end
@@ -1277,7 +1254,7 @@ class Tpkg
1277
1254
  @tmp_directory = File.join(@var_directory, 'tmp')
1278
1255
  @log_directory = File.join(@var_directory, 'logs')
1279
1256
  # It is important to create these dirs in correct order
1280
- dirs_to_create = [@installed_directory, @metadata_directory, @sources_directory,
1257
+ dirs_to_create = [@installed_directory, @metadata_directory, @sources_directory,
1281
1258
  @tmp_directory, @log_directory]
1282
1259
  dirs_to_create.each do |dir|
1283
1260
  if !File.exist?(dir)
@@ -1305,6 +1282,33 @@ class Tpkg
1305
1282
  attr_reader :sudo
1306
1283
  attr_reader :file_system_root
1307
1284
 
1285
+ def gethttp(uri)
1286
+ if uri.scheme != 'http' && uri.scheme != 'https'
1287
+ # It would be possible to add support for FTP and possibly
1288
+ # other things if anyone cares
1289
+ raise "Only http/https URIs are supported, got: '#{uri}'"
1290
+ end
1291
+ http = Net::HTTP.new(uri.host, uri.port)
1292
+ if uri.scheme == 'https'
1293
+ # Eliminate the OpenSSL "using default DH parameters" warning
1294
+ if File.exist?(File.join(@configdir, 'tpkg', 'dhparams'))
1295
+ dh = OpenSSL::PKey::DH.new(IO.read(File.join(@configdir, 'tpkg', 'dhparams')))
1296
+ Net::HTTP.ssl_context_accessor(:tmp_dh_callback)
1297
+ http.tmp_dh_callback = proc { dh }
1298
+ end
1299
+ http.use_ssl = true
1300
+ if File.exist?(File.join(@configdir, 'tpkg', 'ca.pem'))
1301
+ http.ca_file = File.join(@configdir, 'tpkg', 'ca.pem')
1302
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
1303
+ elsif File.directory?(File.join(@configdir, 'tpkg', 'ca'))
1304
+ http.ca_path = File.join(@configdir, 'tpkg', 'ca')
1305
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
1306
+ end
1307
+ end
1308
+ http.start
1309
+ http
1310
+ end
1311
+
1308
1312
  def source_to_local_directory(source)
1309
1313
  source_as_directory = source.gsub(/[^a-zA-Z0-9]/, '')
1310
1314
  File.join(@sources_directory, source_as_directory)
@@ -1327,22 +1331,22 @@ class Tpkg
1327
1331
  warn "Warning: the source directory #{source} has no metadata.yml file. Try running tpkg -x #{source} first."
1328
1332
  next
1329
1333
  end
1330
-
1334
+
1331
1335
  metadata_contents = File.read(File.join(source, 'metadata.yml'))
1332
1336
  Metadata::get_pkgs_metadata_from_yml_doc(metadata_contents, metadata, source)
1333
1337
  else
1334
1338
  uri = http = localdate = remotedate = localdir = localpath = nil
1335
-
1339
+
1336
1340
  uri = URI.join(source, 'metadata.yml')
1337
- http = Tpkg::gethttp(uri)
1338
-
1341
+ http = gethttp(uri)
1342
+
1339
1343
  # Calculate the path to the local copy of the metadata for this URI
1340
1344
  localdir = source_to_local_directory(source)
1341
1345
  localpath = File.join(localdir, 'metadata.yml')
1342
1346
  if File.exist?(localpath)
1343
1347
  localdate = File.mtime(localpath)
1344
1348
  end
1345
-
1349
+
1346
1350
  # get last modified time of the metadata file from the server
1347
1351
  response = http.head(uri.path)
1348
1352
  case response
@@ -1352,7 +1356,7 @@ class Tpkg
1352
1356
  puts "Error fetching metadata from #{uri}: #{response.body}"
1353
1357
  response.error! # Throws an exception
1354
1358
  end
1355
-
1359
+
1356
1360
  # Fetch the metadata if necessary
1357
1361
  metadata_contents = nil
1358
1362
  if !localdate || remotedate != localdate
@@ -1406,7 +1410,7 @@ class Tpkg
1406
1410
  # Populate our list of available packages for a given package name
1407
1411
  def load_available_packages(name=nil)
1408
1412
  prep_metadata
1409
-
1413
+
1410
1414
  if name
1411
1415
  if !@available_packages[name]
1412
1416
  packages = []
@@ -1417,7 +1421,7 @@ class Tpkg
1417
1421
  end
1418
1422
  end
1419
1423
  @available_packages[name] = packages
1420
-
1424
+
1421
1425
  if @@debug
1422
1426
  puts "Loaded #{@available_packages[name].size} available packages for #{name}"
1423
1427
  end
@@ -1436,7 +1440,7 @@ class Tpkg
1436
1440
  end
1437
1441
  end
1438
1442
  end
1439
-
1443
+
1440
1444
  # Used by load_available_native_packages to stuff all the info about a
1441
1445
  # native package into a hash to match the structure we pass around
1442
1446
  # internally for tpkgs
@@ -1483,7 +1487,7 @@ class Tpkg
1483
1487
  elsif line =~ /^\s*$/
1484
1488
  pkg = pkg_for_native_package(name, version, package_version, yum[:source])
1485
1489
  native_packages << pkg
1486
- name = version = package_version = nil
1490
+ name = version = package_version = nil
1487
1491
  end
1488
1492
  # In the end we ignore the architecture. Anything that
1489
1493
  # shows up in yum should be installable on this box, and
@@ -1783,7 +1787,7 @@ class Tpkg
1783
1787
 
1784
1788
  if File.directory?(@metadata_directory)
1785
1789
  Dir.foreach(@metadata_directory) do |entry|
1786
- next if entry == '.' || entry == '..'
1790
+ next if entry == '.' || entry == '..'
1787
1791
  next if package_files && !package_files.include?(entry)
1788
1792
  file_metadata = FileMetadata::instantiate_from_dir(File.join(@metadata_directory, entry))
1789
1793
  ret[file_metadata[:package_file]] = file_metadata
@@ -1802,8 +1806,8 @@ class Tpkg
1802
1806
  else
1803
1807
  pkgs = []
1804
1808
  if req
1805
- req = req.clone # we're using req as the key for our cache, so it's important
1806
- # that we clone it here. Otherwise, req can be changed later on from
1809
+ req = req.clone # we're using req as the key for our cache, so it's important
1810
+ # that we clone it here. Otherwise, req can be changed later on from
1807
1811
  # the calling method and modify our cache inadvertently
1808
1812
  if req[:type] == :native
1809
1813
  load_available_native_packages(req[:name])
@@ -1904,7 +1908,7 @@ class Tpkg
1904
1908
  end
1905
1909
  def normalize_path(path,root=nil,base=nil)
1906
1910
  root ||= @file_system_root
1907
- base ||= @base
1911
+ base ||= @base
1908
1912
  if path[0,1] == File::SEPARATOR
1909
1913
  normalized_path = File.join(root, path)
1910
1914
  else
@@ -2257,7 +2261,7 @@ class Tpkg
2257
2261
  end
2258
2262
 
2259
2263
  def download(source, path, downloaddir = nil, use_cache = true)
2260
- http = Tpkg::gethttp(URI.parse(source))
2264
+ http = gethttp(URI.parse(source))
2261
2265
  localdir = source_to_local_directory(source)
2262
2266
  localpath = File.join(localdir, File.basename(path))
2263
2267
  # Don't download again if file is already there from previous installation
@@ -2276,10 +2280,10 @@ class Tpkg
2276
2280
  # If downloaddir is specified, then download to that directory. Otherwise,
2277
2281
  # download to default source directory
2278
2282
  localdir = downloaddir || localdir
2279
- if !File.exist?(localdir)
2283
+ if !File.exist?(localdir)
2280
2284
  FileUtils.mkdir_p(localdir)
2281
2285
  end
2282
- localpath = File.join(localdir, File.basename(path))
2286
+ localpath = File.join(localdir, File.basename(path))
2283
2287
  end
2284
2288
  uri = URI.join(source, path)
2285
2289
  tmpfile = Tempfile.new(File.basename(localpath), File.dirname(localpath))
@@ -2319,7 +2323,7 @@ class Tpkg
2319
2323
  installed_path = normalize_path(tpkg_path)
2320
2324
  init_scripts[installed_path] = tpkgfile
2321
2325
  end
2322
- end
2326
+ end
2323
2327
  init_scripts
2324
2328
  end
2325
2329
 
@@ -2353,24 +2357,24 @@ class Tpkg
2353
2357
  Tpkg::get_os =~ /Solaris/
2354
2358
  init_directory = File.join(@file_system_root, 'etc')
2355
2359
  end
2356
-
2360
+
2357
2361
  # in case user specify levels in yaml as string/integer instead of array
2358
2362
  if !levels.kind_of?(Array)
2359
2363
  levels = levels.to_s.split(//)
2360
2364
  end
2361
-
2365
+
2362
2366
  levels.each do |level|
2363
2367
  links[File.join(init_directory, "rc#{level}.d", 'S' + start.to_s + File.basename(installed_path))] = installed_path
2364
2368
  end
2365
2369
  elsif Tpkg::get_os =~ /FreeBSD/
2366
- init_directory = File.join(@file_system_root, 'usr', 'local', 'etc', 'rc.d')
2370
+ init_directory = File.join(@file_system_root, 'usr', 'local', 'etc', 'rc.d')
2367
2371
  if tpkgfile[:init][:levels] && tpkgfile[:init][:levels].empty?
2368
2372
  # User doesn't want the init script linked in to auto-start
2369
2373
  else
2370
2374
  links[File.join(init_directory, File.basename(installed_path))] = installed_path
2371
2375
  end
2372
2376
  else
2373
- raise "No init script support for #{Tpkg::get_os}"
2377
+ warn "No init script support for #{Tpkg::get_os}"
2374
2378
  end
2375
2379
  end
2376
2380
  links
@@ -2380,12 +2384,12 @@ class Tpkg
2380
2384
  # package and where they need to be installed on the system
2381
2385
  def crontab_destinations(metadata)
2382
2386
  destinations = {}
2383
-
2387
+
2384
2388
  # Don't do anything unless we have to
2385
2389
  unless metadata[:files] && metadata[:files][:files]
2386
2390
  return destinations
2387
2391
  end
2388
-
2392
+
2389
2393
  metadata[:files][:files].each do |tpkgfile|
2390
2394
  if tpkgfile[:crontab]
2391
2395
  tpkg_path = tpkgfile[:path]
@@ -2429,7 +2433,7 @@ class Tpkg
2429
2433
  destinations[installed_path][:link] = File.join(@file_system_root, 'etc', 'cron.d', File.basename(installed_path))
2430
2434
  end
2431
2435
  else
2432
- raise "No crontab support for #{Tpkg::get_os}"
2436
+ warn "No crontab support for #{Tpkg::get_os}"
2433
2437
  end
2434
2438
  end
2435
2439
  end
@@ -2479,7 +2483,7 @@ class Tpkg
2479
2483
  def unpack(package_file, options={})
2480
2484
  ret_val = 0
2481
2485
 
2482
- # set env variable to let pre/post install know whether this unpack
2486
+ # set env variable to let pre/post install know whether this unpack
2483
2487
  # is part of an install or upgrade
2484
2488
  if options[:is_doing_upgrade]
2485
2489
  ENV['TPKG_ACTION'] = "upgrade"
@@ -2503,7 +2507,7 @@ class Tpkg
2503
2507
 
2504
2508
  metadata = Tpkg::metadata_from_package(package_file, {:topleveldir => topleveldir})
2505
2509
 
2506
- # Get list of files/directories that already exist in the system. Store their perm/ownership.
2510
+ # Get list of files/directories that already exist in the system. Store their perm/ownership.
2507
2511
  # That way, when we copy over the new files, we can set the new files to have the same perm/owernship.
2508
2512
  conflicting_files = {}
2509
2513
  fip = Tpkg::files_in_package(package_file)
@@ -2539,7 +2543,7 @@ class Tpkg
2539
2543
  end
2540
2544
 
2541
2545
  # Set default dir uid/gid to be same as for file.
2542
- default_dir_uid = default_uid
2546
+ default_dir_uid = default_uid
2543
2547
  default_dir_gid = default_gid
2544
2548
  default_dir_perms = 0755
2545
2549
 
@@ -2565,7 +2569,7 @@ class Tpkg
2565
2569
  if File.directory?(f)
2566
2570
  File.chown(default_dir_uid, default_dir_gid, f)
2567
2571
  else
2568
- File.chown(default_uid, default_gid, f)
2572
+ File.chown(default_uid, default_gid, f)
2569
2573
  end
2570
2574
  rescue Errno::EPERM
2571
2575
  raise if Process.euid == 0
@@ -2637,21 +2641,21 @@ class Tpkg
2637
2641
  (1..3).each do | i |
2638
2642
  begin
2639
2643
  Tpkg::decrypt(metadata[:name], working_path, options[:passphrase], *([tpkgfile[:encrypt][:algorithm]].compact))
2640
- break
2644
+ break
2641
2645
  rescue OpenSSL::CipherError
2642
2646
  @@passphrase = nil
2643
2647
  if i == 3
2644
- raise "Incorrect passphrase."
2648
+ raise "Incorrect passphrase."
2645
2649
  else
2646
2650
  puts "Incorrect passphrase. Try again."
2647
2651
  end
2648
2652
  end
2649
2653
  end
2650
2654
 
2651
- if File.file?(working_path)
2655
+ if File.file?(working_path)
2652
2656
  digest = Digest::SHA256.hexdigest(File.read(working_path))
2653
2657
  # get checksum for the decrypted file. Will be used for creating file_metadata
2654
- checksums_of_decrypted_files[File.expand_path(tpkg_path)] = digest
2658
+ checksums_of_decrypted_files[File.expand_path(tpkg_path)] = digest
2655
2659
  end
2656
2660
  end
2657
2661
  end
@@ -2786,11 +2790,14 @@ class Tpkg
2786
2790
 
2787
2791
  def install_crontabs(metadata)
2788
2792
  crontab_destinations(metadata).each do |crontab, destination|
2793
+ # FIXME: Besides the regex being ugly it is also only going to match on
2794
+ # Linux, need to figure out if there's a reason for that or if this can
2795
+ # be made more generic.
2789
2796
  if !@sudo && (destination[destination.keys.first] =~ /\/var\/spool\/cron/)
2790
- install_crontab_bycmd(metadata, crontab, destination)
2797
+ install_crontab_bycmd(metadata, crontab, destination)
2791
2798
  next
2792
2799
  end
2793
-
2800
+
2794
2801
  begin
2795
2802
  if destination[:link]
2796
2803
  install_crontab_link(metadata, crontab, destination)
@@ -2844,6 +2851,7 @@ class Tpkg
2844
2851
  end
2845
2852
  end
2846
2853
  end
2854
+ # FIXME: Can this be replaced by install_crontab_bycmd?
2847
2855
  def install_crontab_file(metadata, crontab, destination)
2848
2856
  if !File.exist?(File.dirname(destination[:file]))
2849
2857
  FileUtils.mkdir_p(File.dirname(destination[:file]))
@@ -2892,18 +2900,21 @@ class Tpkg
2892
2900
  tmpfh.write(oldcron) unless oldcron.empty?
2893
2901
  tmpfh.puts "### TPKG START - #{@base} - #{File.basename(metadata[:filename].to_s)}"
2894
2902
  tmpfh.write File.readlines(crontab)
2895
- tmpfh.puts "### TPKG END - #{@base} - #{File.basename(metadata[:filename].to_s)}"
2903
+ tmpfh.puts "### TPKG END - #{@base} - #{File.basename(metadata[:filename].to_s)}"
2896
2904
  tmpfh.close
2897
2905
  `crontab #{tmpf}`
2898
2906
  FileUtils.rm(tmpf)
2899
2907
  end
2900
2908
  def remove_crontabs(metadata)
2901
2909
  crontab_destinations(metadata).each do |crontab, destination|
2910
+ # FIXME: Besides the regex being ugly it is also only going to match on
2911
+ # Linux, need to figure out if there's a reason for that or if this can
2912
+ # be made more generic.
2902
2913
  if !@sudo && (destination[destination.keys.first] =~ /\/var\/spool\/cron/)
2903
- remove_crontab_bycmd(metadata, crontab, destination)
2914
+ remove_crontab_bycmd(metadata, crontab, destination)
2904
2915
  next
2905
2916
  end
2906
-
2917
+
2907
2918
  begin
2908
2919
  if destination[:link]
2909
2920
  remove_crontab_link(metadata, crontab, destination)
@@ -2935,6 +2946,7 @@ class Tpkg
2935
2946
  end
2936
2947
  end
2937
2948
  end
2949
+ # FIXME: Can this be replaced by remove_crontab_bycmd?
2938
2950
  def remove_crontab_file(metadata, crontab, destination)
2939
2951
  if File.exist?(destination[:file])
2940
2952
  tmpfile = Tempfile.new(File.basename(destination[:file]), File.dirname(destination[:file]))
@@ -3099,8 +3111,8 @@ class Tpkg
3099
3111
  if file_metadata
3100
3112
  file_metadata[:package_file] = File.basename(package_file)
3101
3113
  file_metadata[:files].each do |file|
3102
- # update file_metadata with user/group ownership and permission
3103
- acl = files_info[file[:path]]
3114
+ # update file_metadata with user/group ownership and permission
3115
+ acl = files_info[file[:path]]
3104
3116
  file.merge!(acl) unless acl.nil?
3105
3117
 
3106
3118
  # update file_metadata with the checksums of decrypted files
@@ -3212,7 +3224,7 @@ class Tpkg
3212
3224
  else # basic package specs ('foo' or 'foo=1.0')
3213
3225
  puts "parse_requests request looks like package spec" if @@debug
3214
3226
 
3215
- # Tpkg::parse_request is a class method and doesn't know where packages are installed.
3227
+ # Tpkg::parse_request is a class method and doesn't know where packages are installed.
3216
3228
  # So we have to tell it ourselves.
3217
3229
  req = Tpkg::parse_request(request, @installed_directory)
3218
3230
  newreqs << req
@@ -3230,14 +3242,14 @@ class Tpkg
3230
3242
 
3231
3243
  # After calling parse_request, we should call this method
3232
3244
  # to check whether or not we can meet the requirements/dependencies
3233
- # of the result packages
3245
+ # of the result packages
3234
3246
  def check_requests(packages)
3235
3247
  all_requests_satisfied = true # whether or not all requests can be satisfied
3236
3248
  errors = [""]
3237
3249
  packages.each do |name, pkgs|
3238
3250
  if pkgs.empty?
3239
3251
  errors << ["Unable to find any packages which satisfy #{name}"]
3240
- all_requests_satisfied = false
3252
+ all_requests_satisfied = false
3241
3253
  next
3242
3254
  end
3243
3255
 
@@ -3268,7 +3280,7 @@ class Tpkg
3268
3280
  if !request_satisfied
3269
3281
  errors << ["Unable to find any packages which satisfy #{name}. Possible error(s):"]
3270
3282
  errors << possible_errors
3271
- all_requests_satisfied = false
3283
+ all_requests_satisfied = false
3272
3284
  end
3273
3285
  end
3274
3286
 
@@ -3373,12 +3385,12 @@ class Tpkg
3373
3385
  puts "The package(s) you're trying to install conflict with the following package(s):"
3374
3386
  conflicting_pkgs = conflicting_pkgs.collect{|pkg|pkg[:metadata][:filename]}
3375
3387
  puts conflicting_pkgs.join("\n")
3376
- if options[:force_replace]
3388
+ if options[:force_replace]
3377
3389
  puts "Attemping to replace the conflicting packages."
3378
3390
  success = remove(conflicting_pkgs)
3379
3391
  return success
3380
3392
  else
3381
- puts "Try removing the conflicting package(s) first, or rerun tpkg with the --force-replace option."
3393
+ puts "Try removing the conflicting package(s) first, or rerun tpkg with the --force-replace option."
3382
3394
  return false
3383
3395
  end
3384
3396
  end
@@ -3442,7 +3454,7 @@ class Tpkg
3442
3454
  end
3443
3455
  true
3444
3456
  end
3445
-
3457
+
3446
3458
  # See parse_requests for format of requests
3447
3459
  def install(requests, passphrase=nil, options={})
3448
3460
  ret_val = 0
@@ -3451,7 +3463,7 @@ class Tpkg
3451
3463
  lock
3452
3464
  parse_requests(requests, requirements, packages)
3453
3465
  check_requests(packages)
3454
-
3466
+
3455
3467
  core_packages = []
3456
3468
  requirements.each do |req|
3457
3469
  core_packages << req[:name] if !core_packages.include?(req[:name])
@@ -3461,7 +3473,6 @@ class Tpkg
3461
3473
  puts "install requirements: #{requirements.inspect}" if @@debug
3462
3474
  puts "install packages: #{packages.inspect}" if @@debug
3463
3475
  puts "install core_packages: #{core_packages.inspect}" if @@debug
3464
- #solution_packages = best_solution(requirements.dup, packages.dup)
3465
3476
  solution_packages = best_solution(requirements, packages, core_packages)
3466
3477
  if !solution_packages
3467
3478
  raise "Unable to resolve dependencies. Try running with --debug for more info"
@@ -3469,26 +3480,26 @@ class Tpkg
3469
3480
 
3470
3481
  success = handle_conflicting_pkgs(installed_packages, solution_packages, options)
3471
3482
  return false if !success
3472
-
3483
+
3473
3484
  if !prompt_for_install(solution_packages, 'installed')
3474
3485
  unlock
3475
3486
  return false
3476
3487
  end
3477
-
3488
+
3478
3489
  # Build an array of metadata of pkgs that are already installed
3479
3490
  # We will use this later on to figure out what new packages have been installed/removed
3480
3491
  # in order to report back to the server
3481
3492
  already_installed_pkgs = metadata_for_installed_packages.collect{|metadata| metadata.to_hash}
3482
-
3493
+
3483
3494
  # Create array of packages (names) we have installed so far
3484
3495
  # We will use it later on to determine the order of how to install the packages
3485
- installed_so_far = installed_packages.collect{|pkg| pkg[:metadata][:name]}
3486
-
3496
+ installed_so_far = installed_packages.collect{|pkg| pkg[:metadata][:name]}
3497
+
3487
3498
  while pkg = solution_packages.shift
3488
3499
  # get dependencies and make sure we install the packages in the correct order
3489
3500
  # based on the dependencies
3490
3501
  dependencies = nil
3491
- if pkg[:metadata][:dependencies]
3502
+ if pkg[:metadata][:dependencies]
3492
3503
  dependencies = pkg[:metadata][:dependencies].collect { |dep| dep[:name] }.compact
3493
3504
  # don't install this pkg right now if its dependencies haven't been installed
3494
3505
  if !dependencies.empty? && !dependencies.to_set.subset?(installed_so_far.to_set)
@@ -3496,7 +3507,7 @@ class Tpkg
3496
3507
  next
3497
3508
  end
3498
3509
  end
3499
-
3510
+
3500
3511
  if pkg[:source] == :currently_installed ||
3501
3512
  pkg[:source] == :native_installed
3502
3513
  # Nothing to do for packages currently installed
@@ -3583,17 +3594,17 @@ class Tpkg
3583
3594
  end
3584
3595
  end
3585
3596
  end
3586
-
3587
- # If we're down here, it means we have installed the package. So go ahead and
3597
+
3598
+ # If we're down here, it means we have installed the package. So go ahead and
3588
3599
  # update the list of packages we installed so far
3589
3600
  installed_so_far << pkg[:metadata][:name]
3590
3601
  end # end while loop
3591
-
3602
+
3592
3603
  # log changes
3593
3604
  currently_installed = metadata_for_installed_packages.collect{|metadata| metadata.to_hash}
3594
3605
  newly_installed = currently_installed - already_installed_pkgs
3595
3606
  log_changes({:newly_installed => newly_installed})
3596
-
3607
+
3597
3608
  # send udpate back to reporting server
3598
3609
  unless @report_server.nil?
3599
3610
  options = {:newly_installed => newly_installed, :currently_installed => currently_installed}
@@ -3602,7 +3613,7 @@ class Tpkg
3602
3613
  unlock
3603
3614
  return ret_val
3604
3615
  end
3605
-
3616
+
3606
3617
  # This method can also be used for doing downgrade
3607
3618
  def upgrade(requests=nil, passphrase=nil, options={})
3608
3619
  downgrade = options[:downgrade] || false
@@ -3626,14 +3637,14 @@ class Tpkg
3626
3637
  additional_requirements = []
3627
3638
  requirements.each do |req|
3628
3639
  core_packages << req[:name] if !core_packages.include?(req[:name])
3629
-
3640
+
3630
3641
  # When doing downgrade, we don't want to include the package being
3631
3642
  # downgrade as the requirements. Otherwise, we won't be able to downgrade it
3632
- unless downgrade
3643
+ unless downgrade
3633
3644
  additional_requirements.concat(
3634
3645
  requirements_for_currently_installed_package(req[:name]))
3635
3646
  end
3636
-
3647
+
3637
3648
  # Initialize the list of possible packages for this req
3638
3649
  if !packages[req[:name]]
3639
3650
  packages[req[:name]] = available_packages_that_meet_requirement(req)
@@ -3644,7 +3655,7 @@ class Tpkg
3644
3655
  pkg[:prefer] = false
3645
3656
  end
3646
3657
  end
3647
-
3658
+
3648
3659
  # Look for pkgs that might depend on the pkg we're upgrading,
3649
3660
  # and add them to our list of requirements. We need to make sure that we can still
3650
3661
  # satisfy the dependency requirements if we were to do the upgrade.
@@ -3682,16 +3693,15 @@ class Tpkg
3682
3693
  puts "upgrade requirements: #{requirements.inspect}" if @@debug
3683
3694
  puts "upgrade packages: #{packages.inspect}" if @@debug
3684
3695
  puts "upgrade core_packages: #{core_packages.inspect}" if @@debug
3685
- #solution_packages = best_solution(requirements.dup, packages.dup)
3686
3696
  solution_packages = best_solution(requirements, packages, core_packages)
3687
-
3697
+
3688
3698
  if solution_packages.nil?
3689
3699
  raise "Unable to find solution for upgrading. Please verify that you specified the correct package(s) for upgrade. Try running with --debug for more info"
3690
3700
  end
3691
-
3701
+
3692
3702
  success = handle_conflicting_pkgs(installed_packages, solution_packages, options)
3693
3703
  return false if !success
3694
-
3704
+
3695
3705
  if downgrade
3696
3706
  prompt_action = 'downgraded'
3697
3707
  else
@@ -3701,7 +3711,7 @@ class Tpkg
3701
3711
  unlock
3702
3712
  return false
3703
3713
  end
3704
-
3714
+
3705
3715
  # Build an array of metadata of pkgs that are already installed
3706
3716
  # We will use this later on to figure out what new packages have been installed/removed
3707
3717
  # in order to report back to the server
@@ -3842,7 +3852,7 @@ class Tpkg
3842
3852
  end
3843
3853
  end
3844
3854
 
3845
- # log changes
3855
+ # log changes
3846
3856
  currently_installed = metadata_for_installed_packages.collect{|metadata| metadata.to_hash}
3847
3857
  newly_installed = currently_installed - already_installed_pkgs
3848
3858
  removed = already_installed_pkgs - currently_installed
@@ -3851,7 +3861,7 @@ class Tpkg
3851
3861
  # send update back to reporting server
3852
3862
  if !has_updates
3853
3863
  puts "No updates available"
3854
- elsif !@report_server.nil?
3864
+ elsif !@report_server.nil?
3855
3865
  options = {:newly_installed => newly_installed, :removed => removed,
3856
3866
  :currently_installed => currently_installed}
3857
3867
  send_update_to_server(options)
@@ -3882,12 +3892,12 @@ class Tpkg
3882
3892
  unlock
3883
3893
  return false
3884
3894
  end
3885
-
3895
+
3886
3896
  # Build an array of metadata of pkgs that are already installed
3887
3897
  # We will use this later on to figure out what new packages have been installed/removed
3888
3898
  # in order to report back to the server
3889
3899
  already_installed_pkgs = metadata_for_installed_packages.collect{|metadata| metadata.to_hash}
3890
-
3900
+
3891
3901
  # If user want to remove all the dependent pkgs, then go ahead
3892
3902
  # and include them in our array of things to remove
3893
3903
  if options[:remove_all_dep]
@@ -3897,7 +3907,7 @@ class Tpkg
3897
3907
  # Get list of dependency prerequisites
3898
3908
  ptr = packages_to_remove | get_prerequisites(packages_to_remove)
3899
3909
  pkg_files_to_remove = ptr.map { |pkg| pkg[:metadata][:filename] }
3900
-
3910
+
3901
3911
  # see if any other packages depends on the ones we're about to remove
3902
3912
  # If so, we can't remove that package + any of its prerequisites
3903
3913
  non_removable_pkg_files = []
@@ -3959,7 +3969,7 @@ class Tpkg
3959
3969
  end
3960
3970
  unless Tpkg::confirm
3961
3971
  unlock
3962
- return false
3972
+ return false
3963
3973
  end
3964
3974
  end
3965
3975
 
@@ -3977,19 +3987,19 @@ class Tpkg
3977
3987
  packages_to_remove.each do |pkg|
3978
3988
  pkgname = pkg[:metadata][:name]
3979
3989
  package_file = File.join(@installed_directory, pkg[:metadata][:filename])
3980
-
3990
+
3981
3991
  topleveldir = Tpkg::package_toplevel_directory(package_file)
3982
3992
  workdir = Tpkg::tempdir(topleveldir, @tmp_directory)
3983
3993
  extract_tpkg_tar_command = Tpkg::cmd_to_extract_tpkg_tar(package_file, topleveldir)
3984
3994
  system("#{extract_tpkg_tar_command} | #{@tar} #{@@taroptions} -C #{workdir} -xpf -")
3985
-
3995
+
3986
3996
  # Run preremove script
3987
3997
  if File.exist?(File.join(workdir, 'tpkg', 'preremove'))
3988
3998
  pwd = Dir.pwd
3989
3999
  # chdir into the working directory so that the user can specify a
3990
4000
  # relative path to their file/script.
3991
4001
  Dir.chdir(File.join(workdir, 'tpkg'))
3992
-
4002
+
3993
4003
  # Warn the user about non-executable files, as system will just
3994
4004
  # silently fail and exit if that's the case.
3995
4005
  if !File.executable?(File.join(workdir, 'tpkg', 'preremove'))
@@ -4000,7 +4010,7 @@ class Tpkg
4000
4010
  else
4001
4011
  system(File.join(workdir, 'tpkg', 'preremove')) || raise("Error: preremove for #{File.basename(package_file)} failed with exit value #{$?.exitstatus}")
4002
4012
  end
4003
-
4013
+
4004
4014
  # Switch back to our previous directory
4005
4015
  Dir.chdir(pwd)
4006
4016
  end
@@ -4014,14 +4024,14 @@ class Tpkg
4014
4024
  run_external(pkg[:metadata][:filename], :remove, external[:name], external[:data])
4015
4025
  end
4016
4026
  end if pkg[:metadata][:externals]
4017
-
4027
+
4018
4028
  # determine which configuration files have been modified
4019
4029
  modified_conf_files = []
4020
4030
  file_metadata = file_metadata_for_installed_packages([pkg[:metadata][:filename]]).values[0]
4021
4031
  file_metadata[:files].each do |file|
4022
4032
  if file[:config]
4023
4033
  # get expected checksum. For files that were encrypted, we're interested in the
4024
- # checksum of the decrypted version
4034
+ # checksum of the decrypted version
4025
4035
  chksum_expected = file[:checksum][:digests].first[:value]
4026
4036
  file[:checksum][:digests].each do | digest |
4027
4037
  if digest[:decrypted] == true
@@ -4035,7 +4045,7 @@ class Tpkg
4035
4045
  end
4036
4046
  end
4037
4047
  end if file_metadata
4038
-
4048
+
4039
4049
  # Remove files
4040
4050
  files_to_remove = conflicting_files(package_file, CHECK_REMOVE)
4041
4051
  # Reverse the order of the files, as directories will appear first
@@ -4065,14 +4075,14 @@ class Tpkg
4065
4075
  warn "Failed to remove file #{file}."
4066
4076
  end
4067
4077
  end
4068
-
4078
+
4069
4079
  # Run postremove script
4070
4080
  if File.exist?(File.join(workdir, 'tpkg', 'postremove'))
4071
4081
  pwd = Dir.pwd
4072
4082
  # chdir into the working directory so that the user can specify a
4073
4083
  # relative path to their file/script.
4074
4084
  Dir.chdir(File.join(workdir, 'tpkg'))
4075
-
4085
+
4076
4086
  # Warn the user about non-executable files, as system will just
4077
4087
  # silently fail and exit if that's the case.
4078
4088
  if !File.executable?(File.join(workdir, 'tpkg', 'postremove'))
@@ -4085,36 +4095,36 @@ class Tpkg
4085
4095
  # desirable. We could reinstall the package's files and raise an
4086
4096
  # exception, but this seems the best approach to me.
4087
4097
  system(File.join(workdir, 'tpkg', 'postremove')) || warn("Warning: postremove for #{File.basename(package_file)} failed with exit value #{$?.exitstatus}")
4088
- ret_val = POSTREMOVE_ERR if $?.exitstatus > 0
4089
-
4098
+ ret_val = POSTREMOVE_ERR if !$?.success?
4099
+
4090
4100
  # Switch back to our previous directory
4091
4101
  Dir.chdir(pwd)
4092
4102
  end
4093
-
4103
+
4094
4104
  File.delete(package_file)
4095
-
4105
+
4096
4106
  # delete metadata dir of this package
4097
4107
  package_metadata_dir = File.join(@metadata_directory, File.basename(package_file, File.extname(package_file)))
4098
4108
  FileUtils.rm_rf(package_metadata_dir)
4099
-
4109
+
4100
4110
  # remove native dependency stub packages if needed
4101
4111
  remove_native_stub_pkg(pkg)
4102
-
4112
+
4103
4113
  # Cleanup
4104
4114
  FileUtils.rm_rf(workdir)
4105
4115
  end
4106
-
4107
- # log changes
4116
+
4117
+ # log changes
4108
4118
  currently_installed = metadata_for_installed_packages.collect{|metadata| metadata.to_hash}
4109
4119
  removed = already_installed_pkgs - currently_installed
4110
4120
  log_changes({:removed => removed})
4111
-
4121
+
4112
4122
  # send update back to reporting server
4113
4123
  unless @report_server.nil? || options[:upgrade]
4114
4124
  options = {:removed => removed, :currently_installed => currently_installed}
4115
4125
  send_update_to_server(options)
4116
4126
  end
4117
-
4127
+
4118
4128
  unlock
4119
4129
  return ret_val
4120
4130
  end
@@ -4126,16 +4136,16 @@ class Tpkg
4126
4136
  requests.each do |request|
4127
4137
  req = Tpkg::parse_request(request)
4128
4138
  packages.concat(installed_packages_that_meet_requirement(req).collect { |pkg| pkg[:metadata][:filename] })
4129
- end
4130
-
4139
+ end
4140
+
4131
4141
  # loop through each package, and verify checksum, owner, group and perm of each file that was installed
4132
4142
  packages.each do | package_file |
4133
4143
  puts "Verifying #{package_file}"
4134
4144
  package_full_name = File.basename(package_file, File.extname(package_file))
4135
-
4145
+
4136
4146
  # Extract checksum.xml from the package
4137
4147
  checksum_xml = nil
4138
-
4148
+
4139
4149
  # get file_metadata from the installed package
4140
4150
  file_metadata = FileMetadata::instantiate_from_dir(File.join(@metadata_directory, package_full_name))
4141
4151
  if !file_metadata
@@ -4144,15 +4154,15 @@ class Tpkg
4144
4154
  results[package_file] = errors
4145
4155
  return results
4146
4156
  end
4147
-
4148
- # verify installed files match their checksum
4157
+
4158
+ # verify installed files match their checksum
4149
4159
  file_metadata[:files].each do |file|
4150
4160
  errors = []
4151
4161
  gid_expected, uid_expected, perms_expected, chksum_expected = nil
4152
4162
  fp = file[:path]
4153
-
4163
+
4154
4164
  # get expected checksum. For files that were encrypted, we're interested in the
4155
- # checksum of the decrypted version
4165
+ # checksum of the decrypted version
4156
4166
  if file[:checksum]
4157
4167
  chksum_expected = file[:checksum][:digests].first[:value]
4158
4168
  file[:checksum][:digests].each do | digest |
@@ -4161,7 +4171,7 @@ class Tpkg
4161
4171
  end
4162
4172
  end
4163
4173
  end
4164
-
4174
+
4165
4175
  # get expected acl values
4166
4176
  if file[:uid]
4167
4177
  uid_expected = file[:uid].to_i
@@ -4171,30 +4181,30 @@ class Tpkg
4171
4181
  end
4172
4182
  if file[:perms]
4173
4183
  perms_expected = file[:perms].to_s
4174
- end
4175
-
4184
+ end
4185
+
4176
4186
  fp = normalize_path(fp)
4177
-
4187
+
4178
4188
  # can't handle symlink
4179
4189
  if File.symlink?(fp)
4180
4190
  next
4181
4191
  end
4182
-
4192
+
4183
4193
  # check if file exist
4184
4194
  if !File.exists?(fp)
4185
4195
  errors << "File is missing"
4186
- else
4187
- # get actual values
4196
+ else
4197
+ # get actual values
4188
4198
  chksum_actual = Digest::SHA256.hexdigest(File.read(fp)) if File.file?(fp)
4189
4199
  uid_actual = File.stat(fp).uid
4190
4200
  gid_actual = File.stat(fp).gid
4191
4201
  perms_actual = File.stat(fp).mode.to_s(8)
4192
4202
  end
4193
-
4203
+
4194
4204
  if !chksum_expected.nil? && !chksum_actual.nil? && chksum_expected != chksum_actual
4195
4205
  errors << "Checksum doesn't match (Expected: #{chksum_expected}, Actual: #{chksum_actual}"
4196
- end
4197
-
4206
+ end
4207
+
4198
4208
  if !uid_expected.nil? && !uid_actual.nil? && uid_expected != uid_actual
4199
4209
  errors << "uid doesn't match (Expected: #{uid_expected}, Actual: #{uid_actual}) "
4200
4210
  end
@@ -4212,7 +4222,7 @@ class Tpkg
4212
4222
  end
4213
4223
  return results
4214
4224
  end
4215
-
4225
+
4216
4226
  def execute_init(options, *moreoptions)
4217
4227
  ret_val = 0
4218
4228
  packages_to_execute_on = []
@@ -4224,7 +4234,7 @@ class Tpkg
4224
4234
  action = moreoptions[0]
4225
4235
  requested_packages = options
4226
4236
  end
4227
-
4237
+
4228
4238
  # if user specified no packages, then assume all
4229
4239
  if requested_packages.nil?
4230
4240
  packages_to_execute_on = installed_packages_that_meet_requirement(nil)
@@ -4235,20 +4245,20 @@ class Tpkg
4235
4245
  packages_to_execute_on.concat(installed_packages_that_meet_requirement(req))
4236
4246
  end
4237
4247
  end
4238
-
4248
+
4239
4249
  if packages_to_execute_on.empty?
4240
4250
  warn "Warning: Unable to find package(s) \"#{requested_packages.join(",")}\"."
4241
- else
4251
+ else
4242
4252
  packages_to_execute_on.each do |pkg|
4243
4253
  ret_val |= execute_init_for_package(pkg, action, requested_init_scripts)
4244
- end
4254
+ end
4245
4255
  end
4246
4256
  return ret_val
4247
4257
  end
4248
-
4258
+
4249
4259
  def execute_init_for_package(pkg, action, requested_init_scripts = nil)
4250
4260
  ret_val = 0
4251
-
4261
+
4252
4262
  # Get init scripts metadata for the given package
4253
4263
  init_scripts_metadata = init_scripts(pkg[:metadata])
4254
4264
  # warn if there's no init script and then return
@@ -4256,7 +4266,7 @@ class Tpkg
4256
4266
  warn "Warning: There is no init script for #{pkg[:metadata][:name]}."
4257
4267
  return 1
4258
4268
  end
4259
-
4269
+
4260
4270
  # convert the init scripts metadata to an array of { path => value, start => value}
4261
4271
  # so that we can order them based on their start value. This is necessary because
4262
4272
  # we need to execute the init scripts in correct order.
@@ -4265,30 +4275,30 @@ class Tpkg
4265
4275
  init = {}
4266
4276
  init[:path] = installed_path
4267
4277
  init[:start] = init_info[:init][:start] || 0
4268
-
4278
+
4269
4279
  # if user requests specific init scripts, then only include those
4270
- if requested_init_scripts.nil? or
4280
+ if requested_init_scripts.nil? or
4271
4281
  requested_init_scripts && requested_init_scripts.include?(File.basename(installed_path))
4272
- init_scripts << init
4282
+ init_scripts << init
4273
4283
  end
4274
4284
  end
4275
-
4285
+
4276
4286
  if requested_init_scripts && init_scripts.empty?
4277
4287
  warn "Warning: There are no init scripts that satisfy your request: #{requested_init_scripts.inspect} for package #{pkg[:metadata][:name]}."
4278
4288
  end
4279
4289
 
4280
- # Reverse order if doing stop.
4290
+ # Reverse order if doing stop.
4281
4291
  if action == "stop"
4282
4292
  ordered_init_scripts = init_scripts.sort{ |a,b| b[:start] <=> a[:start] }
4283
4293
  else
4284
4294
  ordered_init_scripts = init_scripts.sort{ |a,b| a[:start] <=> b[:start] }
4285
4295
  end
4286
-
4296
+
4287
4297
  ordered_init_scripts.each do |init_script|
4288
4298
  installed_path = init_script[:path]
4289
4299
  system("#{installed_path} #{action}")
4290
- ret_val = INITSCRIPT_ERR if $?.exitstatus > 0
4291
- end
4300
+ ret_val = INITSCRIPT_ERR if !$?.success?
4301
+ end
4292
4302
  return ret_val
4293
4303
  end
4294
4304
 
@@ -4324,7 +4334,7 @@ class Tpkg
4324
4334
  File.open(@lock_pid_file) { |file| lockpid = file.gets.chomp }
4325
4335
  rescue Errno::ENOENT
4326
4336
  end
4327
-
4337
+
4328
4338
  # check that the process is actually running
4329
4339
  # if not, clean up old lock and attemp to obtain lock again
4330
4340
  if Tpkg::process_running?(lockpid)
@@ -4335,7 +4345,7 @@ class Tpkg
4335
4345
  end
4336
4346
  end
4337
4347
  end
4338
-
4348
+
4339
4349
  def unlock
4340
4350
  if @locks == 0
4341
4351
  warn "unlock called but not locked, that probably shouldn't happen"
@@ -4346,16 +4356,16 @@ class Tpkg
4346
4356
  FileUtils.rm_rf(@lock_directory)
4347
4357
  end
4348
4358
  end
4349
-
4359
+
4350
4360
  # Build a dependency map of currently installed packages
4351
- # For example, if we have pkgB and pkgC which depends on pkgA, then
4361
+ # For example, if we have pkgB and pkgC which depends on pkgA, then
4352
4362
  # the dependency map would look like this:
4353
4363
  # "pkgA.tpkg" => [{pkgB metadata}, {pkgC metadata}]
4354
4364
  def get_dependency_mapping
4355
4365
  dependency_mapping = {}
4356
4366
  installed_packages.each do | pkg |
4357
4367
  metadata = pkg[:metadata]
4358
-
4368
+
4359
4369
  # Get list of pkgs that this pkg depends on
4360
4370
  next if metadata[:dependencies].nil?
4361
4371
  depended_on = []
@@ -4363,16 +4373,16 @@ class Tpkg
4363
4373
  next if req[:type] == :native
4364
4374
  depended_on |= installed_packages_that_meet_requirement(req)
4365
4375
  end
4366
-
4376
+
4367
4377
  # populate the depencency map
4368
4378
  depended_on.each do | req_pkg |
4369
- dependency_mapping[req_pkg[:metadata][:filename]] ||= []
4379
+ dependency_mapping[req_pkg[:metadata][:filename]] ||= []
4370
4380
  dependency_mapping[req_pkg[:metadata][:filename]] << pkg
4371
4381
  end
4372
4382
  end
4373
4383
  return dependency_mapping
4374
4384
  end
4375
-
4385
+
4376
4386
  # Given a list of packages, return a list of dependents packages
4377
4387
  def get_dependents(pkgs)
4378
4388
  dependents = []
@@ -4383,10 +4393,10 @@ class Tpkg
4383
4393
  next if pkgs.nil?
4384
4394
  dependents |= pkgs
4385
4395
  to_check |= pkgs.map { |pkg| pkg[:metadata][:filename] }
4386
- end
4396
+ end
4387
4397
  return dependents
4388
4398
  end
4389
-
4399
+
4390
4400
  # Given a list of packages, return a list of all their prerequisite dependencies
4391
4401
  # Example: If pkgA depends on pkgB, and pkgB depends on pkgC, then calling this
4392
4402
  # method on pkgA will returns pkgB and pkgC
@@ -4404,7 +4414,7 @@ class Tpkg
4404
4414
  end
4405
4415
  return pre_reqs
4406
4416
  end
4407
-
4417
+
4408
4418
  # print out history packages installation/remove
4409
4419
  def installation_history
4410
4420
  if !File.exists?(File.join(@log_directory,'changes.log'))
@@ -4412,15 +4422,15 @@ class Tpkg
4412
4422
  return GENERIC_ERR
4413
4423
  end
4414
4424
  IO.foreach(File.join(@log_directory,'changes.log')) do |line|
4415
- puts line
4425
+ puts line
4416
4426
  end
4417
4427
  end
4418
-
4428
+
4419
4429
  # Download packages that meet the requests specified by the user.
4420
4430
  # Packages are downloaded into the current directory or into the directory
4421
4431
  # specified in options[:out]
4422
4432
  def download_pkgs(requests, options={})
4423
- if options[:out]
4433
+ if options[:out]
4424
4434
  if !File.exists?(options[:out])
4425
4435
  FileUtils.mkdir_p(options[:out])
4426
4436
  elsif !File.directory?(options[:out])
@@ -4429,32 +4439,32 @@ class Tpkg
4429
4439
  end
4430
4440
  end
4431
4441
  output_dir = options[:out] || Dir.pwd
4432
-
4442
+
4433
4443
  requirements = []
4434
4444
  packages = {}
4435
4445
  original_dir = Dir.pwd
4436
-
4446
+
4437
4447
  workdir = Tpkg::tempdir("tpkg_download")
4438
4448
  Dir.chdir(workdir)
4439
4449
  parse_requests(requests, requirements, packages)
4440
4450
  packages = packages.values.flatten
4441
4451
  if packages.size < 1
4442
4452
  puts "Unable to find any packages that satisfy your request. Try running with --debug for more info"
4443
- Dir.chdir(original_dir)
4453
+ Dir.chdir(original_dir)
4444
4454
  return GENERIC_ERR
4445
4455
  end
4446
-
4456
+
4447
4457
  # Confirm with user what packages will be downloaded
4448
4458
  packages.delete_if{|pkg|pkg[:source] !~ /^http/}
4449
4459
  puts "The following packages will be downloaded:"
4450
4460
  packages.each do |pkg|
4451
4461
  puts "#{pkg[:metadata][:filename]} (source: #{pkg[:source]})"
4452
4462
  end
4453
- if @@prompt && !Tpkg::confirm
4454
- Dir.chdir(original_dir)
4463
+ if @@prompt && !Tpkg::confirm
4464
+ Dir.chdir(original_dir)
4455
4465
  return 0
4456
4466
  end
4457
-
4467
+
4458
4468
  err_code = 0
4459
4469
  puts "Downloading to #{output_dir}"
4460
4470
  packages.each do |pkg|
@@ -4468,21 +4478,21 @@ class Tpkg
4468
4478
  err_code = GENERIC_ERR
4469
4479
  end
4470
4480
  end
4471
-
4481
+
4472
4482
  # clean up working directory
4473
4483
  FileUtils.rm_rf(workdir)
4474
4484
 
4475
- Dir.chdir(original_dir)
4485
+ Dir.chdir(original_dir)
4476
4486
  return err_code
4477
4487
  end
4478
-
4488
+
4479
4489
  # TODO: figure out what other methods above can be turned into protected methods
4480
4490
  protected
4481
4491
  # log changes of pkgs that were installed/removed
4482
4492
  def log_changes(options={})
4483
4493
  msg = ""
4484
4494
  user = Etc.getlogin || Etc.getpwuid(Process.uid).name
4485
- newly_installed = removed = []
4495
+ newly_installed = removed = []
4486
4496
  newly_installed = options[:newly_installed] if options[:newly_installed]
4487
4497
  removed = options[:removed] if options[:removed]
4488
4498
  removed.each do |pkg|
@@ -4497,7 +4507,7 @@ class Tpkg
4497
4507
  File.open(File.join(@log_directory,'changes.log'), 'a') {|f| f.write(msg) }
4498
4508
  end
4499
4509
  end
4500
-
4510
+
4501
4511
  def send_update_to_server(options={})
4502
4512
  request = {"client"=>Facter['fqdn'].value}
4503
4513
  request[:user] = Etc.getlogin || Etc.getpwuid(Process.uid).name
@@ -4518,12 +4528,12 @@ class Tpkg
4518
4528
  already_installed = currently_installed
4519
4529
  end
4520
4530
  request[:already_installed] = URI.escape(YAML.dump(already_installed))
4521
-
4531
+
4522
4532
  if options[:removed]
4523
4533
  removed = options[:removed]
4524
4534
  request[:removed] = URI.escape(YAML.dump(removed))
4525
4535
  end
4526
-
4536
+
4527
4537
  begin
4528
4538
  response = nil
4529
4539
  # Need to set timeout otherwise tpkg can hang for a long time when having
@@ -4531,12 +4541,12 @@ class Tpkg
4531
4541
  # I can't seem get net-ssh timeout to work so we'll just handle the timeout ourselves
4532
4542
  timeout(CONNECTION_TIMEOUT) do
4533
4543
  update_uri = URI.parse("#{@report_server}")
4534
- http = Tpkg::gethttp(update_uri)
4544
+ http = gethttp(update_uri)
4535
4545
  post = Net::HTTP::Post.new(update_uri.path)
4536
4546
  post.set_form_data(request)
4537
4547
  response = http.request(post)
4538
4548
  end
4539
-
4549
+
4540
4550
  case response
4541
4551
  when Net::HTTPSuccess
4542
4552
  puts "Successfully send update to reporter server"
@@ -4548,24 +4558,24 @@ class Tpkg
4548
4558
  end
4549
4559
  rescue Timeout::Error
4550
4560
  puts "Timed out when trying to send update to reporter server"
4551
- rescue
4561
+ rescue
4552
4562
  puts "Failed to send update to reporter server"
4553
4563
  end
4554
4564
  end
4555
-
4556
- # create and install native stub package if needed
4557
- # this stub package helps prevent user from removing native packages that
4558
- # our tpkg packages depend on
4565
+
4566
+ # create and install native stub package if needed
4567
+ # this stub package helps prevent user from removing native packages that
4568
+ # our tpkg packages depend on
4559
4569
  def stub_native_pkg(pkg)
4560
4570
  # gather all of the native dependencies
4561
4571
  native_deps = pkg[:metadata].get_native_deps
4562
-
4572
+
4563
4573
  return if native_deps.nil? or native_deps.empty?
4564
4574
 
4565
4575
  if Tpkg::get_os =~ /RedHat|CentOS|Fedora/
4566
4576
  rpm = create_rpm("stub_for_#{pkg[:metadata][:name]}", native_deps)
4567
4577
  return if rpm.nil?
4568
-
4578
+
4569
4579
  # install the rpm
4570
4580
  cmd = "rpm -i #{rpm}"
4571
4581
  puts cmd if @@debug
@@ -4577,16 +4587,16 @@ class Tpkg
4577
4587
  # TODO: support other OSes
4578
4588
  end
4579
4589
  end
4580
-
4590
+
4581
4591
  # remove the native dependency stub packages if there's any
4582
4592
  def remove_native_stub_pkg(pkg)
4583
4593
  # Don't have to do anything if this package has no native dependencies
4584
4594
  native_deps = pkg[:metadata].get_native_deps
4585
4595
  return if native_deps.nil? or native_deps.empty?
4586
-
4596
+
4587
4597
  # the convention is that stub package is named as "stub_for_pkgname"
4588
4598
  stub_pkg_name = "stub_for_#{pkg[:metadata][:name]}"
4589
-
4599
+
4590
4600
  if Tpkg::get_os =~ /RedHat|CentOS|Fedora/
4591
4601
  cmd = "yum -y remove #{stub_pkg_name}"
4592
4602
  puts cmd if @@debug
@@ -4598,16 +4608,16 @@ class Tpkg
4598
4608
  # TODO: support other OSes
4599
4609
  end
4600
4610
  end
4601
-
4611
+
4602
4612
  def create_rpm(name, deps=[])
4603
4613
  # setup directories for rpmbuild
4604
4614
  topdir = Tpkg::tempdir('rpmbuild')
4605
4615
  %w[BUILD RPMS SOURCES SPECS SRPMS].each do |dir|
4606
4616
  FileUtils.mkdir_p(File.join(topdir, dir))
4607
4617
  end
4608
-
4618
+
4609
4619
  dep_list = deps.collect{|dep|dep[:name]}.join(",")
4610
-
4620
+
4611
4621
  # create rpm spec file
4612
4622
  spec = <<-EOS.gsub(/^\s+/, "")
4613
4623
  Name: #{name}
@@ -4627,14 +4637,14 @@ class Tpkg
4627
4637
  File.open(spec_file, 'w') do |file|
4628
4638
  file.puts(spec)
4629
4639
  end
4630
-
4640
+
4631
4641
  # run rpmbuild
4632
4642
  system("rpmbuild -bb --define '_topdir #{topdir}' #{spec_file}")
4633
4643
  if !$?.success?
4634
4644
  warn "Warning: Failed to create native stub package for #{name}"
4635
4645
  return nil
4636
4646
  end
4637
-
4647
+
4638
4648
  # copy result over to tmpfile
4639
4649
  result = File.join(topdir, 'RPMS', 'noarch', "#{name}-1-1.noarch.rpm")
4640
4650
  rpm = nil
@@ -4643,10 +4653,10 @@ class Tpkg
4643
4653
  FileUtils.cp(result, tmpfile.path)
4644
4654
  rpm = tmpfile.path
4645
4655
  end
4646
-
4656
+
4647
4657
  # cleanup
4648
4658
  FileUtils.rm_rf(topdir)
4649
-
4659
+
4650
4660
  return rpm
4651
4661
  end
4652
4662
  end