instrumental_tools 1.0.0 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
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