marathon_deploy 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35b3f25c8764a73dd299377a082c1bf279574ba3
4
- data.tar.gz: f8db464c0a0165b0f16de1bda5c170b07c069e60
3
+ metadata.gz: b3c10080e27dce236a05a0579d9ff2ba19517bb6
4
+ data.tar.gz: 19d88259390b2d88b19542cab495afafcf8445cf
5
5
  SHA512:
6
- metadata.gz: 77cdd112a5424d33c3188391194ae099090ed7bd15b6a3e97ccdf20d0b42517491b5342a51ddba7288b481413e319b84a281c45277b244f822ce1c182990c7a9
7
- data.tar.gz: cbee096acc67009a5b7183fc2eeb7a04890c94f54f09e1f715f43b47e27496f621132d0f8b1d37b60a33d38e0ad3280c2bbd3627ffccd2b232e921ce4984d4fe
6
+ metadata.gz: 0d10120a0317cfb3472efb082c579c3e9ae7b58c3cc3bc8e7ca0dcf3f7c3f26babb21d1876de9ba389fac83e290e7dd9e41ac9e77ba19f199cec66307d623274
7
+ data.tar.gz: 7d51c281c3efa1682114d11f597ffc0067578556ccd734dc0c9c05408e2ff430bd49df12725cdb4a57e6739a587d991893c20cd937310677ea2ce93076ac46c6
data/README.md CHANGED
@@ -1,26 +1,115 @@
1
- # MarathonDeploy
1
+ # Marathon Deploy
2
+
3
+ A [Marathon](https://mesosphere.github.io/marathon/) command-line deployment tool in Ruby. Takes a json or yaml file describing an application and pushes it to the Marathon [REST API](https://mesosphere.github.io/marathon/docs/rest-api.html)
4
+
5
+ ### Feature Summary
6
+ * Deploy a single application descriptor to multiple marathon endpoints
7
+ * Checks for existing deployment of application before starting new deployment
8
+ * Polls for Healthcheck results after deployment
9
+ * Proper exit codes for easier integration with Jenkins automated pipelines
10
+ * Deploy file macro substitution using values from ENV variables (eg, %%MACRO_NAME%%)
11
+ * PRODUCTION / PREPRODUCTION modes (specified with --environment)
12
+ * Rolling upgrade deployment strategy (Marathon default)
13
+
14
+
15
+ ### Roadmap Features
16
+ * Record actions and json payload to a database (for rollback, history, auditing)
17
+ * Deploy a deployment descriptor containing multiple applications
2
18
 
3
- TODO: Write a gem description
4
19
 
5
20
  ## Installation
6
21
 
7
- Add this line to your application's Gemfile:
22
+ Ensure Ruby (1.9+) and gem are installed on you system, then run:
8
23
 
9
- ```ruby
10
- gem 'marathon_deploy'
24
+ ```
25
+ $ gem install marathon_deploy
11
26
  ```
12
27
 
13
- And then execute:
14
-
15
- $ bundle
28
+ Executables from this gem (automatically added to your $PATH):
16
29
 
17
- Or install it yourself as:
30
+ $ deploy.rb (client program executable)
31
+ $ json2yaml.rb (convenience utility for converting json to yaml)
32
+ $ expand_macros.rb (expands all macros in the form %%MACRO%% with value of ENV[MACRO])
18
33
 
19
- $ gem install marathon_deploy
20
34
 
21
35
  ## Usage
22
36
 
23
- TODO: Write usage instructions here
37
+ ### Help
38
+ ```
39
+ deploy.rb -h
40
+ Usage: deploy.rb [options]
41
+ -u, --url MARATHON_URL(S) Default: ["http://localhost:8080"]
42
+ -l, --logfile LOGFILE Default: STDOUT
43
+ -v, --verbose Run verbosely
44
+ -f, --file DEPLOYFILE Deploy file with json or yaml file extension. Default: deploy.yaml
45
+ -e, --environment ENVIRONMENT Default: PREPRODUCTION
46
+ -h, --help Show this message
47
+ ```
48
+
49
+ ### Example Deployfile
50
+ By default, a file called 'deploy.yaml' is searched for in the current directory where deploy.rb is run from. An alternative file name can be provided with the -f parameter.
51
+
52
+ The file format must conform to the [Marathon API specification](https://mesosphere.github.io/marathon/docs/rest-api.html#post-/v2/apps)
53
+
54
+ Minimalistic example (using Docker container):
55
+
56
+ ```
57
+ id: python-example-stable
58
+ cmd: echo python stable `hostname` > index.html; python3 -m http.server 8080
59
+ mem: 16
60
+ cpus: 0.1
61
+ instances: 5
62
+ container:
63
+ type: DOCKER
64
+ docker:
65
+ image: ubuntu:14.04
66
+ network: BRIDGE
67
+ portMappings:
68
+ - containerPort: 8080
69
+ hostPort: 0
70
+ protocol: tcp
71
+ env:
72
+ SERVICE_TAGS: python,webapp,http,weight=100
73
+ SERVICE_NAME: python
74
+ healthChecks:
75
+ - portIndex: 0
76
+ protocol: TCP
77
+ gracePeriodSeconds: 30
78
+ intervalSeconds: 10
79
+ timeoutSeconds: 30
80
+ maxConsecutiveFailures: 3
81
+ - path: "/"
82
+ portIndex: 0
83
+ protocol: HTTP
84
+ gracePeriodSeconds: 30
85
+ intervalSeconds: 10
86
+ timeoutSeconds: 30
87
+ maxConsecutiveFailures: 3
88
+ ```
89
+
90
+ ### JSON to YAML file conversion
91
+
92
+ As a convenience, the provided json2yaml.rb script can convert a JSON file to the arguably more human-readable YAML format:
93
+
94
+ ```
95
+ $json2yaml.rb marathon-webapp.json > marathon-webapp.yaml
96
+ ```
97
+
98
+ ### Parsing a file with macro expansion from ENV variables
99
+
100
+ A helper script which takes a file and replaces all macros having the format %%MACRO%% with the values from ENV variables. Script will fail if there are no ENV values for macro names contained in the template.
101
+
102
+ ```
103
+ $expand_macros.rb -h
104
+ Usage: bin/expand_macros.rb [options]
105
+ -o, --outfile OUTFILE Default: STDOUT
106
+ -l, --logfile LOGFILE Default: STDOUT
107
+ -d, --debug Run in debug mode
108
+ -v, --version Version info
109
+ -f, --force force overwrite of existing OUTFILE
110
+ -t, --template TEMPLATE_FILE Input file. Default: dockerfile.tpl
111
+ -h, --help Show this message
112
+ ```
24
113
 
25
114
  ## Contributing
26
115
 
data/bin/deploy.rb CHANGED
@@ -5,6 +5,7 @@ require 'marathon_deploy/marathon_client'
5
5
  require 'marathon_deploy/error'
6
6
  require 'marathon_deploy/application'
7
7
  require 'marathon_deploy/environment'
8
+ require 'marathon_deploy/version'
8
9
  require 'optparse'
9
10
  require 'logger'
10
11
 
@@ -12,14 +13,15 @@ options = {}
12
13
 
13
14
  # DEFAULTS
14
15
  options[:deployfile] = MarathonDeploy::MarathonDefaults::DEFAULT_DEPLOYFILE
15
- options[:verbose] = MarathonDeploy::MarathonDefaults::DEFAULT_LOGLEVEL
16
+ options[:debug] = MarathonDeploy::MarathonDefaults::DEFAULT_LOGLEVEL
16
17
  options[:environment] = MarathonDeploy::MarathonDefaults::DEFAULT_ENVIRONMENT_NAME
17
- options[:marathon_endpoints] = nil
18
+ options[:marathon_endpoints] = MarathonDeploy::MarathonDefaults::DEFAULT_PREPRODUCTION_MARATHON_ENDPOINTS
18
19
  options[:logfile] = MarathonDeploy::MarathonDefaults::DEFAULT_LOGFILE
19
20
 
20
21
  OptionParser.new do |opts|
21
- opts.banner = "Usage: deploy.rb [options]"
22
-
22
+ opts.banner = "Usage: #{$0} [options]"
23
+ opts.release = MarathonDeploy::VERSION
24
+
23
25
  opts.on("-u","--url MARATHON_URL(S)", Array, "Default: #{options[:marathon_endpoints]}") do |u|
24
26
  options[:marathon_endpoints] = u
25
27
  end
@@ -28,8 +30,13 @@ OptionParser.new do |opts|
28
30
  options[:logfile] = l
29
31
  end
30
32
 
31
- opts.on("-v", "--verbose", "Run verbosely") do |v|
32
- options[:verbose] = Logger::DEBUG
33
+ opts.on("-d", "--debug", "Run in debug mode") do |d|
34
+ options[:debug] = Logger::DEBUG
35
+ end
36
+
37
+ opts.on("-v", "--version", "Version info") do |v|
38
+ puts "#{$0} version #{opts.release}"
39
+ exit!
33
40
  end
34
41
 
35
42
  opts.on("-f", "--file DEPLOYFILE" ,"Deploy file with json or yaml file extension. Default: #{options[:deployfile]}") do |f|
@@ -47,7 +54,7 @@ OptionParser.new do |opts|
47
54
  end.parse!
48
55
 
49
56
  $LOG = options[:logfile] ? Logger.new(options[:logfile]) : Logger.new(STDOUT)
50
- $LOG.level = options[:verbose]
57
+ $LOG.level = options[:debug]
51
58
 
52
59
  deployfile = options[:deployfile]
53
60
  environment = MarathonDeploy::Environment.new(options[:environment])
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'marathon_deploy/error'
4
+ require 'marathon_deploy/macro'
5
+ require 'marathon_deploy/version'
6
+ require 'optparse'
7
+ require 'logger'
8
+
9
+ DEFAULT_TEMPLATE_FILENAME = 'dockerfile.tpl'
10
+
11
+ options = {}
12
+
13
+ # DEFAULTS
14
+ options[:template] = DEFAULT_TEMPLATE_FILENAME
15
+ options[:debug] = Logger::FATAL #Logger::INFO
16
+ options[:outfile] = false
17
+ options[:logfile] = false
18
+ options[:force] = false
19
+
20
+
21
+ OptionParser.new do |opts|
22
+ opts.banner = "Usage: #{$0} [options]"
23
+ opts.release = MarathonDeploy::VERSION
24
+
25
+ opts.on("-o","--outfile OUTFILE", String, "Default: STDOUT") do |o|
26
+ options[:outfile] = o
27
+ end
28
+
29
+ opts.on("-l", "--logfile LOGFILE", "Default: STDOUT") do |l|
30
+ options[:logfile] = l
31
+ end
32
+
33
+ opts.on("-d", "--debug", "Run in debug mode") do |d|
34
+ options[:debug] = Logger::DEBUG
35
+ end
36
+
37
+ opts.on("-v", "--version", "Version info") do |v|
38
+ puts "#{$0} version #{opts.release}"
39
+ exit!
40
+ end
41
+
42
+ opts.on("-f", "--force", "force overwrite of existing OUTFILE") do |f|
43
+ options[:force] = true
44
+ end
45
+
46
+ opts.on("-t", "--template TEMPLATE_FILE" ,"Input file. Default: #{options[:template]}") do |t|
47
+ options[:template] = t
48
+ end
49
+
50
+ opts.on_tail("-h", "--help", "Show this message") do
51
+ puts opts
52
+ exit
53
+ end
54
+ end.parse!
55
+
56
+ $LOG = options[:logfile] ? Logger.new(options[:logfile]) : Logger.new(STDOUT)
57
+ $LOG.level = options[:debug]
58
+
59
+ template = options[:template]
60
+
61
+ begin
62
+ processed = MarathonDeploy::Macro.process_macros(template)
63
+ rescue MarathonDeploy::Error::UndefinedMacroError => e
64
+ abort(e.message)
65
+ rescue Errno::ENOENT => e
66
+ abort("Could not locate template file #{template}")
67
+ end
68
+
69
+ output = IO.new(STDOUT.fileno)
70
+ outfile = options[:outfile]
71
+ if (outfile)
72
+ abort("File #{outfile} already exists. Please remove or rename it.") if (File.exists?(outfile) && !options[:force])
73
+ fd = IO.sysopen(outfile, "w")
74
+ output = IO.new(fd,'w')
75
+ end
76
+
77
+ output.write processed
78
+ output.close
79
+
@@ -10,7 +10,7 @@ module MarathonDeploy
10
10
  HEALTHY_WAIT_TIMEOUT = 300
11
11
  HEALTHY_WAIT_RECHECK_INTERVAL = 3
12
12
  PRODUCTION_ENVIRONMENT_NAME = 'PRODUCTION'
13
- DEFAULT_ENVIRONMENT_NAME = 'INTEGRATION'
13
+ DEFAULT_ENVIRONMENT_NAME = 'PREPRODUCTION'
14
14
  DEFAULT_PREPRODUCTION_MARATHON_ENDPOINTS = ['http://localhost:8080']
15
15
  DEFAULT_PRODUCTION_MARATHON_ENDPOINTS = ['http://paasmaster46-1.mobile.rz:8080']
16
16
  DEFAULT_DEPLOYFILE = 'deploy.yaml'
@@ -20,7 +20,7 @@ module MarathonDeploy
20
20
  MARATHON_DEPLOYMENT_REST_PATH = '/v2/deployments/'
21
21
 
22
22
  @@preproduction_override = {
23
- :instances => 20,
23
+ :instances => 5,
24
24
  :mem => 512,
25
25
  :cpus => 0.1
26
26
  }
@@ -1,3 +1,3 @@
1
1
  module MarathonDeploy
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.files << ["bin/deploy.rb"]
18
18
  spec.files << ["bin/json2yaml.rb"]
19
+ spec.files << ["bin/expand_macros.rb"]
20
+
19
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
23
  spec.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marathon_deploy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Colby
@@ -71,6 +71,7 @@ email:
71
71
  - jcolby@team.mobile.de
72
72
  executables:
73
73
  - deploy.rb
74
+ - expand_macros.rb
74
75
  - json2yaml.rb
75
76
  extensions: []
76
77
  extra_rdoc_files: []
@@ -83,6 +84,7 @@ files:
83
84
  - Rakefile
84
85
  - TODO
85
86
  - bin/deploy.rb
87
+ - bin/expand_macros.rb
86
88
  - bin/json2yaml.rb
87
89
  - examples/deploy.json
88
90
  - examples/deploy.yaml