fleet-api 0.0.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5bcab7f3762c80b4d843b7398603462486b6adc3
4
- data.tar.gz: fd587b58a42bbe1fcaf4ec29e88fedc16dcb3fd0
3
+ metadata.gz: ded5145e7361d7b0e441c91f3811a783a11ec94e
4
+ data.tar.gz: b544579b3f35b5764b4a863618d0b96b38c68442
5
5
  SHA512:
6
- metadata.gz: d4fbd90db07fa039256d3798acd6cbd780536b5649a912ef28c5ebe8ee99ce6a4ed11a845d50a503c4a55d3b135a8302663918e217e541c8de591c5b30a68860
7
- data.tar.gz: c429704b2f41f073d7a55d798d289b2abbe36c1d04e5124478e66b1653181df6c143b6b5b0b125cd8ed15c08a818cd021a6b30394dd82a93489983745c0a9f6c
6
+ metadata.gz: b748b4fc6014400b8228415d432045d379ba191469a80e08c534bf16180126ee4a37f1d6b074043d2d86aa9e82eaac4fcd12a5a907fb94256028a87562d6cf08
7
+ data.tar.gz: 512d2230352cfa529fbeb4a7c412fab72bde79b68660f6047d1fe5f81a76a25464b85ee3d3939c60b5d56357927a86d1c3e8a5a8fc83547f6e80c1a2cae39dce
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.1
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fleet-api (0.0.1)
4
+ fleet-api (0.5.0)
5
5
  faraday (= 0.8.9)
6
6
  faraday_middleware (= 0.9.0)
7
7
 
@@ -44,5 +44,5 @@ DEPENDENCIES
44
44
  fleet-api!
45
45
  rake
46
46
  rspec (~> 3.0)
47
- simplecov
48
- simplecov-rcov
47
+ simplecov (~> 0.9.0)
48
+ simplecov-rcov (~> 0.2.3)
data/LICENSE CHANGED
@@ -186,7 +186,7 @@ Apache License
186
186
  same "printed page" as the copyright notice for easier
187
187
  identification within third-party archives.
188
188
 
189
- Copyright {yyyy} {name of copyright owner}
189
+ Copyright 2014 CenturyLink
190
190
 
191
191
  Licensed under the Apache License, Version 2.0 (the "License");
192
192
  you may not use this file except in compliance with the License.
data/README.md CHANGED
@@ -1,2 +1,115 @@
1
1
  fleet-api
2
2
  =========
