instrumental_tools 1.0.0 → 1.1.3

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 (36) hide show
  1. checksums.yaml +4 -4
  2. data/BUILD.md +15 -0
  3. data/CHANGELOG.md +17 -1
  4. data/CUSTOM_METRICS.md +4 -0
  5. data/INSTALL.md +12 -7
  6. data/README.md +2 -2
  7. data/Rakefile +202 -64
  8. data/TEST.md +18 -0
  9. data/bin/instrument_server +31 -15
  10. data/chef/.kitchen.yml +10 -1
  11. data/chef/instrumental_tools/attributes/default.rb +29 -2
  12. data/chef/instrumental_tools/recipes/default.rb +188 -17
  13. data/chef/instrumental_tools/templates/default/instrument_server.erb +46 -0
  14. data/chef/instrumental_tools/templates/{instrumental.yml.erb → default/instrumental.yml.erb} +6 -6
  15. data/chef/omnibus.sh +27 -0
  16. data/conf/instrumental.yml +6 -6
  17. data/examples/README.md +1 -0
  18. data/examples/redis/README.md +10 -0
  19. data/examples/redis/redis_info.sh +10 -0
  20. data/ext/Rakefile +1 -0
  21. data/ext/mkrf_conf.rb +18 -0
  22. data/instrumental_tools.gemspec +8 -2
  23. data/lib/instrumental_tools/metric_script_executor.rb +45 -6
  24. data/lib/instrumental_tools/server_controller.rb +4 -1
  25. data/lib/instrumental_tools/system_inspector.rb +3 -0
  26. data/lib/instrumental_tools/system_inspector/win32.rb +85 -0
  27. data/lib/instrumental_tools/version.rb +1 -1
  28. data/test/integration/default/serverspec/instrumental_tools_spec.rb +32 -16
  29. data/win32/Makefile +18 -0
  30. data/win32/installer.nsis.erb +242 -0
  31. data/win32/logo.ico +0 -0
  32. data/win32/src/instrumental/InstrumentServerProcess.cs +147 -0
  33. data/win32/src/instrumental/InstrumentServerProcessWorker.cs +89 -0
  34. data/win32/src/instrumental/InstrumentServerService.cs +146 -0
  35. data/win32/src/instrumental/InstrumentServerServiceInstaller.cs +60 -0
  36. metadata +36 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8871b4d7d488bafeb4a58f5d82caad26ba139c00
4
- data.tar.gz: 5901bebe60f6303dbb00cacba6f376ffa1b61c88
3
+ metadata.gz: 2a27d4c996ef62de7323120f50798c5162414783
4
+ data.tar.gz: e9cef00763a959a8038d740d899e9ff89d1a1c45
5
5
  SHA512:
