hyperb 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +12 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +41 -0
- data/Dockerfile +7 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +21 -0
- data/Makefile +16 -0
- data/README.md +188 -0
- data/Rakefile +24 -0
- data/circle.yml +13 -0
- data/examples/README.md +367 -0
- data/examples/auth-gcr-registry.md +19 -0
- data/examples/compose.md +75 -0
- data/examples/handling-errors.md +54 -0
- data/examples/streaming-logs.md +28 -0
- data/examples/streaming-stats.md +25 -0
- data/hyperb.gemspec +30 -0
- data/lib/hyperb.rb +4 -0
- data/lib/hyperb/api.rb +22 -0
- data/lib/hyperb/auth_object.rb +42 -0
- data/lib/hyperb/client.rb +32 -0
- data/lib/hyperb/compose/compose.rb +116 -0
- data/lib/hyperb/containers/container.rb +27 -0
- data/lib/hyperb/containers/containers.rb +251 -0
- data/lib/hyperb/error.rb +44 -0
- data/lib/hyperb/hyper_version.rb +12 -0
- data/lib/hyperb/images/image.rb +13 -0
- data/lib/hyperb/images/images.rb +108 -0
- data/lib/hyperb/network/fips.rb +102 -0
- data/lib/hyperb/request.rb +129 -0
- data/lib/hyperb/services/services.rb +59 -0
- data/lib/hyperb/snapshots/snapshot.rb +12 -0
- data/lib/hyperb/snapshots/snapshots.rb +39 -0
- data/lib/hyperb/utils.rb +39 -0
- data/lib/hyperb/version.rb +3 -0
- data/lib/hyperb/volumes/volume.rb +16 -0
- data/lib/hyperb/volumes/volumes.rb +67 -0
- data/spec/auth_object_spec.rb +45 -0
- data/spec/client_spec.rb +27 -0
- data/spec/compose_spec.rb +145 -0
- data/spec/container_spec.rb +25 -0
- data/spec/containers_spec.rb +442 -0
- data/spec/create_snapshot.rb +30 -0
- data/spec/error_spec.rb +18 -0
- data/spec/fixtures/auth_obj.json +12 -0
- data/spec/fixtures/compose_rm.json +1 -0
- data/spec/fixtures/compose_up.json +1 -0
- data/spec/fixtures/container_stats.json +78 -0
- data/spec/fixtures/containers.json +160 -0
- data/spec/fixtures/create_container.json +4 -0
- data/spec/fixtures/create_image.json +1 -0
- data/spec/fixtures/create_service.json +35 -0
- data/spec/fixtures/create_snapshot.json +8 -0
- data/spec/fixtures/fip_allocate.json +7 -0
- data/spec/fixtures/fips_ls.json +14 -0
- data/spec/fixtures/images.json +32 -0
- data/spec/fixtures/inspect_container.json +159 -0
- data/spec/fixtures/inspect_image.json +89 -0
- data/spec/fixtures/inspect_volume.json +11 -0
- data/spec/fixtures/remove_container.json +1 -0
- data/spec/fixtures/remove_image.json +5 -0
- data/spec/fixtures/volumes.json +13 -0
- data/spec/helper.rb +36 -0
- data/spec/image_spec.rb +17 -0
- data/spec/images_spec.rb +133 -0
- data/spec/network_spec.rb +106 -0
- data/spec/request_spec.rb +41 -0
- data/spec/services_spec.rb +193 -0
- data/spec/version_spec.rb +7 -0
- data/spec/volumes_spec.rb +88 -0
- metadata +74 -3
@@ -0,0 +1,19 @@
|
|
1
|
+
## Authenticating in GCR
|
2
|
+
|
3
|
+
Assuming you already setup google cloud and you have in hands a [service account](https://cloud.google.com/container-registry/docs/advanced-authentication)
|
4
|
+
|
5
|
+
Example:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
|
9
|
+
x_registry_auth = {
|
10
|
+
username: '_json_key',
|
11
|
+
password: File.new('./path/to/service-account.json'),
|
12
|
+
email: 'email@email.com',
|
13
|
+
serveraddress: 'https://gcr.io'
|
14
|
+
}
|
15
|
+
|
16
|
+
image = client.create_image(from_image: 'gcr.io/private/repo/image', x_registry_auth)
|
17
|
+
puts image
|
18
|
+
|
19
|
+
```
|
data/examples/compose.md
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
## Usage examples of compose
|
2
|
+
|
3
|
+
Assuming you already configured your client.
|
4
|
+
|
5
|
+
All compose methods returns a streamable [HTTP::Response::Body]() object
|
6
|
+
|
7
|
+
**Create a Hash representing a [compose file](https://docs.hyper.sh/Reference/compose_file_ref.html) services block**
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
services = {
|
11
|
+
'db': {
|
12
|
+
'environment': [
|
13
|
+
"MYSQL_ROOT_PASSWORD=my-secret-pw"
|
14
|
+
],
|
15
|
+
'external_links': nil,
|
16
|
+
'image': 'mysql:latest'
|
17
|
+
},
|
18
|
+
'web': {
|
19
|
+
'depends_on': [
|
20
|
+
'db'
|
21
|
+
],
|
22
|
+
'external_links': nil,
|
23
|
+
'image': 'wordpress:latest',
|
24
|
+
'links': ['db:mysql']
|
25
|
+
}
|
26
|
+
}
|
27
|
+
```
|
28
|
+
|
29
|
+
after setting up a service hash, you may use up, or create.
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
up = client.compose_up project: 'wp', serviceconfigs: services
|
33
|
+
|
34
|
+
while body = up.readpartial(1024)
|
35
|
+
puts body
|
36
|
+
end
|
37
|
+
|
38
|
+
create = client.compose_create project: 'wp2', serviceconfigs: services
|
39
|
+
create = client.compose_create project: 'wp2', serviceconfigs: services, norecreate: true
|
40
|
+
create = client.compose_create project: 'wp2', serviceconfigs: services, forcerecreate: true
|
41
|
+
|
42
|
+
while body = create.readpartial(1024)
|
43
|
+
puts body
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
**Stoping and removing a compose project (down)**
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
client.compose_down project: 'wp'
|
51
|
+
```
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
client.compose_down project: 'wp', rmi: true
|
55
|
+
```
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
client.compose_down project: 'wp', rmorphans: true
|
59
|
+
```
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
client.compose_down project: 'wp', vol: true
|
63
|
+
```
|
64
|
+
|
65
|
+
**Deleting a compose project**
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
client.compose_rm project: 'wp'
|
69
|
+
```
|
70
|
+
|
71
|
+
**remove all attached volumes**
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
client.compose_rm project: 'wp', rmvol: true
|
75
|
+
```
|
@@ -0,0 +1,54 @@
|
|
1
|
+
## Handling errors
|
2
|
+
|
3
|
+
Hyperb has set of exceptions representing Hyper.sh errors.
|
4
|
+
|
5
|
+
#### Hyperb::Errors::Unauthorized
|
6
|
+
|
7
|
+
raised when credentials are invalid
|
8
|
+
|
9
|
+
#### Hyperb::Errors::NotFound
|
10
|
+
|
11
|
+
raised when resource can't be found
|
12
|
+
|
13
|
+
#### Hyperb::Errors::InternalServerError
|
14
|
+
|
15
|
+
raised when hyper.sh server returns 500
|
16
|
+
|
17
|
+
#### Hyperb::Errors::Conflict
|
18
|
+
|
19
|
+
usually when a container or image can't be deleted or stopped for some reason.
|
20
|
+
|
21
|
+
#### Hyperb::Errors::NotModified
|
22
|
+
|
23
|
+
usually when a container can't be stopped because it was already stopped.
|
24
|
+
|
25
|
+
Examples:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
|
29
|
+
begin
|
30
|
+
stats = client.container_stats id: 'nginxy', stream: true
|
31
|
+
|
32
|
+
while body = stats.readpartial(1024)
|
33
|
+
puts body
|
34
|
+
end
|
35
|
+
|
36
|
+
rescue Exception => e
|
37
|
+
puts 'got something'
|
38
|
+
puts e.message
|
39
|
+
end
|
40
|
+
```
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
|
44
|
+
begin
|
45
|
+
stats = client.container_stats id: 'nginxy', stream: true
|
46
|
+
|
47
|
+
while body = stats.readpartial(1024)
|
48
|
+
puts body
|
49
|
+
end
|
50
|
+
|
51
|
+
rescue Hyperb::Errors::NotFound => e
|
52
|
+
puts 'container not found'
|
53
|
+
end
|
54
|
+
```
|
@@ -0,0 +1,28 @@
|
|
1
|
+
## Streaming container_logs
|
2
|
+
|
3
|
+
Assuming you already configured your client, and you have a running container.
|
4
|
+
|
5
|
+
Hyperb uses [httprb](https://github.com/httprb/http) as the underlying http client, it supports streaming by default,
|
6
|
+
by calling the `readpartial`
|
7
|
+
|
8
|
+
For continuous streaming of the logs, use `follow: true`
|
9
|
+
|
10
|
+
Example:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
|
14
|
+
logs = client.container_logs id: 'nginx', stdout: true, stderr: true, follow: true
|
15
|
+
|
16
|
+
while body = logs.readpartial(1024)
|
17
|
+
puts body
|
18
|
+
end
|
19
|
+
|
20
|
+
```
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
|
24
|
+
logs = client.container_logs id: 'nginx', stdout: true, stderr: true, tail: 30
|
25
|
+
|
26
|
+
puts logs
|
27
|
+
|
28
|
+
```
|
@@ -0,0 +1,25 @@
|
|
1
|
+
## Streaming container_stats
|
2
|
+
|
3
|
+
Assuming you already configured your client, and you have a running container.
|
4
|
+
|
5
|
+
For continuous streaming of the stats, use `stream: true`
|
6
|
+
|
7
|
+
Examples:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
# stream by default
|
11
|
+
stats = client.container_stats id: 'nginx'
|
12
|
+
|
13
|
+
while body = stats.readpartial(1024)
|
14
|
+
puts body
|
15
|
+
end
|
16
|
+
|
17
|
+
```
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
|
21
|
+
stats = client.container_stats id: 'nginx', stream: false
|
22
|
+
|
23
|
+
puts stats
|
24
|
+
|
25
|
+
```
|
data/hyperb.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hyperb/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'hyperb'
|
8
|
+
spec.version = Hyperb::VERSION
|
9
|
+
spec.authors = ['drish']
|
10
|
+
spec.email = ['carlosderich@gmail.com']
|
11
|
+
|
12
|
+
spec.description = %q{The Hyper.sh Ruby Gem}
|
13
|
+
spec.homepage = 'https://github.com/drish/hyperb'
|
14
|
+
spec.summary = spec.description
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.require_paths = ['lib']
|
18
|
+
spec.files = `git ls-files`.split("\n")
|
19
|
+
|
20
|
+
spec.add_dependency 'http', '~> 2.0'
|
21
|
+
|
22
|
+
spec.add_development_dependency 'bundler', '~> 1.8'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'webmock', '~> 3.0', '>= 3.0.1'
|
25
|
+
spec.add_development_dependency 'simplecov', '~> 0.9'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0.10.4'
|
28
|
+
|
29
|
+
spec.required_ruby_version = '>= 2.2'
|
30
|
+
end
|
data/lib/hyperb.rb
ADDED
data/lib/hyperb/api.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'hyperb/images/images'
|
2
|
+
require 'hyperb/containers/containers'
|
3
|
+
require 'hyperb/snapshots/snapshots'
|
4
|
+
require 'hyperb/services/services'
|
5
|
+
require 'hyperb/volumes/volumes'
|
6
|
+
require 'hyperb/network/fips'
|
7
|
+
require 'hyperb/compose/compose'
|
8
|
+
require 'hyperb/hyper_version'
|
9
|
+
|
10
|
+
module Hyperb
|
11
|
+
# wrapper for apis
|
12
|
+
module API
|
13
|
+
include Hyperb::Images
|
14
|
+
include Hyperb::Containers
|
15
|
+
include Hyperb::Volumes
|
16
|
+
include Hyperb::HyperVersion
|
17
|
+
include Hyperb::Network
|
18
|
+
include Hyperb::Snapshots
|
19
|
+
include Hyperb::Services
|
20
|
+
include Hyperb::Compose
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'base64'
|
2
|
+
|
3
|
+
module Hyperb
|
4
|
+
# helper for managing auth objects
|
5
|
+
# used to authenticate into third party docker registries
|
6
|
+
class AuthObject
|
7
|
+
attr_accessor :username, :password, :email, :serveraddress
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@username = options[:username] || ''
|
11
|
+
@email = options[:email] || ''
|
12
|
+
@serveraddress = options[:serveraddress] || ''
|
13
|
+
@password = options[:password].is_a?(File) ? options[:password].read : options[:password]
|
14
|
+
end
|
15
|
+
|
16
|
+
# preserve this order
|
17
|
+
def attrs
|
18
|
+
{
|
19
|
+
username: username,
|
20
|
+
password: password,
|
21
|
+
email: email,
|
22
|
+
serveraddress: serveraddress
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?
|
27
|
+
attrs.values.none? { |atr| blank?(atr) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def blank?(val)
|
31
|
+
val.respond_to?(:empty?) ? val.empty? : !val
|
32
|
+
end
|
33
|
+
|
34
|
+
def encode
|
35
|
+
Base64.urlsafe_encode64(attrs.to_json)
|
36
|
+
end
|
37
|
+
|
38
|
+
def build
|
39
|
+
{ x_registry_auth: encode }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'hyperb/api'
|
2
|
+
|
3
|
+
module Hyperb
|
4
|
+
# client class
|
5
|
+
class Client
|
6
|
+
include Hyperb::API
|
7
|
+
|
8
|
+
attr_accessor :secret_key, :access_key
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
options.each do |key, value|
|
12
|
+
instance_variable_set("@#{key}", value)
|
13
|
+
end
|
14
|
+
yield(self) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def credentials
|
18
|
+
{
|
19
|
+
secret_key: secret_key,
|
20
|
+
access_key: access_key
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def credentials?
|
25
|
+
credentials.values.none? { |cred| blank?(cred) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def blank?(val)
|
29
|
+
val.respond_to?(:empty?) ? val.empty? : !val
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'hyperb/request'
|
2
|
+
require 'hyperb/utils'
|
3
|
+
require 'hyperb/auth_object'
|
4
|
+
require 'json'
|
5
|
+
require 'uri'
|
6
|
+
require 'base64'
|
7
|
+
|
8
|
+
module Hyperb
|
9
|
+
# compose api wrapper
|
10
|
+
module Compose
|
11
|
+
include Hyperb::Utils
|
12
|
+
|
13
|
+
# stop and remove a compose project
|
14
|
+
#
|
15
|
+
# @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_down.html
|
16
|
+
#
|
17
|
+
# @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
|
18
|
+
# @raise [Hyperb::Error::NotFound] raised ips are not found.
|
19
|
+
#
|
20
|
+
# @returns [HTTP::Response::Body] a streamable response object
|
21
|
+
#
|
22
|
+
# @param params [Hash] A customizable set of params.
|
23
|
+
# @option params [String] :project project name
|
24
|
+
# @option params [Boolean] :rmorphans rm containers for services not defined in the compose file
|
25
|
+
# @option params [String] :rmi remove images, all/local
|
26
|
+
# @option params [Boolean] :vol remove data volumes
|
27
|
+
def compose_down(params = {})
|
28
|
+
raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
|
29
|
+
path = '/compose/down'
|
30
|
+
query = {}
|
31
|
+
query[:project] = params[:project] if params.key?(:project)
|
32
|
+
query[:vol] = params[:vol] if params.key?(:vol)
|
33
|
+
query[:rmi] = params[:rmi] if params.key?(:rmi)
|
34
|
+
query[:rmorphans] = params[:rmorphans] if params.key?(:rmorphans)
|
35
|
+
Hyperb::Request.new(self, path, query, 'post').perform
|
36
|
+
end
|
37
|
+
|
38
|
+
# remove a compose project
|
39
|
+
#
|
40
|
+
# @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_rm.html
|
41
|
+
#
|
42
|
+
# @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
|
43
|
+
# @raise [Hyperb::Error::NotFound] raised ips are not found.
|
44
|
+
#
|
45
|
+
# @returns [HTTP::Response::Body] a streamable response object
|
46
|
+
#
|
47
|
+
# @param params [Hash] A customizable set of params.
|
48
|
+
# @option params [String] :project project name
|
49
|
+
# @option params [String] :rmvol project name
|
50
|
+
def compose_rm(params = {})
|
51
|
+
raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
|
52
|
+
path = '/compose/rm'
|
53
|
+
query = {}
|
54
|
+
query[:project] = params[:project] if params.key?(:project)
|
55
|
+
query[:rmvol] = params[:rmvol] if params.key?(:rmvol)
|
56
|
+
Hyperb::Request.new(self, path, query, 'post').perform
|
57
|
+
end
|
58
|
+
|
59
|
+
# create and run a compose project
|
60
|
+
#
|
61
|
+
# @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/Compose/compose_up.html
|
62
|
+
#
|
63
|
+
# @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
|
64
|
+
# @raise [Hyperb::Error::NotFound] raised ips are not found.
|
65
|
+
#
|
66
|
+
# @returns [HTTP::Response::Body] a streamable response object
|
67
|
+
#
|
68
|
+
# @param params [Hash] A customizable set of params.
|
69
|
+
# @option params [String] :project project name
|
70
|
+
# @option params [Hash] :serviceconfigs a hash representing a docker compose file services block
|
71
|
+
# @option params [Hash] :networkconfigs
|
72
|
+
# @option params [Hash] :volumeconfigs
|
73
|
+
def compose_up(params = {})
|
74
|
+
raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
|
75
|
+
path = '/compose/up'
|
76
|
+
query = {}
|
77
|
+
body = {}
|
78
|
+
query[:project] = params[:project] if params.key?(:project)
|
79
|
+
|
80
|
+
body[:serviceconfigs] = { 'M': {} } # inherited from libcompose
|
81
|
+
body[:serviceconfigs][:M] = params[:serviceconfigs] if params.key?(:serviceconfigs)
|
82
|
+
params.delete(:serviceconfigs)
|
83
|
+
body.merge!(params)
|
84
|
+
Hyperb::Request.new(self, path, query, 'post', body).perform
|
85
|
+
end
|
86
|
+
|
87
|
+
# create a compose project
|
88
|
+
#
|
89
|
+
# @see https://docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/
|
90
|
+
# Compose/compose_create.html
|
91
|
+
#
|
92
|
+
# @raise [Hyperb::Error::Unauthorized] raised when credentials are not valid.
|
93
|
+
# @raise [Hyperb::Error::NotFound] raised ips are not found.
|
94
|
+
#
|
95
|
+
# @returns [HTTP::Response::Body] a streamable response object
|
96
|
+
#
|
97
|
+
# @param params [Hash] A customizable set of params.
|
98
|
+
# @option params [String] :project project name
|
99
|
+
# @option params [Hash] :serviceconfigs a hash representing a docker compose file services block
|
100
|
+
# @option params [Hash] :networkconfigs
|
101
|
+
# @option params [Hash] :volumeconfigs
|
102
|
+
def compose_create(params = {})
|
103
|
+
raise ArgumentError, 'Invalid arguments.' unless check_arguments(params, 'project')
|
104
|
+
path = '/compose/create'
|
105
|
+
query = {}
|
106
|
+
body = {}
|
107
|
+
query[:project] = params[:project] if params.key?(:project)
|
108
|
+
|
109
|
+
body[:serviceconfigs] = { 'M': {} } # inherited from libcompose
|
110
|
+
body[:serviceconfigs][:M] = params[:serviceconfigs]
|
111
|
+
params.delete(:serviceconfigs)
|
112
|
+
body.merge!(params)
|
113
|
+
Hyperb::Request.new(self, path, query, 'post', body).perform
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|