packer-client 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +14 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +10 -0
- data/Guardfile +5 -0
- data/Jenkinsfile +110 -0
- data/LICENSE.txt +21 -0
- data/README.md +95 -0
- data/Rakefile +29 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/packer.rb +24 -0
- data/lib/packer/client.rb +187 -0
- data/lib/packer/message/artifact.rb +23 -0
- data/lib/packer/message/artifact_file.rb +25 -0
- data/lib/packer/message/base.rb +29 -0
- data/lib/packer/message/error.rb +21 -0
- data/lib/packer/message/template_builder.rb +27 -0
- data/lib/packer/message/template_provisioner.rb +23 -0
- data/lib/packer/message/template_variable.rb +31 -0
- data/lib/packer/message/ui.rb +25 -0
- data/lib/packer/output/base.rb +25 -0
- data/lib/packer/output/build.rb +51 -0
- data/lib/packer/output/fix.rb +25 -0
- data/lib/packer/output/inspect.rb +29 -0
- data/lib/packer/output/machine_readable.rb +26 -0
- data/lib/packer/output/push.rb +10 -0
- data/lib/packer/output/validate.rb +15 -0
- data/lib/packer/output/version.rb +33 -0
- data/lib/packer/version.rb +3 -0
- data/packer-client.gemspec +29 -0
- metadata +161 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YzljNzQ3MDI0YTI4ZDk0ZWYzNGQ3NWI4NTg0NzMwZTA0NjA3YzEwZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NzBmZmRjZmJlNjVjYTkwZjY1ODQyY2JlNzI3OTNhZTY4OGE5YTg1Mw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTk1MzQ5YmU1MDJmMTYwOGUwZTBjY2Q1NzVkZjRiOGY0NGFhNTE3YTM4YTIy
|
10
|
+
ZDdjYjU4YjI5YjllMmMxODUzMDhmOTQ4YmQ2ZGQyOTk4MDI1N2EyMzMzNTg4
|
11
|
+
OTQwNTRmZTYxYTIwYWM5MzZjYTZhZTFlZjdjYTc1MWMxYWFjZjI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDMzZWNlMjM3NDFkNTRiOTAwMjUwOGZmYTRhNTdhMmM5MjkxNjExNGFlMGZm
|
14
|
+
ZmE5YjE0NWIxMWYxYTE3ZTUwZTZmMmUwN2NjZjhlOGJmZWJlYTE3MjFhZmQy
|
15
|
+
ZDk3NDVhY2JjMzkwNmI5NTRkMmFiMzE4MDNmMTQwY2Q5MjA4ZWU=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.2.5
|
4
|
+
- 2.3.1
|
5
|
+
before_install: gem install bundler -v 1.10.6
|
6
|
+
deploy:
|
7
|
+
provider: rubygems
|
8
|
+
on:
|
9
|
+
tags: true
|
10
|
+
api_key:
|
11
|
+
secure: E4iOts6aVaN7qavJ39NKoAhtJPXVqXG0XQIXbJKshacxzs9WdZxB8v9lxCNCq9nAaybzw++e/CybT3jv+OeujMMJRF61qQ6LxD5btBJlrMItB1RIU0Gb6I0xjb/iIZk5hQejYxxi1wSezUBwwxP+AtyaY5Dw8CB/hH+jk8EgZwWpb70fpK6IARrZNM5XpoEIB/f/ZF1JU6Mfcdvik4mG6sbqTz/3bjv6QbzDw80ejIjzlFeAx7hek4XuIV5KAHU2+ArpRuMIpm03yOBgqrMke481Zqhu6XATz/SV9MLzpVgehttxziTj9fNEkW8Lfn35s4+CxNK1f+UHRraTBXFaiHCCclKAt8NmaxnaCSzHziYzRrryY0tHICiyirdftt6exFf3a+RUECEQim/BrOq7b3T1qMDewtWOp6zH2An+QQ/mVfcx/SPuzkrkZ1zU+MkZhQmJWCgbJQT7P4aeJLUhE9oi37PZg2Kurv5Ul0ERpjVfV0Y102IegfHlp8S/67oDeeQJmh9vhd22EhVnwWYnKxlnEsCFJeaclKtNfCb6VIoyzXmpRdwJyNzMvgHv5WnATQXBhzWXAssaZyEF2FLj88/vHByjJodFfTg3YS2Vj1DbozeLbySXr21+VxHiF0xclsCseQLtogiXkUCcfbHlBe3dCK3VPUVOgA1g0FDI6sE=
|
12
|
+
notifications:
|
13
|
+
slack:
|
14
|
+
secure: I1CCQzA99RbTG/urNV+zB/fH2H6o8SiMmr4WlXmJKHDJEdVwiFmEGLy0Hch1V2Me6udT3FW8uBMshVz2oVhCpu+vuGcky5raf9moHxM3go7kocFPET+NFBexJ0ejNZn+/P9VhFokafYR27AJyTU5TRR7gysnVqmw3kJBC66JyQRaly2zsL2cxkTtCAseArnou0e1K9SqKi8vQAT24nk7Vqxl9LcnCFjGuzNjjVA39SLRa2OSA9O2TOC/nQwSqQCMc0CiOd2qDD9PHC49uSvMnNjVRU5FLHUu3muBEY2ytSVlN1kQZRd4cdYEM4JXcfyEABrH/JggdastlSOAHDjJEarq9vNdaOBoNgiKqH1hF0yW/niv8+0ux0yRfdNEw6543U3KB5YWAlEtlm0cB5HJAx3urZxask2gHyApFOGjASItxDnPH9Z8S9HTTnUEy51oY1ELXUvANXdkRHI0ACGHeBaM3Pnm5//QpUT+V0jYo82yTe8j8H8O+w8eMQ86LEZ1I8hB+H8hqS3BLU3NiVa0MPpGwOfsbpNIOlUP61LS1dcTchAdMxZHeHp+d8gmzAlJCeesZeb+zv6kmu2iN+/ESsT0CT9Bq0TGyK3C+87y7vmB1k+qibnFt11/IAm/r23fYU6ctDTDY2Z/h4uDpN7Fycqeh4xfYqsmQKuEs66aZY0=
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/Guardfile
ADDED
data/Jenkinsfile
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
stage('Install dependencies') {
|
2
|
+
node {
|
3
|
+
checkout scm
|
4
|
+
withRvm('ruby-2.3.1') {
|
5
|
+
sh 'bundle -v || gem install bundler'
|
6
|
+
sh 'bundle install'
|
7
|
+
stash includes: 'Gemfile.lock, .bundle', name: 'bundle'
|
8
|
+
}
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
stage('Style checks') {
|
13
|
+
parallel(Rubocop: {
|
14
|
+
node {
|
15
|
+
checkout scm
|
16
|
+
withRvm('ruby-2.3.1') {
|
17
|
+
unstash 'bundle'
|
18
|
+
bundle_exec 'rake style:rubocop'
|
19
|
+
}
|
20
|
+
}
|
21
|
+
})
|
22
|
+
}
|
23
|
+
|
24
|
+
stage('Tests') {
|
25
|
+
parallel(Unit: {
|
26
|
+
node {
|
27
|
+
checkout scm
|
28
|
+
withRvm('ruby-2.3.1') {
|
29
|
+
unstash 'bundle'
|
30
|
+
bundle_exec 'rake spec:unit'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}, Integration: {
|
34
|
+
node {
|
35
|
+
checkout scm
|
36
|
+
withRvm('ruby-2.3.1') {
|
37
|
+
unstash 'bundle'
|
38
|
+
bundle_exec 'rake spec:integration'
|
39
|
+
}
|
40
|
+
}
|
41
|
+
}, System: {
|
42
|
+
node {
|
43
|
+
checkout scm
|
44
|
+
withRvm('ruby-2.3.1') {
|
45
|
+
unstash 'bundle'
|
46
|
+
bundle_exec 'rake spec:system'
|
47
|
+
}
|
48
|
+
}
|
49
|
+
})
|
50
|
+
}
|
51
|
+
|
52
|
+
if (isRelease()) {
|
53
|
+
stage('Publish') {
|
54
|
+
echo 'Would publish to rubygems.org' // TODO
|
55
|
+
slackSend "Published ${name()} gem version ${version()} to the rubygems.org", color: 'good'
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
def bundle_exec(command) {
|
60
|
+
sh "bundle exec ${command}"
|
61
|
+
}
|
62
|
+
|
63
|
+
def isRelease() {
|
64
|
+
false // FIXME: Building git tags is not yet supported (JENKINS-34395)
|
65
|
+
}
|
66
|
+
|
67
|
+
def name() {
|
68
|
+
node {
|
69
|
+
def matcher = readFile('packer-client.gemspec') =~ "spec.name += '(.+)'"
|
70
|
+
matcher ? matcher[0][1] : null
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
def version() {
|
75
|
+
node {
|
76
|
+
def matcher = readFile('lib/packer/version.rb') =~ "VERSION = '(.+)'"
|
77
|
+
matcher ? matcher[0][1] : null
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
def withRvm(version, cl) {
|
82
|
+
withRvm(version, "executor-${env.EXECUTOR_NUMBER}") {
|
83
|
+
cl()
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
def withRvm(version, gemset, cl) {
|
88
|
+
RVM_HOME='$HOME/.rvm'
|
89
|
+
paths = [
|
90
|
+
"$RVM_HOME/gems/$version@$gemset/bin",
|
91
|
+
"$RVM_HOME/gems/$version@global/bin",
|
92
|
+
"$RVM_HOME/rubies/$version/bin",
|
93
|
+
"$RVM_HOME/bin",
|
94
|
+
"${env.PATH}"
|
95
|
+
]
|
96
|
+
def path = paths.join(':')
|
97
|
+
withEnv(["PATH=${env.PATH}:$RVM_HOME", "RVM_HOME=$RVM_HOME"]) {
|
98
|
+
sh "#!/bin/bash\nset +x; source $RVM_HOME/scripts/rvm; rvm use --create --install --binary $version@$gemset"
|
99
|
+
}
|
100
|
+
withEnv([
|
101
|
+
"PATH=$path",
|
102
|
+
"GEM_HOME=$RVM_HOME/gems/$version@$gemset",
|
103
|
+
"GEM_PATH=$RVM_HOME/gems/$version@$gemset:$RVM_HOME/gems/$version@global",
|
104
|
+
"MY_RUBY_HOME=$RVM_HOME/rubies/$version",
|
105
|
+
"IRBRC=$RVM_HOME/rubies/$version/.irbrc",
|
106
|
+
"RUBY_VERSION=$version"
|
107
|
+
]) {
|
108
|
+
cl()
|
109
|
+
}
|
110
|
+
}
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Ben Vidulich
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# Packer Client
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/zl4bv/packer-ruby.svg?branch=master)](https://travis-ci.org/zl4bv/packer-ruby)
|
4
|
+
|
5
|
+
A ruby client for HashiCorp's [Packer](https://www.packer.io) tool.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'packer-client'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install packer-client
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'packer'
|
27
|
+
client = Packer::Client.new
|
28
|
+
|
29
|
+
# Override path to Packer executable
|
30
|
+
client.executable_path = 'C:\HashiCorp\Packer\packer.exe'
|
31
|
+
|
32
|
+
# Override maximum time that Packer may execute for
|
33
|
+
client.execution_timeout = 7200
|
34
|
+
```
|
35
|
+
|
36
|
+
### Build: Build image(s) from template
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
client.build('template.json')
|
40
|
+
|
41
|
+
# Get build artifacts
|
42
|
+
client.build('template.json').artifacts
|
43
|
+
```
|
44
|
+
|
45
|
+
### Fix: Fix template
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# Get the fixed template JSON
|
49
|
+
client.fix('template.json').json
|
50
|
+
|
51
|
+
# Determine if template is valid
|
52
|
+
client.fix('template.json').valid?
|
53
|
+
```
|
54
|
+
|
55
|
+
### Inspect: See components of a template
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
# Get user variables
|
59
|
+
client.inspect_template('template.json').template_variables
|
60
|
+
|
61
|
+
# Get builders
|
62
|
+
client.inspect_template('template.json').template_builders
|
63
|
+
|
64
|
+
# Get provisioners
|
65
|
+
client.inspect_template('template.json').template_provisioners
|
66
|
+
```
|
67
|
+
|
68
|
+
### Push: Push a template to a Packer build service
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
client.push('template.json')
|
72
|
+
```
|
73
|
+
|
74
|
+
### Validate: Check that a template is valid
|
75
|
+
|
76
|
+
```ruby
|
77
|
+
client.validate('template.json').valid?
|
78
|
+
```
|
79
|
+
|
80
|
+
### Version: Get the Packer version
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
# Get version
|
84
|
+
client.version.version
|
85
|
+
|
86
|
+
# Get version commit
|
87
|
+
client.version.version_commit
|
88
|
+
|
89
|
+
# Get prerelease version
|
90
|
+
client.version.version_prerelease
|
91
|
+
```
|
92
|
+
|
93
|
+
## Contributing
|
94
|
+
|
95
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/zl4bv/packer-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
data/Rakefile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
|
5
|
+
namespace :style do
|
6
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
7
|
+
t.options = ['--fail-level', 'warning']
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Run all style checks'
|
12
|
+
task style: ['style:rubocop']
|
13
|
+
|
14
|
+
namespace :spec do
|
15
|
+
RSpec::Core::RakeTask.new(:unit) do |t|
|
16
|
+
t.pattern = 'spec/unit/**/*_spec.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec::Core::RakeTask.new(:integration) do |t|
|
20
|
+
t.pattern = 'spec/integration/**/*_spec.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Note you must have Packer installed to run the system tests
|
24
|
+
RSpec::Core::RakeTask.new(:system) do |t|
|
25
|
+
t.pattern = 'spec/system/**/*_spec.rb'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
task default: [:style, 'spec:unit', 'spec:integration']
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'packer'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require 'pry'
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/lib/packer.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
require 'os'
|
4
|
+
|
5
|
+
require 'packer/message/base'
|
6
|
+
require 'packer/message/artifact'
|
7
|
+
require 'packer/message/artifact_file'
|
8
|
+
require 'packer/message/error'
|
9
|
+
require 'packer/message/template_builder'
|
10
|
+
require 'packer/message/template_provisioner'
|
11
|
+
require 'packer/message/template_variable'
|
12
|
+
require 'packer/message/ui'
|
13
|
+
|
14
|
+
require 'packer/output/base'
|
15
|
+
require 'packer/output/machine_readable'
|
16
|
+
require 'packer/output/build'
|
17
|
+
require 'packer/output/fix'
|
18
|
+
require 'packer/output/inspect'
|
19
|
+
require 'packer/output/push'
|
20
|
+
require 'packer/output/validate'
|
21
|
+
require 'packer/output/version'
|
22
|
+
|
23
|
+
require 'packer/client'
|
24
|
+
require 'packer/version'
|
@@ -0,0 +1,187 @@
|
|
1
|
+
module Packer
|
2
|
+
# Ruby client for HashiCorp Packer.
|
3
|
+
class Client
|
4
|
+
# Sets the path to the Packer executable.
|
5
|
+
attr_writer :executable_path
|
6
|
+
|
7
|
+
# Sets the maximum amount of time Packer may execute for before timing
|
8
|
+
# out.
|
9
|
+
attr_writer :execution_timeout
|
10
|
+
|
11
|
+
# Executes +packer build+.
|
12
|
+
#
|
13
|
+
# Will execute multiple builds in parallel as defined in the template.
|
14
|
+
# The various artifacts created by the template will be outputted.
|
15
|
+
#
|
16
|
+
# @param [String,Packer::Template] template the Packer template
|
17
|
+
# @param [Hash] options
|
18
|
+
# @option options [Boolean] :force force a build to continue if artifacts
|
19
|
+
# exist, deletes existing artifacts
|
20
|
+
# @option options [Array<String>] :except build all builds other than
|
21
|
+
# these
|
22
|
+
# @option options [Array<String>] :only only build the given builds by
|
23
|
+
# name
|
24
|
+
# @option options [Boolean] :parallel disable parallelization (on by
|
25
|
+
# default)
|
26
|
+
# @option options [Hash] :vars variables for templates
|
27
|
+
# @option options [String] :var_file path to JSON file containing user
|
28
|
+
# variables
|
29
|
+
# @return [Packer::Output::Build]
|
30
|
+
def build(template, options = {})
|
31
|
+
args = ['build', '-machine-readable']
|
32
|
+
args << '-force' if options.key?(:force)
|
33
|
+
args << "-except=#{options[:except].join(',')}" if options.key?(:except)
|
34
|
+
args << "-only=#{options[:only].join(',')}" if options.key?(:only)
|
35
|
+
args << "-parallel=#{options[:parallel]}" if options.key?(:parallel)
|
36
|
+
args << "-var-file=#{options[:var_file]}" if options.key?(:var_file)
|
37
|
+
|
38
|
+
vars = options[:vars] || {}
|
39
|
+
vars.each { |key, val| args << "-var '#{key}=#{val}'" }
|
40
|
+
|
41
|
+
args << template
|
42
|
+
|
43
|
+
Packer::Output::Build.new(command(args))
|
44
|
+
end
|
45
|
+
|
46
|
+
# @api private
|
47
|
+
# @param [Array<String>] args to pass to Packer
|
48
|
+
def command(args)
|
49
|
+
cmd = [executable_path, args].join(' ')
|
50
|
+
so = Mixlib::ShellOut.new(cmd, timeout: execution_timeout)
|
51
|
+
so.run_command
|
52
|
+
end
|
53
|
+
|
54
|
+
# Gets the path to the Packer executable. Defaults to +packer.exe+ on
|
55
|
+
# Windows and +packer+ on other platforms. The default values expect the
|
56
|
+
# Packer executable to be available via the PATH.
|
57
|
+
#
|
58
|
+
# @return [String] path to Packer executable
|
59
|
+
def executable_path
|
60
|
+
return @executable_path if @executable_path
|
61
|
+
|
62
|
+
if OS.windows?
|
63
|
+
'packer.exe'
|
64
|
+
else
|
65
|
+
'packer'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Gets the maximum amount of time Packer may execute for before timing
|
70
|
+
# out. Defaults to 2 hours.
|
71
|
+
#
|
72
|
+
# @return [Fixnum] execution timeout
|
73
|
+
def execution_timeout
|
74
|
+
@execution_timeout || 7200 # 2 hours
|
75
|
+
end
|
76
|
+
|
77
|
+
# Executes +packer fix+.
|
78
|
+
#
|
79
|
+
# Reads the JSON template and attempts to fix know backwards
|
80
|
+
# incompatibilities. The fixed template will be outputted to standard out.
|
81
|
+
#
|
82
|
+
# If the template cannot be fixed due to an error, the command will exit
|
83
|
+
# will a non-zero exist status. Error messages will appear on standard
|
84
|
+
# error.
|
85
|
+
#
|
86
|
+
# @param [String,Packer::Template] template the Packer template
|
87
|
+
# @return [Packer::Output::Fix]
|
88
|
+
def fix(template)
|
89
|
+
Packer::Output::Fix.new(command(['fix', template]))
|
90
|
+
end
|
91
|
+
|
92
|
+
# Excutes +packer inspect+
|
93
|
+
#
|
94
|
+
# Inspects a template, parsing and outputting the components a template
|
95
|
+
# defines. This does not validate the contents of a template (other than
|
96
|
+
# basic syntax by necessity).
|
97
|
+
#
|
98
|
+
# @param [String,Packer::Template] template the Packer template
|
99
|
+
# @return [Packer::Output::Inspect]
|
100
|
+
def inspect_template(template)
|
101
|
+
args = ['inspect', '-machine-readable', template]
|
102
|
+
|
103
|
+
Packer::Output::Inspect.new(command(args))
|
104
|
+
end
|
105
|
+
|
106
|
+
# Executes +packer push+.
|
107
|
+
#
|
108
|
+
# Push the given template and supporting files to a Packer build service
|
109
|
+
# such as Atlas.
|
110
|
+
#
|
111
|
+
# If a build configuration for the given template does not exist, it will
|
112
|
+
# be created automatically. If the build configuration already exists, a
|
113
|
+
# new version will be created with this template and the supporting files.
|
114
|
+
#
|
115
|
+
# Additional configuration options (such as Atlas server URL and files to
|
116
|
+
# include) may be specified in the "push" section of the Packer template.
|
117
|
+
# Please see the online documentation about these configurables.
|
118
|
+
#
|
119
|
+
# @param [String,Packer::Template] template the Packer template
|
120
|
+
# @param [Hash] options
|
121
|
+
# @option options [String] :message a message to identify the purpose of
|
122
|
+
# changes in this Packer template much like a VCS commit message
|
123
|
+
# @option options [String] :name the destination build in Atlas. This is
|
124
|
+
# in a format "username/name".
|
125
|
+
# @option options [String] :token the access token to use when uploading
|
126
|
+
# @option options [Hash] :vars variables for templates
|
127
|
+
# @option options [String] :var_file path to JSON file containing user
|
128
|
+
# variables
|
129
|
+
# @return [Packer::Output::Push]
|
130
|
+
def push(template, options = {})
|
131
|
+
args = ['push']
|
132
|
+
args << "-message=#{options[:message]}" if options.key?(:message)
|
133
|
+
args << "-name=#{options[:name]}" if options.key?(:name)
|
134
|
+
args << "-token=#{options[:token]}" if options.key?(:token)
|
135
|
+
args << "-var-file=#{options[:var_file]}" if options.key?(:var_file)
|
136
|
+
|
137
|
+
vars = options[:vars] || {}
|
138
|
+
vars.each { |key, val| args << "-var '#{key}=#{val}'" }
|
139
|
+
|
140
|
+
args << template
|
141
|
+
|
142
|
+
Packer::Output::Push.new(command(args))
|
143
|
+
end
|
144
|
+
|
145
|
+
# Executes +packer validate+
|
146
|
+
#
|
147
|
+
# Checks the template is valid by parsing the template and also checking
|
148
|
+
# the configuration with the various builders, provisioners, etc.
|
149
|
+
#
|
150
|
+
# If it is not valid, the errors will be shown and the command will exit
|
151
|
+
# with a non-zero exit status. If it is valid, it will exist with a zero
|
152
|
+
# exist status.
|
153
|
+
#
|
154
|
+
# @param [String,Packer::Template] template the Packer template
|
155
|
+
# @param [Hash] options
|
156
|
+
# @option options [Boolean] :syntax_only only check syntax. Do not verify
|
157
|
+
# config of the template.
|
158
|
+
# @option options [Array<String>] :except validate all builds other than
|
159
|
+
# these
|
160
|
+
# @option options [Array<String>] :only validate only these builds
|
161
|
+
# @option options [Hash] :vars variables for templates
|
162
|
+
# @option options [String] :var_file path to JSON file containing user
|
163
|
+
# variables
|
164
|
+
# @return [Packer::Output::Validate]
|
165
|
+
def validate(template, options = {})
|
166
|
+
args = ['validate']
|
167
|
+
args << '-syntax-only' if options.key?(:syntax_only)
|
168
|
+
args << "-except=#{options[:except].join(',')}" if options.key?(:except)
|
169
|
+
args << "-only=#{options[:only].join(',')}" if options.key?(:only)
|
170
|
+
args << "-var-file=#{options[:var_file]}" if options.key?(:var_file)
|
171
|
+
|
172
|
+
vars = options[:vars] || {}
|
173
|
+
vars.each { |key, val| args << "-var '#{key}=#{val}'" }
|
174
|
+
|
175
|
+
args << template
|
176
|
+
|
177
|
+
Packer::Output::Validate.new(command(args))
|
178
|
+
end
|
179
|
+
|
180
|
+
# Executes +packer version+
|
181
|
+
#
|
182
|
+
# @return [Packer::Output::Version]
|
183
|
+
def version
|
184
|
+
Packer::Output::Version.new(command(['version', '-machine-readable']))
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Message representing an artifact produced by a builder
|
4
|
+
class Artifact < Base
|
5
|
+
# Zero-based index of the artifact being described
|
6
|
+
attr_accessor :artifact_index
|
7
|
+
|
8
|
+
# The unique ID of the builder
|
9
|
+
attr_accessor :builder_id
|
10
|
+
|
11
|
+
attr_accessor :files
|
12
|
+
|
13
|
+
# The ID (if any) of the artifact that was built
|
14
|
+
attr_accessor :id
|
15
|
+
|
16
|
+
# If +true+, this means the artifact was nil
|
17
|
+
attr_accessor :nil
|
18
|
+
|
19
|
+
# The human-readable string description of the artifact
|
20
|
+
attr_accessor :string
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Message representing a file associated with an artifact
|
4
|
+
class ArtifactFile < Base
|
5
|
+
# The zero-based index of the file
|
6
|
+
attr_accessor :file_index
|
7
|
+
|
8
|
+
# The filename
|
9
|
+
attr_accessor :filename
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
# @param [Array<String>] fields
|
13
|
+
def self.from_fields(fields)
|
14
|
+
msg = new
|
15
|
+
msg.timestamp = fields[0]
|
16
|
+
msg.target = fields[1]
|
17
|
+
msg.type = fields[2]
|
18
|
+
msg.data = fields[3..-1]
|
19
|
+
msg.file_index = fields[5]
|
20
|
+
msg.filename = fields[6]
|
21
|
+
msg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Base class for all message types
|
4
|
+
class Base
|
5
|
+
# Unix timestamp in UTC of when the message was printed
|
6
|
+
attr_accessor :timestamp
|
7
|
+
|
8
|
+
# Target of the following output
|
9
|
+
attr_accessor :target
|
10
|
+
|
11
|
+
# Type of message outputted by Packer
|
12
|
+
attr_accessor :type
|
13
|
+
|
14
|
+
# Zero or more values associated with the message type
|
15
|
+
attr_accessor :data
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
# @param [Array<String>] fields
|
19
|
+
def self.from_fields(fields)
|
20
|
+
msg = new
|
21
|
+
msg.timestamp = fields[0]
|
22
|
+
msg.target = fields[1]
|
23
|
+
msg.type = fields[2]
|
24
|
+
msg.data = fields[3..-1]
|
25
|
+
msg
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Represents an error message
|
4
|
+
class Error < Base
|
5
|
+
# The error message
|
6
|
+
attr_accessor :error
|
7
|
+
|
8
|
+
# @api private
|
9
|
+
# @param [Array<String>] fields
|
10
|
+
def self.from_fields(fields)
|
11
|
+
msg = new
|
12
|
+
msg.timestamp = fields[0]
|
13
|
+
msg.target = fields[1]
|
14
|
+
msg.type = fields[2]
|
15
|
+
msg.data = fields[3..-1]
|
16
|
+
msg.error = fields[3]
|
17
|
+
msg
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Message representing a builder defined within the template
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/machine-readable/command-inspect.html
|
6
|
+
class TemplateBuilder < Base
|
7
|
+
# The name of the builder
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
# The type of the builder
|
11
|
+
attr_accessor :builder_type
|
12
|
+
|
13
|
+
# @api private
|
14
|
+
# @param [Array<String>] fields
|
15
|
+
def self.from_fields(fields)
|
16
|
+
msg = new
|
17
|
+
msg.timestamp = fields[0]
|
18
|
+
msg.target = fields[1]
|
19
|
+
msg.type = fields[2]
|
20
|
+
msg.data = fields[3..-1]
|
21
|
+
msg.name = fields[3]
|
22
|
+
msg.builder_type = fields[4]
|
23
|
+
msg
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Message representing a provisioner defined within the template
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/machine-readable/command-inspect.html
|
6
|
+
class TemplateProvisioner < Base
|
7
|
+
# The name/type of the provisioner
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
# @api private
|
11
|
+
# @param [Array<String>] fields
|
12
|
+
def self.from_fields(fields)
|
13
|
+
msg = new
|
14
|
+
msg.timestamp = fields[0]
|
15
|
+
msg.target = fields[1]
|
16
|
+
msg.type = fields[2]
|
17
|
+
msg.data = fields[3..-1]
|
18
|
+
msg.name = fields[3]
|
19
|
+
msg
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Message representing a user variable defined within the template
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/machine-readable/command-inspect.html
|
6
|
+
class TemplateVariable < Base
|
7
|
+
# The name of the variable
|
8
|
+
attr_accessor :name
|
9
|
+
|
10
|
+
# The default value of the variable
|
11
|
+
attr_accessor :default
|
12
|
+
|
13
|
+
# If non-zero, then this variable is required
|
14
|
+
attr_accessor :required
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
# @param [Array<String>] fields
|
18
|
+
def self.from_fields(fields)
|
19
|
+
msg = new
|
20
|
+
msg.timestamp = fields[0]
|
21
|
+
msg.target = fields[1]
|
22
|
+
msg.type = fields[2]
|
23
|
+
msg.data = fields[3..-1]
|
24
|
+
msg.name = fields[3]
|
25
|
+
msg.default = fields[4]
|
26
|
+
msg.required = fields[5]
|
27
|
+
msg
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Packer
|
2
|
+
module Message
|
3
|
+
# Represents a message destined for a UI
|
4
|
+
class Ui < Base
|
5
|
+
# The type of UI message
|
6
|
+
attr_accessor :ui_message_type
|
7
|
+
|
8
|
+
# The string output to be displayed by the UI
|
9
|
+
attr_accessor :output
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
# @param [Array<String>] fields
|
13
|
+
def self.from_fields(fields)
|
14
|
+
msg = new
|
15
|
+
msg.timestamp = fields[0]
|
16
|
+
msg.target = fields[1]
|
17
|
+
msg.type = fields[2]
|
18
|
+
msg.data = fields[3..-1]
|
19
|
+
msg.ui_message_type = fields[3]
|
20
|
+
msg.output = fields[4]
|
21
|
+
msg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Base class for output from all Packer commands
|
4
|
+
class Base
|
5
|
+
# @param [Mixlib::ShellOut] output from the build command
|
6
|
+
def initialize(output)
|
7
|
+
@output = output
|
8
|
+
end
|
9
|
+
|
10
|
+
# Returns the raw standard error output
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
def stderr
|
14
|
+
@output.stderr
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the raw standard output
|
18
|
+
#
|
19
|
+
# @return [String]
|
20
|
+
def stdout
|
21
|
+
@output.stdout
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents the output from +packer build+.
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/command-line/build.html
|
6
|
+
class Build < MachineReadable
|
7
|
+
# Information about an artifact of the targeted item.
|
8
|
+
#
|
9
|
+
# @return [Array<Packer::Message::Artifact]
|
10
|
+
def artifacts
|
11
|
+
afcts = []
|
12
|
+
|
13
|
+
afct ||= Packer::Message::Artifact.new
|
14
|
+
select_messages('artifact').each do |fields|
|
15
|
+
afct.timestamp ||= fields[0]
|
16
|
+
afct.target ||= fields[1]
|
17
|
+
afct.type ||= 'artifact'
|
18
|
+
afct.artifact_index ||= fields[3]
|
19
|
+
|
20
|
+
case fields[4]
|
21
|
+
when 'builder-id'
|
22
|
+
afct.builder_id = fields[5]
|
23
|
+
when 'end'
|
24
|
+
afcts << afct
|
25
|
+
afct = Packer::Message::Artifact.new
|
26
|
+
when 'file'
|
27
|
+
afct.files ||= []
|
28
|
+
afct.files << Packer::Message::ArtifactFile.from_fields(fields)
|
29
|
+
when 'files-count'
|
30
|
+
next
|
31
|
+
when 'id'
|
32
|
+
afct.id = fields[5]
|
33
|
+
when 'nil'
|
34
|
+
afct.nil = true
|
35
|
+
when 'string'
|
36
|
+
afct.string = fields[5]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
afcts
|
41
|
+
end
|
42
|
+
|
43
|
+
# Build errors that occurred
|
44
|
+
#
|
45
|
+
# @return [Array<Packer::Message::Error]
|
46
|
+
def errors
|
47
|
+
select_messages('error').map { |fields| Packer::Message::Error.from_fields(fields) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents the output from +packer fix+.
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/command-line/fix.html
|
6
|
+
class Fix < Base
|
7
|
+
# JSON representing the fixed template or +nil+ if the fixing fails or the
|
8
|
+
# template is not valid.
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def json
|
12
|
+
return nil unless valid?
|
13
|
+
|
14
|
+
stdout
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns +true+ if the fixing was successful and the template is valid.
|
18
|
+
#
|
19
|
+
# @return [Boolean]
|
20
|
+
def valid?
|
21
|
+
@output.exitstatus.zero?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents the output from +packer inspect+.
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/command-line/inspect.html
|
6
|
+
class Inspect < MachineReadable
|
7
|
+
# User variables defined within the template.
|
8
|
+
#
|
9
|
+
# @return [Array<Packer::Message::TemplateVariable]
|
10
|
+
def template_variables
|
11
|
+
select_messages('template-variable').map { |fields| Packer::Message::TemplateVariable.from_fields(fields) }
|
12
|
+
end
|
13
|
+
|
14
|
+
# Builders defined within the template.
|
15
|
+
#
|
16
|
+
# @return [Array<Packer::Message::TemplateVariable]
|
17
|
+
def template_builders
|
18
|
+
select_messages('template-builder').map { |fields| Packer::Message::TemplateBuilder.from_fields(fields) }
|
19
|
+
end
|
20
|
+
|
21
|
+
# Provisioners defined within the template.
|
22
|
+
#
|
23
|
+
# @return [Array<Packer::Message::TemplateVariable]
|
24
|
+
def template_provisioners
|
25
|
+
select_messages('template-provisioner').map { |fields| Packer::Message::TemplateProvisioner.from_fields(fields) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents commands that produce machine-readable output
|
4
|
+
class MachineReadable < Base
|
5
|
+
# Outputs that would have normally gone to the console if Packer were
|
6
|
+
# running in human-readable mode.
|
7
|
+
#
|
8
|
+
# @return [Array<Packer::Message::Ui>]
|
9
|
+
def ui_messages
|
10
|
+
select_messages('ui').map { |fields| Packer::Message::Ui.from_fields(fields) }
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
# @param [String] type of message
|
17
|
+
# @return [Array<Array>] lists of message fields
|
18
|
+
def select_messages(type)
|
19
|
+
stdout
|
20
|
+
.split("\n")
|
21
|
+
.map { |line| CSV.parse(line).first }
|
22
|
+
.select { |fields| fields[2] == type }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents the output from +packer validate+.
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/command-line/validate.html
|
6
|
+
class Validate < Base
|
7
|
+
# Returns +true+ if the template is valid.
|
8
|
+
#
|
9
|
+
# @return [Boolean]
|
10
|
+
def valid?
|
11
|
+
@output.exitstatus.zero?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Packer
|
2
|
+
module Output
|
3
|
+
# Represents the output from +packer version+.
|
4
|
+
#
|
5
|
+
# @see https://www.packer.io/docs/machine-readable/command-version.html
|
6
|
+
class Version < MachineReadable
|
7
|
+
# The version of Packer running, only including the major, minor, and
|
8
|
+
# patch versions.
|
9
|
+
#
|
10
|
+
# @return [String]
|
11
|
+
def version
|
12
|
+
msgs = select_messages('version')
|
13
|
+
msgs[0][3]
|
14
|
+
end
|
15
|
+
|
16
|
+
# The SHA1 of the Git commit that build this version of Packer.
|
17
|
+
#
|
18
|
+
# @return [String]
|
19
|
+
def version_commit
|
20
|
+
msgs = select_messages('version-commit')
|
21
|
+
msgs[0][3]
|
22
|
+
end
|
23
|
+
|
24
|
+
# The prerelease tag (if any) for the running version of packer.
|
25
|
+
#
|
26
|
+
# @return [String]
|
27
|
+
def version_prerelease
|
28
|
+
msgs = select_messages('version-prelease')
|
29
|
+
msgs[0][3]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'packer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'packer-client'
|
8
|
+
spec.version = Packer::VERSION
|
9
|
+
spec.authors = ['Ben Vidulich']
|
10
|
+
spec.email = ['ben@vidulich.co.nz']
|
11
|
+
|
12
|
+
spec.summary = "A Ruby client for HashiCorp's Packer tool."
|
13
|
+
spec.description = "A Ruby client for HashiCorp's Packer tool."
|
14
|
+
spec.homepage = 'https://github.com/zl4bv/packer-ruby'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec'
|
25
|
+
spec.add_development_dependency 'rspec-its'
|
26
|
+
|
27
|
+
spec.add_runtime_dependency 'mixlib-shellout', '~> 2.2'
|
28
|
+
spec.add_runtime_dependency 'os', '~> 0.9'
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: packer-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ben Vidulich
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-its
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mixlib-shellout
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.2'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: os
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
97
|
+
description: A Ruby client for HashiCorp's Packer tool.
|
98
|
+
email:
|
99
|
+
- ben@vidulich.co.nz
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- .rubocop.yml
|
107
|
+
- .travis.yml
|
108
|
+
- CODE_OF_CONDUCT.md
|
109
|
+
- Gemfile
|
110
|
+
- Guardfile
|
111
|
+
- Jenkinsfile
|
112
|
+
- LICENSE.txt
|
113
|
+
- README.md
|
114
|
+
- Rakefile
|
115
|
+
- bin/console
|
116
|
+
- bin/setup
|
117
|
+
- lib/packer.rb
|
118
|
+
- lib/packer/client.rb
|
119
|
+
- lib/packer/message/artifact.rb
|
120
|
+
- lib/packer/message/artifact_file.rb
|
121
|
+
- lib/packer/message/base.rb
|
122
|
+
- lib/packer/message/error.rb
|
123
|
+
- lib/packer/message/template_builder.rb
|
124
|
+
- lib/packer/message/template_provisioner.rb
|
125
|
+
- lib/packer/message/template_variable.rb
|
126
|
+
- lib/packer/message/ui.rb
|
127
|
+
- lib/packer/output/base.rb
|
128
|
+
- lib/packer/output/build.rb
|
129
|
+
- lib/packer/output/fix.rb
|
130
|
+
- lib/packer/output/inspect.rb
|
131
|
+
- lib/packer/output/machine_readable.rb
|
132
|
+
- lib/packer/output/push.rb
|
133
|
+
- lib/packer/output/validate.rb
|
134
|
+
- lib/packer/output/version.rb
|
135
|
+
- lib/packer/version.rb
|
136
|
+
- packer-client.gemspec
|
137
|
+
homepage: https://github.com/zl4bv/packer-ruby
|
138
|
+
licenses:
|
139
|
+
- MIT
|
140
|
+
metadata: {}
|
141
|
+
post_install_message:
|
142
|
+
rdoc_options: []
|
143
|
+
require_paths:
|
144
|
+
- lib
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
requirements:
|
152
|
+
- - ! '>='
|
153
|
+
- !ruby/object:Gem::Version
|
154
|
+
version: '0'
|
155
|
+
requirements: []
|
156
|
+
rubyforge_project:
|
157
|
+
rubygems_version: 2.4.5
|
158
|
+
signing_key:
|
159
|
+
specification_version: 4
|
160
|
+
summary: A Ruby client for HashiCorp's Packer tool.
|
161
|
+
test_files: []
|