6
- metadata.gz: 71a0be3021518f008517cfbf8d0802ca80de6c3362df63f9d70aabaf0a86eac6341fec2018f7c4de1047b0e4e30639f155085182d35c3e59b7b0f23f8a55081c
7
- data.tar.gz: 5c55425bdb4b2cd64adee1c7aa363d918bbb18175a106796cd29145dc3b17d69be1adba0e5f94af61ee864d98af8665a3b73143420169b2b804e1960207f82b8
6
+ metadata.gz: d4f571bc227d0cf8e2668337542bfb8de90ac11e57964decb105457257949483befd35f3ee1c281b6db33ca64a48deedf803e2f95535313427e2e357df2621ca
7
+ data.tar.gz: 670224fe2b26100ea685880bae31f9440f0d24a39604f3f27779dc0c71dd2bdc333f784e844c9e1d5bce37aec3472abda5adccd8402f6bcab86dd85fb421628d
data/BUILD.md CHANGED
@@ -48,3 +48,18 @@ rake package:osx:tarball
48
48
  ```
49
49
 
50
50
  On release, the tarball should be uploaded to the Github releases page and linked to from the main README.md.
51
+
52
+ ## `exe` packages
53
+
54
+ In order to build the Windows installer, you'll need to have [NSIS](http://nsis.sourceforge.net/Main_Page) and [Mono](http://www.mono-project.com/) installed. If you're using Mac OS X, run the following commands:
55
+
56
+ ```
57
+ brew install makensis
58
+ brew install mono
59
+ ```
60
+
61
+ To build the installer:
62
+
63
+ ```
64
+ rake package:win32:package
65
+ ```
@@ -1,4 +1,20 @@
1
- ### 1.0.0 [?]
1
+ ### 1.1.3 [August 17, 2015]
2
+ * Fix gem installation of tools
3
+ * Use latest Instrumental Agent
4
+
5
+ ### 1.1.1 [August 3rd, 2015]
6
+ * Defaults to secure protocol when connecting
7
+
8
+ ### 1.1.0 [August 3rd, 2015]
9
+ * Windows support
10
+ * Windows installer
11
+ * Updated Chef scripts to use remote_file
12
+ * Updated Chef script to support Windows
13
+ * Use latest `instrumental_agent` gem
14
+ * Add Powershell integration for custom metrics
15
+ * Process now disconnects from Instrumental when idling between reports
16
+
17
+ ### 1.0.0 [May 21st, 2015]
2
18
  * Configurable pid and log file locations
3
19
  * Pid and log file default to $HOME
4
20
  * Process control commands do not require API key
@@ -62,3 +62,7 @@ You may output error information on `STDERR` of your process, and it will be out
62
62
  ### Timeouts
63
63
 
64
64
  Your script is responsible for managing timeouts. The `instrument_server` process will not attempt to terminate your process for you.
65
+
66
+ ### Powershell Integration
67
+
68
+ Windows administrators may create Powershell scripts following the above guidelines. You should write your output to the STDOUT stream using `Write-Output`. The file extension of the Powershell script must be `.ps1` in order for it to be executd by the Instrument Server process.
data/INSTALL.md CHANGED
@@ -4,13 +4,14 @@
4
4
 
5
5
  Prebuilt `deb` and `rpm` packages are available via the [packagecloud.io](https://packagecloud.io/) service. These files are also available to download directly:
6
6
 
7
- * 64-bit Debian package (Ubuntu, Debian) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_amd64.deb](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_amd64.deb)
8
- * 32-bit Debian package (Ubuntu, Debian) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_i386.deb](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_i386.deb)
9
- * 64-bit RPM package (RHEL, Amazon AMI) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_amd64.rpm](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_amd64.rpm)
10
- * 32-bit RPM package (RHEL, Amazon AMI) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_i386.rpm](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_i386.rpm)
11
- * 64-bit Linux tarball (CoreOS, etc.) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_linux-x86_64.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_linux-x86_64.tar.gz)
12
- * 32-bit Linux tarball (CoreOS, etc.) [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_linux-x86.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_linux-x86.tar.gz)
13
- * 64-bit Mac OS X tarball [https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_osx.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.0.0/instrumental-tools_1.0.0_osx.tar.gz)
7
+ * 64-bit Debian package (Ubuntu, Debian) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_amd64.deb](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_amd64.deb)
8
+ * 32-bit Debian package (Ubuntu, Debian) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_i386.deb](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_i386.deb)
9
+ * 64-bit RPM package (RHEL, Amazon AMI) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_amd64.rpm](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_amd64.rpm)
10
+ * 32-bit RPM package (RHEL, Amazon AMI) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_i386.rpm](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_i386.rpm)
11
+ * 64-bit Linux tarball (CoreOS, etc.) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_linux-x86_64.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_linux-x86_64.tar.gz)
12
+ * 32-bit Linux tarball (CoreOS, etc.) [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_linux-x86.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_linux-x86.tar.gz)
13
+ * Windows installer [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_win32.exe](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_win32.exe)
14
+ * 64-bit Mac OS X tarball [https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_osx.tar.gz](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_osx.tar.gz)
14
15
 
15
16
  # Ubuntu
16
17
 
@@ -45,6 +46,10 @@ sudo tar -zxvf ./instrumental-tools_1.0.0_linux-x86_64.tar.gz -C /opt/instrument
45
46
  sudo cp /opt/instrumental-tools/etc/instrumental.yml /etc/
46
47
  ```
47
48
 
