instrumental_tools 1.0.0.rc2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BUILD.md +50 -0
- data/CHANGELOG.md +5 -1
- data/CUSTOM_METRICS.md +9 -1
- data/INSTALL.md +89 -0
- data/LICENSE +1 -1
- data/README.md +23 -3
- data/Rakefile +257 -0
- data/TEST.md +9 -0
- data/bin/instrument_server +48 -7
- data/chef/.kitchen.yml +16 -0
- data/chef/Berksfile +4 -0
- data/chef/Berksfile.lock +9 -0
- data/chef/instrumental_tools/attributes/default.rb +2 -0
- data/chef/instrumental_tools/metadata.rb +3 -0
- data/chef/instrumental_tools/recipes/default.rb +21 -0
- data/chef/instrumental_tools/templates/instrumental.yml.erb +6 -0
- data/conf/instrumental.yml +6 -0
- data/debian/after-install.sh +6 -0
- data/debian/after-remove.sh +4 -0
- data/debian/before-remove.sh +4 -0
- data/debian/instrument_server +46 -0
- data/examples/mysql/mysql_status.rb +3 -3
- data/instrumental_tools.gemspec +32 -4
- data/lib/instrumental_tools/metric_script_executor.rb +38 -34
- data/lib/instrumental_tools/server_controller.rb +122 -35
- data/lib/instrumental_tools/system_inspector/linux.rb +80 -42
- data/lib/instrumental_tools/version.rb +1 -1
- data/puppet/.kitchen.yml +26 -0
- data/puppet/.librarian/puppet/config +2 -0
- data/puppet/Puppetfile +4 -0
- data/puppet/Puppetfile.lock +17 -0
- data/puppet/instrumental_tools/manifests/init.pp +29 -0
- data/puppet/instrumental_tools/metadata.json +11 -0
- data/puppet/instrumental_tools/templates/instrumental.yml.erb +6 -0
- data/puppet/manifests/site.pp +3 -0
- data/rpm/after-install.sh +7 -0
- data/rpm/after-remove.sh +4 -0
- data/rpm/before-remove.sh +5 -0
- data/rpm/instrument_server +46 -0
- data/systemd/instrument_server.service +13 -0
- data/test/integration/default/serverspec/instrumental_tools_spec.rb +29 -0
- metadata +164 -11
- data/.gitignore +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8871b4d7d488bafeb4a58f5d82caad26ba139c00
|
4
|
+
data.tar.gz: 5901bebe60f6303dbb00cacba6f376ffa1b61c88
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71a0be3021518f008517cfbf8d0802ca80de6c3362df63f9d70aabaf0a86eac6341fec2018f7c4de1047b0e4e30639f155085182d35c3e59b7b0f23f8a55081c
|
7
|
+
data.tar.gz: 5c55425bdb4b2cd64adee1c7aa363d918bbb18175a106796cd29145dc3b17d69be1adba0e5f94af61ee864d98af8665a3b73143420169b2b804e1960207f82b8
|
data/BUILD.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Building instrumental-tools
|
2
|
+
|
3
|
+
## The Gem
|
4
|
+
|
5
|
+
Building the `instrumental_tools` gem can be done via:
|
6
|
+
|
7
|
+
```
|
8
|
+
rake gem
|
9
|
+
```
|
10
|
+
|
11
|
+
This will produce a .gem file suitable for release. As a shortcut for the RubyGems release process, you can issue the following command:
|
12
|
+
|
13
|
+
```
|
14
|
+
rake release
|
15
|
+
```
|
16
|
+
|
17
|
+
to push a new copy of the gem directly to RubyGems. This presumes you have the correct `rubygems_api_key` available in your system Gem config.
|
18
|
+
|
19
|
+
## `deb`, `rpm` and `tgz` packages
|
20
|
+
|
21
|
+
Building new `deb`, `rpm` and `tgz` packages can be done via the following rake commands:
|
22
|
+
|
23
|
+
For 32 bit Linux:
|
24
|
+
|
25
|
+
```
|
26
|
+
rake package:linux-x86:package # builds `rpm` and `deb`
|
27
|
+
rake package:linux-x86:tarball # buidls tgz
|
28
|
+
```
|
29
|
+
|
30
|
+
For 64 bit Linux:
|
31
|
+
|
32
|
+
```
|
33
|
+
rake package:linux-x86_64:package
|
34
|
+
rake package:linux-x86_64:tarball
|
35
|
+
```
|
36
|
+
|
37
|
+
|
38
|
+
For Mac OS X:
|
39
|
+
|
40
|
+
```
|
41
|
+
rake package:osx:tarball
|
42
|
+
```
|
43
|
+
|
44
|
+
`deb` and `rpm` packages should be pushed to PackageCloud. You will need to ensure you have the `package_cloud` gem installed (`bundle install` should install it for you - see the [PackageCloud instructions](https://packagecloud.io/docs#cli_install) otherwise). You will also need write credentials to PackageCloud available in `~/.packagecloud`; they will follow the format:
|
45
|
+
|
46
|
+
```
|
47
|
+
{"url":"https://packagecloud.io","token":"YOUR PACKAGECLOUD API TOKEN"}
|
48
|
+
```
|
49
|
+
|
50
|
+
On release, the tarball should be uploaded to the Github releases page and linked to from the main README.md.
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
###
|
1
|
+
### 1.0.0 [?]
|
2
2
|
* Configurable pid and log file locations
|
3
3
|
* Pid and log file default to $HOME
|
4
4
|
* Process control commands do not require API key
|
5
5
|
* Omit "-d" in favor of "start" and "stop", "foreground" runs process in foreground
|
6
6
|
* Configurable reporting interval
|
7
7
|
* Custom scripts may be executed and have their output sent to Instrumental (See [CUSTOM_METRICS.md](CUSTOM_METRICS.md))
|
8
|
+
* Support dropping privileges at startup
|
9
|
+
* Example scripts for monitoring Docker and MySQL
|
10
|
+
* Example startup scripts for starting process at boot time
|
11
|
+
* Example Chef and Puppet recipes
|
8
12
|
|
9
13
|
### 0.6.0 [August 11th, 2014]
|
10
14
|
* Don't report swap usage if it's zero (Patrick Wyatt)
|
data/CUSTOM_METRICS.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Custom Metric Scripts
|
2
2
|
|
3
|
-
You may have specific pieces of architecture that you would like `instrument_server` to monitor. As of version 0.
|
3
|
+
You may have specific pieces of architecture that you would like `instrument_server` to monitor. As of version 1.0.0 of the `instrument_server` gem, you may pass the `-e` flag to `instrument_server` on startup to enable this functionality. There are several [examples](examples/) of scripts that you may use for your infrastructure, or you can [write your own](#writing_custom_scripts).
|
4
4
|
|
5
5
|
## Installing Custom Scripts
|
6
6
|
|
@@ -28,6 +28,12 @@ Your script is expected to output data in the following format on `STDOUT` in or
|
|
28
28
|
METRIC_NAME METRIC_VALUE
|
29
29
|
```
|
30
30
|
|
31
|
+
or
|
32
|
+
|
33
|
+
```
|
34
|
+
METRIC_NAME METRIC_VALUE UNIX_TIME_IN_SECONDS
|
35
|
+
```
|
36
|
+
|
31
37
|
For example, if a script named `application_load` were to report two metrics, `memory` and `load`, to the `instrument_server` process, its output should be:
|
32
38
|
|
33
39
|
```
|
@@ -43,6 +49,8 @@ HOST_NAME.SCRIPT_NAME.METRIC_NAME
|
|
43
49
|
|
44
50
|
Using the previous example, if the `application_load` script ran on a host named `app-0001`, its `memory` and `load` metrics would be submitted to Instrumental as `app-0001.application_load.memory` and `app-0001.application_load.load`.
|
45
51
|
|
52
|
+
The optional third parameter of the above formats, `UNIX_TIME_IN_SECONDS`, represents the time under which the submitted metric should be measured. Generally you do not need to provide this value, as `instrument_server` will default to recording the time when it receives the metric from your script as the time under which the measurement should be recorded.
|
53
|
+
|
46
54
|
### Exit Codes
|
47
55
|
|
48
56
|
If you do not want the output of your script submitted to Instrumental, your process should exit with a non-zero exit code. Its `STDOUT` output will still be provided to your script on the next iteration.
|
data/INSTALL.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# Package Locations
|
2
|
+
|
3
|
+
## PackageCloud
|
4
|
+
|
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
|
+
|
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)
|
14
|
+
|
15
|
+
# Ubuntu
|
16
|
+
|
17
|
+
```sh
|
18
|
+
sudo apt-get install curl
|
19
|
+
curl https://packagecloud.io/install/repositories/expectedbehavior/instrumental/script.deb | sudo bash
|
20
|
+
sudo apt-get install instrumental-tools
|
21
|
+
```
|
22
|
+
|
23
|
+
# Debian
|
24
|
+
|
25
|
+
```sh
|
26
|
+
su -c "apt-get install curl"
|
27
|
+
su -c "curl https://packagecloud.io/install/repositories/expectedbehavior/instrumental/script.deb | bash"
|
28
|
+
su -c "apt-get install instrumental-tools"
|
29
|
+
```
|
30
|
+
|
31
|
+
# Enterprise Linux (CentOS, AWS Linux, RedHat)
|
32
|
+
|
33
|
+
```sh
|
34
|
+
curl https://packagecloud.io/install/repositories/expectedbehavior/instrumental/script.rpm | sudo bash
|
35
|
+
sudo yum install instrumental-tools
|
36
|
+
```
|
37
|
+
|
38
|
+
# Other ( CoreOS, et al )
|
39
|
+
|
40
|
+
## Installing the software
|
41
|
+
|
42
|
+
```sh
|
43
|
+
sudo mkdir -p /opt/instrumental-tools/
|
44
|
+
sudo tar -zxvf ./instrumental-tools_1.0.0_linux-x86_64.tar.gz -C /opt/instrumental-tools/ --strip 1
|
45
|
+
sudo cp /opt/instrumental-tools/etc/instrumental.yml /etc/
|
46
|
+
```
|
47
|
+
|
48
|
+
# RubyGems
|
49
|
+
|
50
|
+
```sh
|
51
|
+
sudo gem install instrumental_tools
|
52
|
+
```
|
53
|
+
|
54
|
+
Installing `instrumental_tools` via Rubygems will not create the `/opt/instrumental-tools/` directory on your server or setup the process to run on startup. It is advisable that you install the software via the `deb` or `rpm` packages if your system supports its.
|
55
|
+
|
56
|
+
## Adding to system startup
|
57
|
+
|
58
|
+
### systemd
|
59
|
+
|
60
|
+
```sh
|
61
|
+
sudo cp /opt/instrumental-tools/lib/app/systemd/instrument_server.service /etc/systemd/system/
|
62
|
+
sudo systemctl enable instrument_server.service
|
63
|
+
sudo systemctl start instrument_server
|
64
|
+
```
|
65
|
+
|
66
|
+
### sysvinit (update-rc.d)
|
67
|
+
|
68
|
+
```sh
|
69
|
+
sudo cp /opt/instrumental-tools/lib/app/debian/instrument_server /etc/init.d/
|
70
|
+
sudo update-rc.d instrument_server defaults
|
71
|
+
sudo /etc/init.d/instrument_server start
|
72
|
+
```
|
73
|
+
|
74
|
+
### sysvinit (chkconfig)
|
75
|
+
|
76
|
+
```sh
|
77
|
+
sudo cp /opt/instrumental-tools/lib/app/rpm/instrument_server /etc/init.d/
|
78
|
+
sudo chkconfig --add instrument_server
|
79
|
+
sudo chkconfig instrument_server on
|
80
|
+
sudo service instrument_server start
|
81
|
+
```
|
82
|
+
|
83
|
+
# Chef
|
84
|
+
|
85
|
+
An example Chef cookbook for installing `instrumental-tools` is available in [`chef/instrumental_tools`](chef/instrumental_tools).
|
86
|
+
|
87
|
+
# Puppet
|
88
|
+
|
89
|
+
An example Puppet module for installing `instrumental-tools` is available in [`puppet/instrumental_tools`](puppet/instrumental_tools).
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,30 @@
|
|
1
1
|
# Instrumental Tools
|
2
2
|
|
3
|
-
A collection of
|
3
|
+
A collection of tools for monitoring servers with Instrumental ([www.instrumentalapp.com](http://www.instrumentalapp.com/)).
|
4
4
|
|
5
|
-
##
|
5
|
+
## Operating System Support
|
6
6
|
|
7
|
-
|
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.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Installation instructions for supported platforms is available in [INSTALL.md](INSTALL.md). The recommended installation method is to use a prebuilt package, which will automatically install the application as a service in your operating system's startup list.
|
12
|
+
|
13
|
+
Once you've installed the package, you will want to edit the `/etc/instrumental.yml` file with your Instrumental API key. Example `/etc/instrumental.yml`:
|
14
|
+
|
15
|
+
## Sent Metrics
|
16
|
+
|
17
|
+
The default `instrument_server` behavior will collect metrics on the following data:
|
18
|
+
|
19
|
+
* CPU (`user`, `nice`, `system`, `idle`, `iowait` and `total in use`)
|
20
|
+
* Load (at 1 minute, 5 minute and 15 minute intervals)
|
21
|
+
* Memory (`used`, `free`, `buffers`, `cached`, `free_percent` )
|
22
|
+
* Swap (`used`, `free`, `free_percent`)
|
23
|
+
* Disk Capacity (`total`, `used`, `available`, `available percent` for all mounted disks)
|
24
|
+
* Disk Usage (`percent_utilization` for all mounted disks)
|
25
|
+
* Filesystem stats (`open_files`, `max_open_files`)
|
26
|
+
|
27
|
+
## Command Line Usage
|
8
28
|
|
9
29
|
Basic usage:
|
10
30
|
|
data/Rakefile
CHANGED
@@ -1 +1,258 @@
|
|
1
|
+
|
1
2
|
require 'bundler/gem_tasks'
|
3
|
+
require 'etc'
|
4
|
+
require 'fileutils'
|
5
|
+
require 'socket'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
PACKAGE_CATEGORY = "Utilities"
|
9
|
+
PACKAGECLOUD_REPO = "expectedbehavior/instrumental"
|
10
|
+
CONFIG_DIR = "conf"
|
11
|
+
CONFIG_DEST = "/etc/"
|
12
|
+
|
13
|
+
GEMSPEC = Bundler::GemHelper.instance.gemspec
|
14
|
+
SPEC_PATH = Bundler::GemHelper.instance.spec_path
|
15
|
+
PACKAGE_NAME = GEMSPEC.name.gsub("_", "-") # Debian packages cannot include _ in name
|
16
|
+
VERSION = GEMSPEC.version
|
17
|
+
TRAVELING_RUBY_VERSION = "20150210-2.1.5"
|
18
|
+
TRAVELING_RUBY_FILE = "packaging/traveling-ruby-#{TRAVELING_RUBY_VERSION}-%s.tar.gz"
|
19
|
+
DEST_DIR = File.join("/opt/", PACKAGE_NAME)
|
20
|
+
PACKAGE_OUTPUT_NAME = [PACKAGE_NAME, VERSION].join("_")
|
21
|
+
LICENSE = Array(GEMSPEC.licenses).first || "None"
|
22
|
+
VENDOR = Array(GEMSPEC.authors).first || Etc.getlogin
|
23
|
+
MAINTAINER = Array(GEMSPEC.email).first || [Etc.getlogin, Socket.gethostname].join("@")
|
24
|
+
HOMEPAGE = GEMSPEC.homepage || ""
|
25
|
+
DESCRIPTION = GEMSPEC.description || ""
|
26
|
+
SUPPORTED_DISTROS = {
|
27
|
+
'deb' => ['ubuntu/precise', 'ubuntu/lucid', 'ubuntu/trusty', 'ubuntu/utopic', 'debian/lenny', 'debian/squeeze', 'debian/wheezy'],
|
28
|
+
'rpm' => ['el/5', 'el/6', 'el/7']
|
29
|
+
}
|
30
|
+
EXTRA_ARGS = {
|
31
|
+
'deb' => '--deb-init debian/instrument_server --after-install debian/after-install.sh --before-remove debian/before-remove.sh --after-remove debian/after-remove.sh --deb-user nobody --deb-group nogroup',
|
32
|
+
'rpm' => '--rpm-init rpm/instrument_server --after-install rpm/after-install.sh --before-remove rpm/before-remove.sh --after-remove rpm/after-remove.sh --rpm-user nobody --rpm-group nobody --rpm-os linux --rpm-attr "-,nobody,nobody:/opt/instrumental-tools/" --directories /opt/instrumental-tools/'
|
33
|
+
}
|
34
|
+
|
35
|
+
|
36
|
+
ARCHITECTURES = {
|
37
|
+
'linux-x86' => {
|
38
|
+
runtime: TRAVELING_RUBY_FILE % "linux-x86",
|
39
|
+
arch: "i386",
|
40
|
+
packages: %w{deb rpm},
|
41
|
+
platform: "linux",
|
42
|
+
packagecloud: true
|
43
|
+
},
|
44
|
+
'linux-x86_64' => {
|
45
|
+
runtime: TRAVELING_RUBY_FILE % "linux-x86_64",
|
46
|
+
arch: "amd64",
|
47
|
+
packages: %w{deb rpm},
|
48
|
+
platform: "linux",
|
49
|
+
packagecloud: true
|
50
|
+
},
|
51
|
+
'osx' => {
|
52
|
+
runtime: TRAVELING_RUBY_FILE % "osx",
|
53
|
+
arch: "x86_64",
|
54
|
+
packages: [],
|
55
|
+
platform: "darwin",
|
56
|
+
packagecloud: false
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
|
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
|
+
|
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
|
+
|
77
|
+
BUNDLE_CONFIG = <<-EOBUNDLECONFIG
|
78
|
+
BUNDLE_PATH: .
|
79
|
+
BUNDLE_WITHOUT: development
|
80
|
+
BUNDLE_DISABLE_SHARED_GEMS: '1'
|
81
|
+
EOBUNDLECONFIG
|
82
|
+
|
83
|
+
|
84
|
+
desc "Package your app"
|
85
|
+
task :package => ARCHITECTURES.map { |name, _| "package:%s" % name }
|
86
|
+
|
87
|
+
ARCHITECTURES.each do |name, config|
|
88
|
+
namespace "package" do
|
89
|
+
|
90
|
+
has_packaging = Array(config[:packages]).size > 0
|
91
|
+
|
92
|
+
if has_packaging
|
93
|
+
desc "Package your app for %s" % name
|
94
|
+
task name => ["%s:package" % name]
|
95
|
+
else
|
96
|
+
desc "Package your app for %s" % name
|
97
|
+
task name => ["%s:tarball" % name]
|
98
|
+
end
|
99
|
+
|
100
|
+
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))
|
104
|
+
end
|
105
|
+
|
106
|
+
if has_packaging
|
107
|
+
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])
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if config[:packagecloud]
|
114
|
+
namespace "packagecloud" do
|
115
|
+
desc "Push packages (%s) to package_cloud" % config[:packages].join(",")
|
116
|
+
task "push" do
|
117
|
+
packages = create_packages(create_tarball(create_directory_bundle(name, DEST_DIR)), config[:platform], config[:arch], config[:packages])
|
118
|
+
by_extension = packages.group_by { |path| File.extname(path)[1..-1] }
|
119
|
+
by_extension.each do |extension, files|
|
120
|
+
distros = SUPPORTED_DISTROS[extension]
|
121
|
+
distros.each do |distro|
|
122
|
+
repo = File.join(PACKAGECLOUD_REPO, distro)
|
123
|
+
files.each do |file|
|
124
|
+
yank_cmd = "package_cloud yank %s %s" % [repo, file]
|
125
|
+
puts yank_cmd
|
126
|
+
system(yank_cmd)
|
127
|
+
sh "package_cloud push %s %s" % [repo, file]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
file config[:runtime] do
|
140
|
+
download_runtime(name)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
namespace "package" do
|
145
|
+
|
146
|
+
desc "Install gems to local directory"
|
147
|
+
task :bundle_install do
|
148
|
+
if RUBY_VERSION !~ /^2\.1\./
|
149
|
+
abort "You can only 'bundle install' using Ruby 2.1, because that's what Traveling Ruby uses."
|
150
|
+
end
|
151
|
+
|
152
|
+
tmp_package_dir = File.join("packaging", "tmp")
|
153
|
+
spec_path = SPEC_PATH
|
154
|
+
cache_dir = File.join("packaging", "vendor", "*", "*", "cache", "*")
|
155
|
+
|
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]
|
159
|
+
|
160
|
+
GEMSPEC.require_paths.each do |path|
|
161
|
+
sh "ln -sf %s %s" % [File.expand_path(path), tmp_package_dir]
|
162
|
+
end
|
163
|
+
|
164
|
+
Bundler.with_clean_env do
|
165
|
+
sh "cd %s && env BUNDLE_IGNORE_CONFIG=1 bundle install --path ../vendor --without development" % tmp_package_dir
|
166
|
+
end
|
167
|
+
|
168
|
+
sh "rm -rf %s" % tmp_package_dir
|
169
|
+
sh "rm -f %s" % cache_dir
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
174
|
+
def create_packages(directory, platform, architecture, package_formats)
|
175
|
+
Array(package_formats).map { |pkg| create_package(directory, pkg, platform, architecture) }
|
176
|
+
end
|
177
|
+
|
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
|
183
|
+
end
|
184
|
+
|
185
|
+
def create_directory_bundle(target, prefix = nil)
|
186
|
+
package_dir = [PACKAGE_NAME, VERSION, target].join("_")
|
187
|
+
prefixed_dir = if prefix
|
188
|
+
File.join(package_dir, prefix)
|
189
|
+
else
|
190
|
+
package_dir
|
191
|
+
end
|
192
|
+
lib_dir = File.join(prefixed_dir, "lib")
|
193
|
+
config_dest_dir = File.join(package_dir, CONFIG_DEST)
|
194
|
+
app_dir = File.join(lib_dir, "app")
|
195
|
+
ruby_dir = File.join(lib_dir, "ruby")
|
196
|
+
dest_vendor_dir = File.join(lib_dir, "vendor")
|
197
|
+
vendor_dir = File.join("packaging", "vendor")
|
198
|
+
traveling_ruby_file = "packaging/traveling-ruby-%s-%s.tar.gz" % [TRAVELING_RUBY_VERSION, target]
|
199
|
+
spec_path = SPEC_PATH
|
200
|
+
bundle_dir = File.join(dest_vendor_dir, ".bundle")
|
201
|
+
|
202
|
+
|
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
|
208
|
+
|
209
|
+
GEMSPEC.files.each do |file|
|
210
|
+
destination_dir = File.join(app_dir, File.dirname(file))
|
211
|
+
FileUtils.mkdir_p(destination_dir)
|
212
|
+
|
213
|
+
sh "cp %s %s" % [file, destination_dir]
|
214
|
+
end
|
215
|
+
|
216
|
+
Dir[File.join(CONFIG_DIR, "*")].each do |file|
|
217
|
+
sh "cp %s %s" % [file, config_dest_dir]
|
218
|
+
end
|
219
|
+
|
220
|
+
sh "mkdir %s" % ruby_dir
|
221
|
+
sh "tar -xzf %s -C %s" % [traveling_ruby_file, ruby_dir]
|
222
|
+
|
223
|
+
GEMSPEC.executables.each do |file|
|
224
|
+
destination = File.join(prefixed_dir, file)
|
225
|
+
|
226
|
+
File.open(destination, "w") { |f| f.write(WRAPPER_SCRIPT % File.join("bin", file)) }
|
227
|
+
|
228
|
+
sh "chmod +x %s" % destination
|
229
|
+
end
|
230
|
+
|
231
|
+
sh "cp -pR %s %s" % [vendor_dir, lib_dir]
|
232
|
+
sh "cp %s Gemfile Gemfile.lock %s" % [spec_path, dest_vendor_dir]
|
233
|
+
|
234
|
+
GEMSPEC.require_paths.each do |path|
|
235
|
+
sh "ln -sf ../app/%s %s" % [path, File.join(dest_vendor_dir, path)]
|
236
|
+
end
|
237
|
+
|
238
|
+
FileUtils.mkdir_p(bundle_dir)
|
239
|
+
File.open(File.join(bundle_dir, "config"), "w") { |f| f.write(BUNDLE_CONFIG) }
|
240
|
+
package_dir
|
241
|
+
end
|
242
|
+
|
243
|
+
def create_tarball(package_dir)
|
244
|
+
gzip_file = "%s.tar.gz" % package_dir
|
245
|
+
|
246
|
+
sh "tar -czf %s %s" % [gzip_file, package_dir]
|
247
|
+
|
248
|
+
gzip_file
|
249
|
+
end
|
250
|
+
|
251
|
+
def download_runtime(target)
|
252
|
+
traveling_ruby_name = ["traveling-ruby", TRAVELING_RUBY_VERSION, target].join("-")
|
253
|
+
traveling_ruby_file = "%s.tar.gz" % traveling_ruby_name
|
254
|
+
traveling_ruby_releases = "http://d6r77u77i8pq3.cloudfront.net/releases"
|
255
|
+
traveling_ruby_url = File.join(traveling_ruby_releases, traveling_ruby_file)
|
256
|
+
|
257
|
+
sh "cd packaging && curl -L -O --fail %s" % traveling_ruby_url
|
258
|
+
end
|
data/TEST.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# Testing Installation
|
2
|
+
|
3
|
+
You can test installation of `instrumental_tools` by running the [ServerSpec tests](test/integration/default/serverspec/). From the `chef` or `puppet` directories, run the following command:
|
4
|
+
|
5
|
+
```
|
6
|
+
bundle exec kitchen verify
|
7
|
+
```
|
8
|
+
|
9
|
+
to test installation and setup procedures for the `instrumental_tools` command. You must have [Vagrant](https://www.vagrantup.com/) installed; currently the KitchenCI integration is setup to use [VMWare Fusion](http://www.vmware.com/products/fusion) and the [VMWare Fusion Vagrant provider](https://www.vagrantup.com/vmware); you can configure a separate provider for your specific setup by change the `provider` flag in the `.kitchen.yml` file for your particular setup.
|
data/bin/instrument_server
CHANGED
@@ -8,35 +8,48 @@ rescue Gem::LoadError
|
|
8
8
|
puts ' gem install instrumental_agent'
|
9
9
|
exit 1
|
10
10
|
end
|
11
|
+
|
11
12
|
require 'etc'
|
12
13
|
require 'instrumental_agent'
|
13
14
|
require 'fileutils'
|
14
15
|
require 'optparse'
|
15
16
|
require 'socket'
|
17
|
+
require 'tmpdir'
|
18
|
+
|
16
19
|
$: << File.join(File.dirname(__FILE__), "..", "lib")
|
17
20
|
require 'instrumental_tools/version'
|
18
21
|
require 'instrumental_tools/server_controller'
|
19
22
|
|
20
23
|
def require_api_key(options, parser)
|
21
|
-
if options[:api_key].to_s.strip.empty?
|
24
|
+
if options[:api_key].to_s.strip.empty? && !File.exists?(options[:config_file])
|
22
25
|
print parser.help
|
23
26
|
exit 1
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
27
|
-
|
30
|
+
|
31
|
+
cur_directory = Dir.pwd
|
32
|
+
home_directory = Dir.home rescue nil
|
33
|
+
script_location = File.expand_path(File.dirname(__FILE__))
|
34
|
+
tmp_dir = Dir.tmpdir
|
35
|
+
script_data_directory = [cur_directory, home_directory, script_location, tmp_dir].compact.detect { |dir| File.writable?(dir) }
|
36
|
+
|
37
|
+
default_script_directory = File.join(script_data_directory, '.instrumental_scripts')
|
28
38
|
default_command = :foreground
|
29
39
|
|
30
40
|
options = {
|
31
41
|
:collector => 'collector.instrumentalapp.com',
|
32
42
|
:port => '8000',
|
33
43
|
:hostname => Socket.gethostname,
|
34
|
-
:pid_location => File.join(
|
35
|
-
:log_location => File.join(
|
44
|
+
:pid_location => File.join(script_data_directory, 'instrument_server.pid'),
|
45
|
+
:log_location => File.join(script_data_directory, 'instrument_server.log'),
|
46
|
+
:tmp_location => Dir.tmpdir,
|
36
47
|
:enable_scripts => false,
|
37
48
|
:script_location => default_script_directory,
|
38
49
|
:report_interval => 30,
|
39
|
-
:debug => false
|
50
|
+
:debug => false,
|
51
|
+
:config_file => '/etc/instrumental.yml',
|
52
|
+
:user => nil
|
40
53
|
}
|
41
54
|
|
42
55
|
option_parser = OptionParser.new do |opts|
|
@@ -49,6 +62,10 @@ Default command: #{default_command.to_s}
|
|
49
62
|
options[:api_key] = api_key
|
50
63
|
end
|
51
64
|
|
65
|
+
opts.on('-f', '--config-file PATH', "Config file with location of your API key (default #{options[:config_file]})") do |path|
|
66
|
+
options[:config_file] = path
|
67
|
+
end
|
68
|
+
|
52
69
|
opts.on('-c', '--collector COLLECTOR[:PORT]', "Collector (default #{options[:collector]}:#{options[:port]})") do |collector|
|
53
70
|
address, port = collector.split(':')
|
54
71
|
options[:collector] = address
|
@@ -79,6 +96,14 @@ Default command: #{default_command.to_s}
|
|
79
96
|
options[:script_location] = path
|
80
97
|
end
|
81
98
|
|
99
|
+
opts.on('-u', '--user USER_TO_RUN_AS', "User to run instrument_server as. You must have permissions to drop privileges to this user.") do |u|
|
100
|
+
options[:user] = u
|
101
|
+
end
|
102
|
+
|
103
|
+
opts.on('-t', '--temp-dir TEMP_DIRECTORY', "Where to store temporary files (default #{options[:tmp_location]})") do |t|
|
104
|
+
options[:tmp_location] = t
|
105
|
+
end
|
106
|
+
|
82
107
|
opts.on('--debug', "Print all sent metrics to the log") do
|
83
108
|
options[:debug] = true
|
84
109
|
end
|
@@ -91,9 +116,25 @@ end
|
|
91
116
|
|
92
117
|
option_parser.parse!
|
93
118
|
|
119
|
+
if options[:user]
|
120
|
+
desired_uid = Etc.getpwnam(options[:user]).uid
|
121
|
+
Process::Sys.setuid(desired_uid)
|
122
|
+
if desired_uid && desired_uid != 0
|
123
|
+
begin
|
124
|
+
Process::Sys.setuid(0)
|
125
|
+
rescue Errno::EPERM
|
126
|
+
nil
|
127
|
+
else
|
128
|
+
puts "Cannot drop privileges to #{options[:user]}"
|
129
|
+
exit 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
94
134
|
command = ARGV.first && ARGV.first.to_sym
|
95
135
|
command ||= default_command
|
96
136
|
|
137
|
+
|
97
138
|
options[:api_key] ||= ENV["INSTRUMENTAL_TOKEN"]
|
98
139
|
|
99
140
|
if options[:pid_location].to_s.strip.empty?
|
@@ -148,7 +189,7 @@ running_as_daemon = [:start, :restart].include?(command)
|
|
148
189
|
|
149
190
|
controller = ServerController.spawn(
|
150
191
|
:name => File.basename(__FILE__),
|
151
|
-
:path =>
|
192
|
+
:path => options[:tmp_location],
|
152
193
|
:pid_file => options[:pid_location],
|
153
194
|
:verbose => true,
|
154
195
|
:log_file => options[:log_location],
|
@@ -165,7 +206,7 @@ end
|
|
165
206
|
|
166
207
|
if running_as_daemon
|
167
208
|
begin
|
168
|
-
Timeout.timeout(
|
209
|
+
Timeout.timeout(1) do
|
169
210
|
Process.waitpid(controller.pid)
|
170
211
|
end
|
171
212
|
rescue Timeout::Error
|
data/chef/.kitchen.yml
ADDED
data/chef/Berksfile
ADDED
data/chef/Berksfile.lock
ADDED