3
+
4
+ Provides a Ruby wrapper around the CoreOS Fleet API.
5
+
6
+ The client allows programmatic access to most of the *fleetctl* commands including the ability to load, start, stop, unload and destroy unit files.
7
+
8
+ At this point, there is no official Fleet API (though one is [in the works](https://github.com/coreos/fleet/blob/master/Documentation/api-v1-alpha.md)) so this library mimcs the behavior of the *fleetctl* command line tool and simply writes data to the [etcd]() key-value-store. The Fleet daemon reads data out of specific keys in etcd and processes it as appropiate.
9
+
10
+ As work on the actual Fleet API progresses, this library will be refactored to use the real API.
11
+
12
+ An alternative implementation is available in the [cloudspace/ruby-fleetctl](https://github.com/cloudspace/ruby-fleetctl) gem. The *ruby-fleetctl* gem takes a different approach and uses SSH to interact directly with the *fleetctl* binary to send commands. Our approach of writing directly to etcd cuts out the *fleetctl* middleman but is in more danger of being broken by future releases since we're effectively using a "private API".
13
+
14
+ The current version of the *fleet-api* gem is known to work with version 0.5.0 of Fleet which ships with the the current stable version of CoreOS (367.1.0)
15
+
16
+ ### Installation
17
+
18
+ Install the gem directly:
19
+
20
+ gem install fleet-api
21
+
22
+ Alternatively, add this line to your application's Gemfile:
23
+
24
+ gem 'fleet-api', require: 'fleet'
25
+
26
+
27
+ ### Usage
28
+
29
+ Configure the URL for the etcd API:
30
+
31
+ require 'fleet'
32
+
33
+ Fleet.configure do |fleet|
34
+ fleet.fleet_api_url = 'http://10.1.42.1:4001'
35
+ end
36
+
37
+ If you don't provide an explicit value for the `.fleet_api_url` attribute, it will default to using the value of the `FLEETCTL_ENDPOINT` environment variable.
38
+
39
+ **Note: since this Fleet API is not yet available in the stable version of CoreOS, the URL value provided must be the endpoint for the etcd API.**
40
+
41
+ #### Service Definitions
42
+
43
+ When submitting a service definition to the `Fleet::Client` you must convert your [unit file](http://www.freedesktop.org/software/systemd/man/systemd.unit.html) into a Ruby hash. Each section in the unit file is represented as a key/value pair in the hash where the key is the name of the section and the value is another hash containing all the statements for that section.
44
+
45
+ For example, look at the following unit file.
46
+
47
+ [Unit]
48
+ Description=Useless infinite loop
49
+
50
+ [Service]
51
+ ExecStart=/bin/bash -c "while true; do sleep 1; done"
52
+
53
+ This unit file would be represented as the following Ruby hash.
54
+
55
+ {
56
+ 'Unit' => {
57
+ 'Description' => 'Useless infinite loop'
58
+ },
59
+ 'Service' => {
60
+ 'ExecStart' => "/bin/bash -c \"while true; do sleep 1; done\""
61
+ }
62
+ }
63
+
64
+ #### Loading a Unit File
65
+
66
+ Equivalent of `fleetctl load`:
67
+
68
+ service = {
69
+ 'Unit' => {
70
+ 'Description' => 'Useless infinite loop'
71
+ },
72
+ 'Service' => {
73
+ 'ExecStart' => "/bin/bash -c \"while true; do sleep 1; done\""
74
+ }
75
+ }
76
+
77
+ client = Fleet.new
78
+ client.load('forever.service', service)
79
+
80
+ Note that the name you pass-in as the first parameter to the `.load` method should end in ".service"
81
+
82
+ #### Starting a Service
83
+
84
+ Equivalent of `fleetctl start`:
85
+
86
+ client = Fleet.new
87
+ client.start('forever.service')
88
+
89
+ #### Stopping a Service
90
+
91
+ Equivalent of `fleetctl stop`:
92
+
93
+ client = Fleet.new
94
+ client.stop('forever.service')
95
+
96
+ #### Unloading a Unit File
97
+
98
+ Equivalent of `fleetctl unload`:
99
+
100
+ client = Fleet.new
101
+ client.unload('forever.service')
102
+
103
+ #### Destroying a Service
104
+
105
+ Equivalent of `fleetctl destroy`:
106
+
107
+ client = Fleet.new
108
+ client.destroy('forever.service')
109
+
110
+ #### Retrieving Service Status
111
+
112
+ Equivalent of `fleetctl status`:
113
+
114
+ client = Fleet.new
115
+ client.status('forever.service')
data/fleet-api.gemspec CHANGED
@@ -7,16 +7,18 @@ Gem::Specification.new do |gem|
7
7
  gem.summary = 'A simple REST client for the CoreOS Fleet API'
8
8
  gem.homepage = 'https://github.com/centurylinklabs/fleet-api'
9
9
  gem.license = 'Apache 2'
10
+ gem.platform = Gem::Platform::RUBY
10
11
  gem.files = `git ls-files`.split($\)
11
12
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
12
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
14
  gem.name = 'fleet-api'
14
15
  gem.require_paths = %w(lib)
15
16
  gem.version = Fleet::VERSION
17
+ gem.required_ruby_version = '>= 1.9.3'
16
18
  gem.add_dependency 'faraday', '= 0.8.9'
17
19
  gem.add_dependency 'faraday_middleware', '= 0.9.0'
18
20
  gem.add_development_dependency 'rake'
19
21
  gem.add_development_dependency 'rspec', '~> 3.0'
20
- gem.add_development_dependency 'simplecov'
21
- gem.add_development_dependency 'simplecov-rcov'
22
+ gem.add_development_dependency 'simplecov', '~> 0.9.0'
23
+ gem.add_development_dependency 'simplecov-rcov', '~> 0.2.3'
22
24
  end
data/lib/fleet/client.rb CHANGED
@@ -12,7 +12,7 @@ module Fleet
12
12
 
13
13
  FLEET_PATH = 'v2/keys/_coreos.com/fleet'
14
14
  MAX_RETRIES = 10
15
- SLEEP_TIME = (1.0 / 10.0)
15
+ SLEEP_TIME = (4.0 / MAX_RETRIES.to_f)
16
16
 
17
17
  attr_accessor(*Configuration::VALID_OPTIONS_KEYS)
18
18
 
@@ -30,24 +30,26 @@ module Fleet
30
30
  include Fleet::Client::State
31
31
  include Fleet::Client::Unit
32
32
 
33
- def load(name, service_def={})
33
+ def load(name, service_def=nil)
34
34
 
35
- unless service_def.is_a?(ServiceDefinition)
36
- service_def = ServiceDefinition.new(name, service_def)
37
- end
35
+ if service_def
36
+ unless service_def.is_a?(ServiceDefinition)
37
+ service_def = ServiceDefinition.new(name, service_def)
38
+ end
38
39
 
39
- begin
40
- create_unit(service_def.sha1, service_def.to_unit)
41
- rescue Fleet::PreconditionFailed
42
- end
40
+ begin
41
+ create_unit(service_def.sha1, service_def.to_unit)
42
+ rescue Fleet::PreconditionFailed
43
+ end
43
44
 
44
- begin
45
- create_job(service_def.name, service_def.to_job)
46
- rescue Fleet::PreconditionFailed
45
+ begin
46
+ create_job(service_def.name, service_def.to_job)
47
+ rescue Fleet::PreconditionFailed
48
+ end
47
49
  end
48
50
 
49
- update_job_target_state(service_def.name, :loaded)
50
- wait_for_load_state(service_def.name, 'loaded')
51
+ update_job_target_state(name, :loaded)
52
+ wait_for_load_state(name, 'loaded')
51
53
  end
52
54
 
53
55
  def start(service_name)
@@ -69,7 +71,7 @@ module Fleet
69
71
  wait_for_load_state(service_name, :no_state)
70
72
  end
71
73
 
72
- def states(service_name)
74
+ def status(service_name)
73
75
  fleet_state = get_state(service_name)
74
76
  service_states = JSON.parse(fleet_state['node']['value'])
75
77
  service_states.each_with_object({}) do |(k, v), hash|
@@ -86,7 +88,7 @@ module Fleet
86
88
  def wait_for_load_state(service_name, target_state='loaded')
87
89
  result = MAX_RETRIES.times do
88
90
  begin
89
- break target_state if states(service_name)[:load_state] == target_state
91
+ break target_state if status(service_name)[:load_state] == target_state
90
92
  rescue Fleet::NotFound
91
93
  # :no_state is a special case of target state that indicates we
92
94
  # expect the state to not be found at all (useful when waiting for
data/lib/fleet/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Fleet
2
- VERSION = '0.0.1'.freeze unless defined?(Fleet::VERSION)
2
+ VERSION = '0.5.1'.freeze unless defined?(Fleet::VERSION)
3
3
  end
@@ -32,85 +32,117 @@ describe Fleet::Client do
32
32
  { 'node' => { 'value' => '{ "loadState": "loaded" }' } }
33
33
  end
34
34
 
35
- before do
36
- allow(subject).to receive(:create_unit).and_return(nil)
37
- allow(subject).to receive(:create_job).and_return(nil)
38
- allow(subject).to receive(:update_job_target_state).and_return(nil)
39
- allow(subject).to receive(:get_state).and_return(fleet_state)
40
- allow(Fleet::ServiceDefinition).to receive(:new).and_return(sd)
41
- end
35
+ context 'when a service definition is provided' do
36
+ before do
37
+ allow(subject).to receive(:create_unit).and_return(nil)
38
+ allow(subject).to receive(:create_job).and_return(nil)
39
+ allow(subject).to receive(:update_job_target_state).and_return(nil)
40
+ allow(subject).to receive(:get_state).and_return(fleet_state)
41
+ allow(Fleet::ServiceDefinition).to receive(:new).and_return(sd)
42
+ end
42
43
 
43
- it 'invokes #create_unit' do
44
- expect(subject).to receive(:create_unit)
45
- .with(sd.sha1, sd.to_unit)
44
+ it 'invokes #create_unit' do
45
+ expect(subject).to receive(:create_unit)
46
+ .with(sd.sha1, sd.to_unit)
46
47
 
47
- subject.load(name, service_def)
48
- end
48
+ subject.load(name, service_def)
49
+ end
49
50
 
50
- it 'invokes #create_job' do
51
- expect(subject).to receive(:create_job)
52
- .with(sd.name, sd.to_job)
51
+ it 'invokes #create_job' do
52
+ expect(subject).to receive(:create_job)
53
+ .with(sd.name, sd.to_job)
53
54
 
54
- subject.load(name, service_def)
55
- end
55
+ subject.load(name, service_def)
56
+ end
56
57
 
57
- it 'invokes #update_job_target_state' do
58
- expect(subject).to receive(:update_job_target_state)
59
- .with(sd.name, :loaded)
58
+ it 'invokes #update_job_target_state' do
59
+ expect(subject).to receive(:update_job_target_state)
60
+ .with(sd.name, :loaded)
60
61
 
61
- subject.load(name, service_def)
62
- end
62
+ subject.load(name, service_def)
63
+ end
63
64
 
64
- it 'checks the job state' do
65
- expect(subject).to receive(:get_state).with(sd.name)
66
- subject.load(name, service_def)
67
- end
65
+ it 'checks the job state' do
66
+ expect(subject).to receive(:get_state).with(sd.name)
67
+ subject.load(name, service_def)
68
+ end
68
69
 
69
- context 'when #create_unit raises PreconditionFailed' do
70
+ context 'when #create_unit raises PreconditionFailed' do
70
71
 
71
- before do
72
- allow(subject).to receive(:create_unit)
73
- .and_raise(Fleet::PreconditionFailed.new('boom'))
72
+ before do
73
+ allow(subject).to receive(:create_unit)
74
+ .and_raise(Fleet::PreconditionFailed.new('boom'))
75
+ end
76
+
77
+ it 'does not blow up' do
78
+ expect { subject.load(name, service_def) }.to_not raise_error
79
+ end
74
80
  end
75
81
 
76
- it 'does not blow up' do
77
- expect { subject.load(name, service_def) }.to_not raise_error
82
+ context 'when #create_unit raises something other than PreconditionFailed' do
83
+
84
+ before do
85
+ allow(subject).to receive(:create_unit)
86
+ .and_raise(Fleet::BadRequest.new('boom'))
87
+ end
88
+
89
+ it 'propagates the error' do
90
+ expect { subject.load(name, service_def) }.to(raise_error(Fleet::BadRequest))
91
+ end
78
92
  end
79
- end
80
93
 
81
- context 'when #create_unit raises something other than PreconditionFailed' do
94
+ context 'when #create_job raises PreconditionFailed' do
82
95
 
83
- before do
84
- allow(subject).to receive(:create_unit)
85
- .and_raise(Fleet::BadRequest.new('boom'))
96
+ before do
97
+ allow(subject).to receive(:create_job)
98
+ .and_raise(Fleet::PreconditionFailed.new('boom'))
99
+ end
100
+
101
+ it 'does not blow up' do
102
+ expect { subject.load(name, service_def) }.to_not raise_error
103
+ end
86
104
  end
87
105
 
88
- it 'propagates the error' do
89
- expect { subject.load(name, service_def) }.to(raise_error(Fleet::BadRequest))
106
+ context 'when #create_job raises something other than PreconditionFailed' do
107
+
108
+ before do
109
+ allow(subject).to receive(:create_job)
110
+ .and_raise(Fleet::BadRequest.new('boom'))
111
+ end
112
+
113
+ it 'propagates the error' do
114
+ expect { subject.load(name, service_def) }.to(raise_error(Fleet::BadRequest))
115
+ end
90
116
  end
91
117
  end
92
118
 
93
- context 'when #create_job raises PreconditionFailed' do
119
+ context 'when no service definition is provided' do
94
120
 
95
121
  before do
96
- allow(subject).to receive(:create_job)
97
- .and_raise(Fleet::PreconditionFailed.new('boom'))
122
+ allow(subject).to receive(:update_job_target_state).and_return(nil)
123
+ allow(subject).to receive(:get_state).and_return(fleet_state)
98
124
  end
99
125
 
100
- it 'does not blow up' do
101
- expect { subject.load(name, service_def) }.to_not raise_error
126
+ it 'does NOT invoke #create_unit' do
127
+ expect(subject).to_not receive(:create_unit)
128
+ subject.load(name)
102
129
  end
103
- end
104
130
 
105
- context 'when #create_job raises something other than PreconditionFailed' do
131
+ it 'does NOT invoke #create_job' do
132
+ expect(subject).to_not receive(:create_job)
133
+ subject.load(name)
134
+ end
106
135
 
107
- before do
108
- allow(subject).to receive(:create_job)
109
- .and_raise(Fleet::BadRequest.new('boom'))
136
+ it 'invokes #update_job_target_state' do
137
+ expect(subject).to receive(:update_job_target_state)
138
+ .with(sd.name, :loaded)
139
+
140
+ subject.load(name)
110
141
  end
111
142
 
112
- it 'propagates the error' do
113
- expect { subject.load(name, service_def) }.to(raise_error(Fleet::BadRequest))
143
+ it 'checks the job state' do
144
+ expect(subject).to receive(:get_state).with(sd.name)
145
+ subject.load(name)
114
146
  end
115
147
  end
116
148
  end
@@ -223,7 +255,7 @@ describe Fleet::Client do
223
255
  end
224
256
  end
225
257
 
226
- describe '#states' do
258
+ describe '#status' do
227
259
 
228
260
  let(:service_name) { 'foo.service' }
229
261
 
@@ -237,11 +269,11 @@ describe Fleet::Client do
237
269
 
238
270
  it 'retrieves service state from the fleet client' do
239
271
  expect(subject).to receive(:get_state).with(service_name)
240
- subject.states(service_name)
272
+ subject.status(service_name)
241
273
  end
242
274
 
243
275
  it 'returns the state hash w/ normalized keys' do
244
- expect(subject.states(service_name)).to eq(load: 'loaded', run: 'running')
276
+ expect(subject.status(service_name)).to eq(load: 'loaded', run: 'running')
245
277
  end
246
278
  end
247
279
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fleet-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - CenturyLink
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-15 00:00:00.000000000 Z
11
+ date: 2014-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -70,30 +70,30 @@ dependencies:
70
70
  name: simplecov
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 0.9.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: 0.9.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: simplecov-rcov
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ">="
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0'
89
+ version: 0.2.3
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0'
96
+ version: 0.2.3
97
97
  description: A simple REST client for the CoreOS Fleet API
98
98
  email:
99
99
  - clt-labs-futuretech@centurylink.com
@@ -102,6 +102,7 @@ extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
104
  - ".gitignore"
105
+ - ".travis.yml"
105
106
  - Gemfile
106
107
  - Gemfile.lock
107
108
  - LICENSE
@@ -144,7 +145,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
145
  requirements:
145
146
  - - ">="
146
147
  - !ruby/object:Gem::Version
147
- version: '0'
148
+ version: 1.9.3
148
149
  required_rubygems_version: !ruby/object:Gem::Requirement
149
150
  requirements:
150
151
  - - ">="
@@ -152,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
153
  version: '0'
153
154
  requirements: []
154
155
  rubyforge_project:
155
- rubygems_version: 2.3.0
156
+ rubygems_version: 2.2.0
156
157
  signing_key:
157
158
  specification_version: 4
158
159
  summary: A simple REST client for the CoreOS Fleet API