49
+ # Windows
50
+
51
+ Download the [installer](https://s3.amazonaws.com/instrumental-tools/1.1.2/instrumental-tools_1.1.2_win32.exe) and run it, adding in your API key when prompted.
52
+
48
53
  # RubyGems
49
54
 
50
55
  ```sh
data/README.md CHANGED
@@ -4,7 +4,7 @@ A collection of tools for monitoring servers with Instrumental ([www.instrumenta
4
4
 
5
5
  ## Operating System Support
6
6
 
7
- `instrumental_tools` is currently officially supported on 32-bit and 64-bit Linux, as well as Mac OS X. There are prebuilt packages available for Debian and RHEL-based systems.
7
+ `instrumental_tools` is currently officially supported on 32-bit and 64-bit Linux, Windows systems and Mac OS X. There are prebuilt packages available for Debian, RHEL and Win32 systems.
8
8
 
9
9
  ## Installation
10
10
 
@@ -90,7 +90,7 @@ something like this in your capistrano configuration:
90
90
  namespaces[:instrumental].tasks[:restart_instrument_server].options[:roles] = [:web, :worker]
91
91
  ```
92
92
 
93
- ### NOTEs
93
+ ### NOTES
94
94
 
95
95
  Mac OS users: Due to a bug in Ruby, instrument_server can occasionally deadlock ([bug report](http://bugs.ruby-lang.org/issues/5811)).
96
96
 
data/Rakefile CHANGED
@@ -2,9 +2,13 @@
2
2
  require 'bundler/gem_tasks'
3
3
  require 'etc'
4
4
  require 'fileutils'
5
+ require 'find'
5
6
  require 'socket'
7
+ require 'tempfile'
6
8
  require 'yaml'
7
9
 
10
+ task :default => 'build'
11
+
8
12
  PACKAGE_CATEGORY = "Utilities"
9
13
  PACKAGECLOUD_REPO = "expectedbehavior/instrumental"
10
14
  CONFIG_DIR = "conf"
@@ -14,7 +18,7 @@ GEMSPEC = Bundler::GemHelper.instance.gemspec
14
18
  SPEC_PATH = Bundler::GemHelper.instance.spec_path
15
19
  PACKAGE_NAME = GEMSPEC.name.gsub("_", "-") # Debian packages cannot include _ in name
16
20
  VERSION = GEMSPEC.version
17
- TRAVELING_RUBY_VERSION = "20150210-2.1.5"
21
+ TRAVELING_RUBY_VERSION = "20150517-2.1.6"
18
22
  TRAVELING_RUBY_FILE = "packaging/traveling-ruby-#{TRAVELING_RUBY_VERSION}-%s.tar.gz"
19
23
  DEST_DIR = File.join("/opt/", PACKAGE_NAME)
20
24
  PACKAGE_OUTPUT_NAME = [PACKAGE_NAME, VERSION].join("_")
@@ -33,46 +37,81 @@ EXTRA_ARGS = {
33
37
  }
34
38
 
35
39
 
40
+ WRAPPER_SCRIPT_SHELL = <<-EOSCRIPT
41
+ #!/bin/bash
42
+ set -e
43
+
44
+ # Figure out where this script is located.
45
+ SELFDIR="`dirname \"$0\"`"
46
+ SELFDIR="`cd \"$SELFDIR\" && pwd`"
47
+
48
+ # Tell Bundler where the Gemfile and gems are.
49
+ export BUNDLE_GEMFILE="$SELFDIR/lib/vendor/Gemfile"
50
+ unset BUNDLE_IGNORE_CONFIG
51
+
52
+ # Run the actual app using the bundled Ruby interpreter.
53
+ exec "$SELFDIR/lib/ruby/bin/ruby" -rbundler/setup "$SELFDIR/lib/app/%s" "$@"
54
+ EOSCRIPT
55
+
56
+ WRAPPER_SCRIPT_BAT = <<-EOSCRIPT
57
+ @echo off
58
+
59
+ :: Tell Bundler where the Gemfile and gems are.
60
+ set "BUNDLE_GEMFILE=%%~dp0\\lib\\vendor\\Gemfile"
61
+ set BUNDLE_IGNORE_CONFIG=
62
+
63
+ :: Run the actual app using the bundled Ruby interpreter, with Bundler activated.
64
+ @"%%~dp0\\lib\\ruby\\bin\\ruby.bat" -rbundler/setup "%%~dp0\\lib\\app\\%s" %%*
65
+ EOSCRIPT
66
+
36
67
  ARCHITECTURES = {
37
68
  'linux-x86' => {
38
69
  runtime: TRAVELING_RUBY_FILE % "linux-x86",
39
70
  arch: "i386",
40
71
  packages: %w{deb rpm},
41
72
  platform: "linux",
42
- packagecloud: true
73
+ packagecloud: true,
74
+ wrapper: WRAPPER_SCRIPT_SHELL,
75
+ separator: '/',
76
+ package_from_compressed: true,
77
+ dest_dir: DEST_DIR
43
78
  },
44
79
  'linux-x86_64' => {
45
80
  runtime: TRAVELING_RUBY_FILE % "linux-x86_64",
46
81
  arch: "amd64",
47
82
  packages: %w{deb rpm},
48
83
  platform: "linux",
49
- packagecloud: true
84
+ packagecloud: true,
85
+ wrapper: WRAPPER_SCRIPT_SHELL,
86
+ separator: '/',
87
+ package_from_compressed: true,
88
+ dest_dir: DEST_DIR
50
89
  },
51
90
  'osx' => {
52
91
  runtime: TRAVELING_RUBY_FILE % "osx",
53
92
  arch: "x86_64",
54
93
  packages: [],
55
94
  platform: "darwin",
56
- packagecloud: false
95
+ packagecloud: false,
96
+ wrapper: WRAPPER_SCRIPT_SHELL,
97
+ separator: '/',
98
+ dest_dir: DEST_DIR
99
+ },
100
+ 'win32' => {
101
+ runtime: TRAVELING_RUBY_FILE % "win32",
102
+ packages: %w{exe},
103
+ packagecloud: false,
104
+ compress_format: 'zip',
105
+ wrapper: WRAPPER_SCRIPT_BAT,
106
+ separator: '\\',
107
+ extension: '.bat',
108
+ package_from_compressed: false,
109
+ dest_dir: ''
57
110
  }
58
111
  }
59
112
 
60
113
 
61
- WRAPPER_SCRIPT = <<-EOSCRIPT
62
- #!/bin/bash
63
- set -e
64
-
65
- # Figure out where this script is located.
66
- SELFDIR="`dirname \"$0\"`"
67
- SELFDIR="`cd \"$SELFDIR\" && pwd`"
68
-
69
- # Tell Bundler where the Gemfile and gems are.
70
- export BUNDLE_GEMFILE="$SELFDIR/lib/vendor/Gemfile"
71
- unset BUNDLE_IGNORE_CONFIG
72
114
 
73
- # Run the actual app using the bundled Ruby interpreter.
74
- exec "$SELFDIR/lib/ruby/bin/ruby" -rbundler/setup "$SELFDIR/lib/app/%s" "$@"
75
- EOSCRIPT
76
115
 
77
116
  BUNDLE_CONFIG = <<-EOBUNDLECONFIG
78
117
  BUNDLE_PATH: .
@@ -94,19 +133,27 @@ ARCHITECTURES.each do |name, config|
94
133
  task name => ["%s:package" % name]
95
134
  else
96
135
  desc "Package your app for %s" % name
97
- task name => ["%s:tarball" % name]
136
+ task name => ["%s:compress" % name]
98
137
  end
99
138
 
100
139
  namespace name do
101
- desc "Create a tarball for %s" % name
102
- task "tarball" => [:bundle_install, config[:runtime]] do
103
- create_tarball(create_directory_bundle(name))
140
+ desc "Create a compressed package for %s" % name
141
+ task "compress" do
142
+ task("package:bundle_install").invoke(name.to_sym)
143
+ task(config[:runtime]).invoke
144
+ create_compressed_package(create_directory_bundle(name, config[:wrapper], config[:separator], config[:extension]), config[:compress_format])
104
145
  end
105
146
 
106
147
  if has_packaging
107
148
  desc "Create packages (%s) for %s" % [config[:packages].join(","), name]
108
- task "package" => [:bundle_install, config[:runtime]] do
109
- create_packages(create_tarball(create_directory_bundle(name, DEST_DIR)), config[:platform], config[:arch], config[:packages])
149
+ task "package" do
150
+ task("package:bundle_install").invoke(name.to_sym)
151
+ task(config[:runtime]).invoke
152
+ destination = create_directory_bundle(name, config[:wrapper], config[:separator], config[:extension], config[:dest_dir])
153
+ if config[:package_from_compressed]
154
+ destination = create_compressed_package(destination, config[:compress_format])
155
+ end
156
+ create_packages(destination, config[:platform], config[:arch], config[:packages])
110
157
  end
111
158
  end
112
159
 
@@ -114,17 +161,21 @@ ARCHITECTURES.each do |name, config|
114
161
  namespace "packagecloud" do
115
162
  desc "Push packages (%s) to package_cloud" % config[:packages].join(",")
116
163
  task "push" do
117
- packages = create_packages(create_tarball(create_directory_bundle(name, DEST_DIR)), config[:platform], config[:arch], config[:packages])
164
+ destination = create_directory_bundle(name, config[:wrapper], config[:separator], config[:extension], config[:dest_dir])
165
+ if config[:package_from_compressed]
166
+ destination = create_compressed_package(destination, config[:compress_format])
167
+ end
168
+ packages = create_packages(destination, config[:platform], config[:arch], config[:packages])
118
169
  by_extension = packages.group_by { |path| File.extname(path)[1..-1] }
119
170
  by_extension.each do |extension, files|
120
171
  distros = SUPPORTED_DISTROS[extension]
121
172
  distros.each do |distro|
122
173
  repo = File.join(PACKAGECLOUD_REPO, distro)
123
174
  files.each do |file|
124
- yank_cmd = "package_cloud yank %s %s" % [repo, file]
175
+ yank_cmd = %Q{package_cloud yank "%s" "%s"} % [repo, file]
125
176
  puts yank_cmd
126
177
  system(yank_cmd)
127
- sh "package_cloud push %s %s" % [repo, file]
178
+ sh %Q{package_cloud push "%s" "%s"} % [repo, file]
128
179
  end
129
180
  end
130
181
  end
@@ -144,7 +195,7 @@ end
144
195
  namespace "package" do
145
196
 
146
197
  desc "Install gems to local directory"
147
- task :bundle_install do
198
+ task :bundle_install, [:platform] do |t, args|
148
199
  if RUBY_VERSION !~ /^2\.1\./
149
200
  abort "You can only 'bundle install' using Ruby 2.1, because that's what Traveling Ruby uses."
150
201
  end
@@ -153,20 +204,23 @@ namespace "package" do
153
204
  spec_path = SPEC_PATH
154
205
  cache_dir = File.join("packaging", "vendor", "*", "*", "cache", "*")
155
206
 
156
- sh "rm -rf %s" % tmp_package_dir
157
- sh "mkdir -p %s" % tmp_package_dir
158
- sh "cp %s Gemfile Gemfile.lock %s" % [spec_path, tmp_package_dir]
207
+ sh %Q{rm -rf "%s"} % tmp_package_dir
208
+ sh %Q{mkdir -p "%s"} % tmp_package_dir
209
+ sh %Q{cp "%s" Gemfile Gemfile.lock "%s"} % [spec_path, tmp_package_dir]
159
210
 
160
- GEMSPEC.require_paths.each do |path|
161
- sh "ln -sf %s %s" % [File.expand_path(path), tmp_package_dir]
162
- end
211
+ sh %Q{ln -sf "%s" "%s"} % [File.expand_path("lib"), tmp_package_dir]
163
212
 
213
+ env = if args[:platform] == :win32
214
+ "INSTALL_WINDOWS=1"
215
+ else
216
+ ""
217
+ end
164
218
  Bundler.with_clean_env do
165
- sh "cd %s && env BUNDLE_IGNORE_CONFIG=1 bundle install --path ../vendor --without development" % tmp_package_dir
219
+ sh %Q{cd "%s" && env BUNDLE_IGNORE_CONFIG=1 #{env} bundle install --path ../vendor --without development} % tmp_package_dir
166
220
  end
167
221
 
168
- sh "rm -rf %s" % tmp_package_dir
169
- sh "rm -f %s" % cache_dir
222
+ sh %Q{rm -rf "%s"} % tmp_package_dir
223
+ sh %Q{rm -f "%s"} % cache_dir
170
224
  end
171
225
 
172
226
  end
@@ -175,14 +229,33 @@ def create_packages(directory, platform, architecture, package_formats)
175
229
  Array(package_formats).map { |pkg| create_package(directory, pkg, platform, architecture) }
176
230
  end
177
231
 
178
- def create_package(tarball, pkg, platform, architecture)
179
- output_name = [[PACKAGE_OUTPUT_NAME, architecture].join("_"), pkg].join(".")
180
- extra_args = EXTRA_ARGS[pkg] || ""
181
- sh "fpm -s tar -t %s -f -n %s -v %s -a %s --license \"%s\" --vendor \"%s\" --maintainer \"%s\" --url \"%s\" --description \"%s\" --category \"%s\" --config-files %s -C %s -p %s %s %s" % [pkg, PACKAGE_NAME, VERSION, architecture, LICENSE, VENDOR, MAINTAINER, HOMEPAGE, DESCRIPTION, PACKAGE_CATEGORY, CONFIG_DEST, File.basename(tarball, ".tar.gz"), output_name, extra_args, tarball]
182
- output_name
232
+ def create_package(source, pkg, platform, architecture)
233
+ supported_by_fpm = %w{deb rpm}
234
+ supported_by_nsis = %w{exe}
235
+ if supported_by_fpm.include?(pkg)
236
+ output_name = [[PACKAGE_OUTPUT_NAME, architecture].join("_"), pkg].join(".")
237
+ extra_args = EXTRA_ARGS[pkg] || ""
238
+ sh %Q{fpm -s tar -t "%s" -f -n "%s" -v "%s" -a "%s" --license "%s" --vendor "%s" --maintainer "%s" --url "%s" --description "%s" --category "%s" --config-files "%s" -C "%s" -p "%s" %s "%s"} % [pkg, PACKAGE_NAME, VERSION, architecture, LICENSE, VENDOR, MAINTAINER, HOMEPAGE, DESCRIPTION, PACKAGE_CATEGORY, CONFIG_DEST, File.basename(source, ".tar.gz"), output_name, extra_args, source]
239
+ output_name
240
+ elsif supported_by_nsis.include?(pkg)
241
+ nsis_script = File.join("win32", "installer.nsis.erb")
242
+ installer_name = File.basename(source) + ".exe"
243
+ template = NSISERBContext.new(installer_name, [source], nsis_script)
244
+
245
+ temp = Tempfile.new("nsis", ".")
246
+ temp.write(template.result)
247
+ temp.close(false)
248
+
249
+ sh %Q{makensis "%s"} % temp.path
250
+
251
+ temp.unlink
252
+
253
+ else
254
+ raise StandardError.new("Format %s is not supported" % pkg)
255
+ end
183
256
  end
184
257
 
185
- def create_directory_bundle(target, prefix = nil)
258
+ def create_directory_bundle(target, wrapper_script, separator, extension = nil, prefix = nil)
186
259
  package_dir = [PACKAGE_NAME, VERSION, target].join("_")
187
260
  prefixed_dir = if prefix
188
261
  File.join(package_dir, prefix)
@@ -200,52 +273,71 @@ def create_directory_bundle(target, prefix = nil)
200
273
  bundle_dir = File.join(dest_vendor_dir, ".bundle")
201
274
 
202
275
 
203
- sh "rm -rf %s" % package_dir
204
- sh "mkdir %s" % package_dir
205
- sh "mkdir -p %s" % prefixed_dir
206
- sh "mkdir -p %s" % config_dest_dir
207
- sh "mkdir -p %s" % app_dir
276
+ sh %Q{rm -rf "%s"} % package_dir
277
+ sh %Q{mkdir "%s"} % package_dir
278
+ sh %Q{mkdir -p "%s"} % prefixed_dir
279
+ sh %Q{mkdir -p "%s"} % config_dest_dir
280
+ sh %Q{mkdir -p "%s"} % app_dir
208
281
 
209
282
  GEMSPEC.files.each do |file|
210
283
  destination_dir = File.join(app_dir, File.dirname(file))
211
284
  FileUtils.mkdir_p(destination_dir)
212
285
 
213
- sh "cp %s %s" % [file, destination_dir]
286
+ sh %Q{cp "%s" "%s"} % [file, destination_dir]
214
287
  end
215
288
 
216
289
  Dir[File.join(CONFIG_DIR, "*")].each do |file|
217
- sh "cp %s %s" % [file, config_dest_dir]
290
+ sh %Q{cp "%s" "%s"} % [file, config_dest_dir]
218
291
  end
219
292
 
220
- sh "mkdir %s" % ruby_dir
221
- sh "tar -xzf %s -C %s" % [traveling_ruby_file, ruby_dir]
293
+ sh %Q{mkdir "%s"} % ruby_dir
294
+ sh %Q{tar -xzf "%s" -C "%s"} % [traveling_ruby_file, ruby_dir]
222
295
 
223
296
  GEMSPEC.executables.each do |file|
224
- destination = File.join(prefixed_dir, file)
297
+ destination = File.join(prefixed_dir, file + extension.to_s)
225
298
 
226
- File.open(destination, "w") { |f| f.write(WRAPPER_SCRIPT % File.join("bin", file)) }
299
+ bin_path = "bin" + separator + file
300
+ File.open(destination, "w") { |f| f.write(wrapper_script % bin_path) }
227
301
 
228
- sh "chmod +x %s" % destination
302
+ sh %Q{chmod +x "%s"} % destination
229
303
  end
230
304
 
231
- sh "cp -pR %s %s" % [vendor_dir, lib_dir]
232
- sh "cp %s Gemfile Gemfile.lock %s" % [spec_path, dest_vendor_dir]
305
+ sh %Q{cp -pR "%s" "%s"} % [vendor_dir, lib_dir]
306
+ sh %Q{cp "%s" Gemfile Gemfile.lock "%s"} % [spec_path, dest_vendor_dir]
233
307
 
234
- GEMSPEC.require_paths.each do |path|
235
- sh "ln -sf ../app/%s %s" % [path, File.join(dest_vendor_dir, path)]
236
- end
308
+
309
+ sh %Q{ln -sf "../app/%s" "%s"} % ["lib", File.join(dest_vendor_dir, "lib")]
237
310
 
238
311
  FileUtils.mkdir_p(bundle_dir)
239
312
  File.open(File.join(bundle_dir, "config"), "w") { |f| f.write(BUNDLE_CONFIG) }
313
+
314
+ post_build_dir = File.join(target)
315
+ post_build_makefile = File.join(post_build_dir, "Makefile")
316
+ if File.exists?(post_build_makefile)
317
+ sh %Q{cd "%s" && make clean || /usr/bin/true} % post_build_dir
318
+ sh %Q{cd "%s" && make install prefix="%s"} % [post_build_dir, File.expand_path(package_dir)]
319
+ end
240
320
  package_dir
241
321
  end
242
322
 
243
- def create_tarball(package_dir)
244
- gzip_file = "%s.tar.gz" % package_dir
323
+ def create_compressed_package(package_dir, format = 'tar.gz')
324
+ format ||= 'tar.gz'
325
+ case format
326
+ when 'tar.gz'
327
+ gzip_file = "%s.tar.gz" % package_dir
328
+
329
+ sh %Q{tar -czf "%s" "%s"} % [gzip_file, package_dir]
245
330
 
246
- sh "tar -czf %s %s" % [gzip_file, package_dir]
331
+ gzip_file
332
+ when 'zip'
333
+ zip_file = "%s.zip" % package_dir
247
334
 
248
- gzip_file
335
+ sh %Q{zip -r "%s" "%s"} % [zip_file, package_dir]
336
+
337
+ zip_file
338
+ else
339
+ raise StandardError.new("Format %s is not supported" % format)
340
+ end
249
341
  end
250
342
 
251
343
  def download_runtime(target)
@@ -256,3 +348,49 @@ def download_runtime(target)
256
348
 
257
349
  sh "cd packaging && curl -L -O --fail %s" % traveling_ruby_url
258
350
  end
351
+
352
+
353
+ class NSISERBContext
354
+ attr_reader :template_path, :directories, :installer_file_name
355
+
356
+ def initialize(installer_name, directories, template_path)
357
+ @directories = directories
358
+ @template_path = template_path
359
+ @installer_file_name = installer_name
360
+ end
361
+
362
+ def template_source
363
+ File.read(template_path)
364
+ end
365
+
366
+ def removable_artifacts
367
+ removable_files = Set.new
368
+ removable_directories = Set.new
369
+ directories.each do |dir|
370
+ Find.find(dir) do |path|
371
+ puts path.inspect
372
+ if File.file?(path)
373
+ without_base = path.split(File::SEPARATOR)[1..-1]
374
+ without_file = without_base[0..-2]
375
+ removable_files << without_base.join("\\")
376
+ removable_directories << without_file.join("\\")
377
+ end
378
+ end
379
+ end
380
+ removable_files << "InstrumentServer.exe"
381
+ dirs = removable_directories.to_a.sort_by { |path| path.split("\\").size }.reverse
382
+ [removable_files.to_a, dirs]
383
+ end
384
+
385
+ def service_name
386
+ "instrument_server"
387
+ end
388
+
389
+ def uninstaller_name
390
+ "uninstaller.exe"
391
+ end
392
+
393
+ def result
394
+ ERB.new(template_source).result(binding)
395
+ end
396
+ end