hyperb 0.2.1 → 0.2.2
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 +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
|