superhosting 0.0.1
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 +15 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +117 -0
- data/LICENSE.txt +22 -0
- data/README.md +23 -0
- data/Rakefile +6 -0
- data/Vagrantfile +10 -0
- data/bin/sx +10 -0
- data/bootstrap.sh +31 -0
- data/lib/superhosting.rb +40 -0
- data/lib/superhosting/base.rb +37 -0
- data/lib/superhosting/cli/base.rb +227 -0
- data/lib/superhosting/cli/cmd/admin_add.rb +11 -0
- data/lib/superhosting/cli/cmd/admin_container_add.rb +16 -0
- data/lib/superhosting/cli/cmd/admin_container_delete.rb +16 -0
- data/lib/superhosting/cli/cmd/admin_container_list.rb +12 -0
- data/lib/superhosting/cli/cmd/admin_delete.rb +11 -0
- data/lib/superhosting/cli/cmd/admin_passwd.rb +16 -0
- data/lib/superhosting/cli/cmd/container_add.rb +21 -0
- data/lib/superhosting/cli/cmd/container_admin_add.rb +16 -0
- data/lib/superhosting/cli/cmd/container_admin_delete.rb +16 -0
- data/lib/superhosting/cli/cmd/container_admin_list.rb +12 -0
- data/lib/superhosting/cli/cmd/container_change.rb +21 -0
- data/lib/superhosting/cli/cmd/container_delete.rb +11 -0
- data/lib/superhosting/cli/cmd/container_list.rb +9 -0
- data/lib/superhosting/cli/cmd/container_reconfig.rb +11 -0
- data/lib/superhosting/cli/cmd/container_restore.rb +24 -0
- data/lib/superhosting/cli/cmd/container_save.rb +14 -0
- data/lib/superhosting/cli/cmd/container_update.rb +11 -0
- data/lib/superhosting/cli/cmd/mysql_db_add.rb +9 -0
- data/lib/superhosting/cli/cmd/mysql_db_delete.rb +9 -0
- data/lib/superhosting/cli/cmd/mysql_db_dump.rb +9 -0
- data/lib/superhosting/cli/cmd/mysql_db_sql.rb +9 -0
- data/lib/superhosting/cli/cmd/mysql_grant.rb +9 -0
- data/lib/superhosting/cli/cmd/mysql_user_add.rb +12 -0
- data/lib/superhosting/cli/cmd/mysql_user_delete.rb +9 -0
- data/lib/superhosting/cli/cmd/site_add.rb +16 -0
- data/lib/superhosting/cli/cmd/site_alias_add.rb +16 -0
- data/lib/superhosting/cli/cmd/site_alias_delete.rb +16 -0
- data/lib/superhosting/cli/cmd/site_delete.rb +11 -0
- data/lib/superhosting/cli/cmd/site_rename.rb +16 -0
- data/lib/superhosting/cli/cmd/user_add.rb +24 -0
- data/lib/superhosting/cli/cmd/user_change.rb +24 -0
- data/lib/superhosting/cli/cmd/user_delete.rb +16 -0
- data/lib/superhosting/cli/cmd/user_list.rb +9 -0
- data/lib/superhosting/cli/cmd/user_passwd.rb +16 -0
- data/lib/superhosting/cli/error/ambiguous_command.rb +11 -0
- data/lib/superhosting/cli/error/base.rb +8 -0
- data/lib/superhosting/cli/error/controller.rb +8 -0
- data/lib/superhosting/controller/admin.rb +21 -0
- data/lib/superhosting/controller/admin/container.rb +24 -0
- data/lib/superhosting/controller/container.rb +174 -0
- data/lib/superhosting/controller/container/admin.rb +24 -0
- data/lib/superhosting/controller/mysql.rb +17 -0
- data/lib/superhosting/controller/mysql/db.rb +23 -0
- data/lib/superhosting/controller/mysql/user.rb +15 -0
- data/lib/superhosting/controller/site.rb +106 -0
- data/lib/superhosting/controller/site/alias.rb +21 -0
- data/lib/superhosting/controller/user.rb +25 -0
- data/lib/superhosting/docker_api.rb +31 -0
- data/lib/superhosting/helpers.rb +30 -0
- data/lib/superhosting/script_executor/base.rb +26 -0
- data/lib/superhosting/script_executor/container.rb +36 -0
- data/lib/superhosting/script_executor/site.rb +13 -0
- data/lib/superhosting/version.rb +3 -0
- data/superhosting.gemspec +32 -0
- metadata +341 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
N2ZhNTc2Yjg3MjdlM2M5ZTgzYzNiYWYwMmMyNDA5MTZjMDQ4NzQzZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZDMwZmM4ZTQ1NzhiMWRmNTM2Y2I3MGQ5NjZjNWJkZjM0Yjk3OTA1NA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MGUxMWE4ODlkMjJkZDFmNjU3YmVmZjJmZWJkMzNhZmU1MTNhYTY3ZDY0ZDdj
|
10
|
+
MjEyNmM1ZTgxOGNmYWZhMzY3YzkxODlkMTkzYjVjMDUzZWExMjUyZTdiYzI5
|
11
|
+
MTdjOTY0NzIwMGY0MzNiZDE2OTY3ZDA5MmM3OTBlMmE5ZjQ2ZjU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MTdmNDg1NDNiY2RjYjYwOTQzNjQ2N2FiNDk5YzE2OTUyN2NmYmE2MGM1NGNm
|
14
|
+
ZWJlNzNlODAwNjM2YTQxN2UxYmUwZWZjYTE3N2M1N2E4OTY5YzA0ZjhhMWYy
|
15
|
+
N2ZlNmM2ODM5ZGNiNzRjMWFhNTliZjZjNGM3YzAzYjc5OTNlNjU=
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 2.2.1
|
4
|
+
deploy:
|
5
|
+
provider: rubygems
|
6
|
+
api_key:
|
7
|
+
secure: zVrSJRx992jsyfOywuEPsi/xJogvspgadByoZX4+2wVrvTtkA/6lNnutm7rKwOeO57GsX4siKsOQ43j1nT0N+gwjb/XKfn0yaev657eAC/1ybvZMu98dZ+J2FjAAouz4qqtfacAczf7mXf0Xi53K+az6GUMeuldxdDDyhm5Xr3ZhPqhueh7eIijNVdSx+vK78qTgRNjZFrXsqvN+SdS8ZT0ZPqvKcI6MarOppdpavCUbYWIyx6bOcKictc3CbS5XdM3n9iPM3ribhj/vqkX+nruRQf9oqq7ZnqU4oan3jdTlo3ZAdaiKWcDhjgzOBJkojUTEEgWGgnBFHZNNaRcdXGo9TADUcvM8fd/59eX71EuB3WL+kHgLKwkWT1/pnTuPk+PVJfR3df46UaEMQkF4b7fxigJ1sXzt+zJ3CJD+X5ejR+c8E4bYCxZXWFxhZhi+UG3sFJQVOIRJE8Hohs2gLdvxBYyjgrCCk+TJaCxgU1gg5CbfuQ05oblpNk12E2GwAa9iPue89X80GVvkO/twTeTN2LAw3lOacuacU+BIyzohly6t7V1YiNQq0p9Sqlvvnnrwkqgp1jAuD56tOeLzjTsEkrHnuGstIJnh+GzbsJLm/BcXCnLcdbdvpKn66Pt9z+RmsRfW01QptWpYx8I2DgJtVjWEYeDKwJCZ8/c0rmc=
|
8
|
+
gem: superhosting
|
9
|
+
on:
|
10
|
+
tags: true
|
11
|
+
repo: flant/superhosting
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
GIT
|
2
|
+
remote: https://github.com/flant/net_status.git
|
3
|
+
revision: 50e9cceac16a288f9ffa396c070b2bbfe5f9d01d
|
4
|
+
specs:
|
5
|
+
net_status (0.0.2)
|
6
|
+
|
7
|
+
GIT
|
8
|
+
remote: https://github.com/flant/path_mapper.git
|
9
|
+
revision: 03d57883e9db7eeb46ef361b3c54002f86b78cd6
|
10
|
+
specs:
|
11
|
+
path_mapper (0.0.2)
|
12
|
+
|
13
|
+
PATH
|
14
|
+
remote: .
|
15
|
+
specs:
|
16
|
+
superhosting (0.0.1)
|
17
|
+
mixlib-cli (>= 1.5.0, < 2.0)
|
18
|
+
mixlib-shellout (>= 2.2.6, < 3.0)
|
19
|
+
net_status (>= 0.0.1, < 1.0)
|
20
|
+
path_mapper (>= 0.0.1, < 1.0)
|
21
|
+
|
22
|
+
GEM
|
23
|
+
remote: https://rubygems.org/
|
24
|
+
specs:
|
25
|
+
addressable (2.4.0)
|
26
|
+
backports (3.6.8)
|
27
|
+
binding_of_caller (0.7.2)
|
28
|
+
debug_inspector (>= 0.0.1)
|
29
|
+
byebug (8.2.2)
|
30
|
+
coderay (1.1.1)
|
31
|
+
debug_inspector (0.0.2)
|
32
|
+
diff-lcs (1.2.5)
|
33
|
+
ethon (0.8.1)
|
34
|
+
ffi (>= 1.3.0)
|
35
|
+
excon (0.47.0)
|
36
|
+
faraday (0.9.2)
|
37
|
+
multipart-post (>= 1.2, < 3)
|
38
|
+
faraday_middleware (0.10.0)
|
39
|
+
faraday (>= 0.7.4, < 0.10)
|
40
|
+
ffi (1.9.10)
|
41
|
+
gh (0.14.0)
|
42
|
+
addressable
|
43
|
+
backports
|
44
|
+
faraday (~> 0.8)
|
45
|
+
multi_json (~> 1.0)
|
46
|
+
net-http-persistent (>= 2.7)
|
47
|
+
net-http-pipeline
|
48
|
+
highline (1.7.8)
|
49
|
+
json (1.8.3)
|
50
|
+
launchy (2.4.3)
|
51
|
+
addressable (~> 2.3)
|
52
|
+
method_source (0.8.2)
|
53
|
+
mixlib-cli (1.5.0)
|
54
|
+
mixlib-shellout (2.2.6)
|
55
|
+
multi_json (1.11.2)
|
56
|
+
multipart-post (2.0.0)
|
57
|
+
net-http-persistent (2.9.4)
|
58
|
+
net-http-pipeline (1.0.1)
|
59
|
+
pry (0.10.3)
|
60
|
+
coderay (~> 1.1.0)
|
61
|
+
method_source (~> 0.8.1)
|
62
|
+
slop (~> 3.4)
|
63
|
+
pry-byebug (3.3.0)
|
64
|
+
byebug (~> 8.0)
|
65
|
+
pry (~> 0.10)
|
66
|
+
pry-stack_explorer (0.4.9.2)
|
67
|
+
binding_of_caller (>= 0.7)
|
68
|
+
pry (>= 0.9.11)
|
69
|
+
pusher-client (0.6.2)
|
70
|
+
json
|
71
|
+
websocket (~> 1.0)
|
72
|
+
rake (10.5.0)
|
73
|
+
rspec (3.4.0)
|
74
|
+
rspec-core (~> 3.4.0)
|
75
|
+
rspec-expectations (~> 3.4.0)
|
76
|
+
rspec-mocks (~> 3.4.0)
|
77
|
+
rspec-core (3.4.3)
|
78
|
+
rspec-support (~> 3.4.0)
|
79
|
+
rspec-expectations (3.4.0)
|
80
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
81
|
+
rspec-support (~> 3.4.0)
|
82
|
+
rspec-mocks (3.4.1)
|
83
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
84
|
+
rspec-support (~> 3.4.0)
|
85
|
+
rspec-support (3.4.1)
|
86
|
+
slop (3.6.0)
|
87
|
+
travis (1.8.2)
|
88
|
+
backports
|
89
|
+
faraday (~> 0.9)
|
90
|
+
faraday_middleware (~> 0.9, >= 0.9.1)
|
91
|
+
gh (~> 0.13)
|
92
|
+
highline (~> 1.6)
|
93
|
+
launchy (~> 2.1)
|
94
|
+
pusher-client (~> 0.4)
|
95
|
+
typhoeus (~> 0.6, >= 0.6.8)
|
96
|
+
typhoeus (0.8.0)
|
97
|
+
ethon (>= 0.8.0)
|
98
|
+
websocket (1.2.2)
|
99
|
+
|
100
|
+
PLATFORMS
|
101
|
+
ruby
|
102
|
+
|
103
|
+
DEPENDENCIES
|
104
|
+
bundler (~> 1.7)
|
105
|
+
excon (>= 0.45.4, < 1.0)
|
106
|
+
net_status!
|
107
|
+
path_mapper!
|
108
|
+
pry (>= 0.10.3, < 1.0)
|
109
|
+
pry-byebug (>= 3.3.0, < 4.0)
|
110
|
+
pry-stack_explorer (>= 0.4.9.2, < 1.0)
|
111
|
+
rake (~> 10.0)
|
112
|
+
rspec (~> 3.4, >= 3.4.0)
|
113
|
+
superhosting!
|
114
|
+
travis (~> 1.8, >= 1.8.2)
|
115
|
+
|
116
|
+
BUNDLED WITH
|
117
|
+
1.11.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Alexey Igrychev
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Superhosting
|
2
|
+
|
3
|
+
TODO
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'superhosting'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install superhosting
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO
|
data/Rakefile
ADDED
data/Vagrantfile
ADDED
data/bin/sx
ADDED
data/bootstrap.sh
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env /bin/bash
|
2
|
+
|
3
|
+
apt-get update
|
4
|
+
apt-get install -y build-essential libpam0g-dev apt-transport-https ca-certificates
|
5
|
+
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
|
6
|
+
echo 'deb https://apt.dockerproject.org/repo ubuntu-trusty main' > /etc/apt/sources.list.d/docker.list
|
7
|
+
apt-get update
|
8
|
+
apt-get install -y docker-engine
|
9
|
+
|
10
|
+
gpasswd -a vagrant docker
|
11
|
+
service docker restart
|
12
|
+
|
13
|
+
cd /tmp
|
14
|
+
git clone https://github.com/flant/pam_docker.git
|
15
|
+
cd pam_docker
|
16
|
+
make
|
17
|
+
make install-ubuntu-14.04
|
18
|
+
|
19
|
+
curl -sSL https://rvm.io/mpapis.asc | gpg --import -
|
20
|
+
curl -sSL https://get.rvm.io | sudo bash -s stable
|
21
|
+
|
22
|
+
echo 'source /etc/profile.d/rvm.sh' >> /etc/bash.bashrc
|
23
|
+
source /etc/profile.d/rvm.sh
|
24
|
+
|
25
|
+
rvm group add rvm vagrant
|
26
|
+
rvm install 2.2.1 --quiet-curl
|
27
|
+
rvm --default use 2.2.1
|
28
|
+
gem install bundler
|
29
|
+
|
30
|
+
cd /vagrant
|
31
|
+
bundle install
|
data/lib/superhosting.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'mixlib/cli'
|
2
|
+
require 'mixlib/shellout'
|
3
|
+
require 'logger'
|
4
|
+
require 'pathname'
|
5
|
+
require 'excon'
|
6
|
+
require 'json'
|
7
|
+
require 'etc'
|
8
|
+
require 'erb'
|
9
|
+
require 'ostruct'
|
10
|
+
require 'pry-byebug'
|
11
|
+
|
12
|
+
require 'path_mapper'
|
13
|
+
require 'net_status'
|
14
|
+
|
15
|
+
require 'superhosting/version'
|
16
|
+
require 'superhosting/helpers'
|
17
|
+
|
18
|
+
require 'superhosting/base'
|
19
|
+
require 'superhosting/controller/admin'
|
20
|
+
require 'superhosting/controller/admin/container'
|
21
|
+
require 'superhosting/controller/container'
|
22
|
+
require 'superhosting/controller/container/admin'
|
23
|
+
require 'superhosting/controller/mysql'
|
24
|
+
require 'superhosting/controller/mysql/db'
|
25
|
+
require 'superhosting/controller/mysql/user'
|
26
|
+
require 'superhosting/controller/site'
|
27
|
+
require 'superhosting/controller/site/alias'
|
28
|
+
require 'superhosting/controller/user'
|
29
|
+
|
30
|
+
require 'superhosting/script_executor/base'
|
31
|
+
require 'superhosting/script_executor/container'
|
32
|
+
require 'superhosting/script_executor/site'
|
33
|
+
|
34
|
+
require 'superhosting/docker_api'
|
35
|
+
|
36
|
+
require 'superhosting/cli/error/base'
|
37
|
+
Dir["#{File.dirname(__FILE__)}/superhosting/cli/error/*.rb"].each{|cmd| require_relative cmd.split('.rb').first}
|
38
|
+
|
39
|
+
require 'superhosting/cli/base'
|
40
|
+
Dir["#{File.dirname(__FILE__)}/superhosting/cli/cmd/*.rb"].each{|cmd| require_relative cmd.split('.rb').first}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Superhosting
|
2
|
+
class Base
|
3
|
+
include Helpers
|
4
|
+
|
5
|
+
def initialize(config_path: '/etc/sx', lib_path: '/var/lib/sx', logger: nil, docker_socket: nil)
|
6
|
+
@config_path = Pathname.new(config_path)
|
7
|
+
@lib_path = Pathname.new(lib_path)
|
8
|
+
@config = PathMapper.new(config_path)
|
9
|
+
@lib = PathMapper.new(lib_path)
|
10
|
+
@logger = logger
|
11
|
+
|
12
|
+
@docker_api = DockerApi.new(socket: docker_socket)
|
13
|
+
end
|
14
|
+
|
15
|
+
def debug(*a, &b)
|
16
|
+
@logger.debug(*a, &b) unless @logger.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def command!(*command_args)
|
20
|
+
cmd = Mixlib::ShellOut.new(*command_args)
|
21
|
+
cmd.run_command
|
22
|
+
if cmd.status.success?
|
23
|
+
debug([cmd.stdout, cmd.stderr].join("\n"))
|
24
|
+
cmd
|
25
|
+
else
|
26
|
+
raise NetStatus::Exception.new(error: :error, message: [cmd.stdout, cmd.stderr].join("\n"))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def command(*command_args)
|
31
|
+
cmd = Mixlib::ShellOut.new(*command_args)
|
32
|
+
cmd.run_command
|
33
|
+
debug([cmd.stdout, cmd.stderr].join("\n"))
|
34
|
+
cmd
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
module Superhosting
|
2
|
+
module Cli
|
3
|
+
module Cmd; end
|
4
|
+
class Base
|
5
|
+
include Mixlib::CLI
|
6
|
+
|
7
|
+
COMMANDS_MODULE = Cmd
|
8
|
+
CONTROLLERS_MODULE = Superhosting::Controller
|
9
|
+
CONTROLLER_BASE_OPTIONS = [:config_path, :lib_path, :docker_socket]
|
10
|
+
|
11
|
+
banner "#{?= * 50}\n#{?- * 19}SUPERHOSTING#{?- * 19}\n#{?= * 50}\n\n"
|
12
|
+
|
13
|
+
option :help,
|
14
|
+
:short => '-h',
|
15
|
+
:long => '--help',
|
16
|
+
:on => :tail
|
17
|
+
|
18
|
+
option :debug,
|
19
|
+
:long => '--debug',
|
20
|
+
:boolean => true,
|
21
|
+
:on => :tail
|
22
|
+
|
23
|
+
option :config_path,
|
24
|
+
:long => '--config-path PATH',
|
25
|
+
:on => :tail
|
26
|
+
|
27
|
+
option :lib_path,
|
28
|
+
:long => '--lib-path PATH',
|
29
|
+
:on => :tail
|
30
|
+
|
31
|
+
option :docker_socket,
|
32
|
+
:long => '--docker-socket PATH',
|
33
|
+
:on => :tail
|
34
|
+
|
35
|
+
def initialize(argv, node)
|
36
|
+
self.class.options.merge!(Base::options)
|
37
|
+
super()
|
38
|
+
|
39
|
+
@pos_args = parse_options(argv)
|
40
|
+
@node = node
|
41
|
+
|
42
|
+
@logger = Logger.new(STDOUT)
|
43
|
+
@logger.level = config[:debug] ? Logger::DEBUG : Logger::INFO
|
44
|
+
@logger.formatter = proc {|severity, datetime, progname, msg| sprintf("%s\n", msg.to_s.strip) }
|
45
|
+
|
46
|
+
self.help if config[:help] or self.class == Base
|
47
|
+
end
|
48
|
+
|
49
|
+
def help
|
50
|
+
def get_childs_banners(node)
|
51
|
+
if node.is_a? Hash
|
52
|
+
node.map do |k,v|
|
53
|
+
if v.is_a? Hash
|
54
|
+
get_childs_banners(node[k])
|
55
|
+
else
|
56
|
+
v.banner
|
57
|
+
end
|
58
|
+
end.join("\n")
|
59
|
+
else
|
60
|
+
node.banner
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
@logger.info("#{opt_parser.to_s}\n#{get_childs_banners(@node) if self.class == Base}")
|
65
|
+
|
66
|
+
exit 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def run
|
70
|
+
begin
|
71
|
+
net_status = action
|
72
|
+
net_status ||= {}
|
73
|
+
|
74
|
+
raise Error::Controller, net_status unless net_status[:error].nil?
|
75
|
+
@logger.info(net_status[:data]) unless net_status[:data].nil?
|
76
|
+
@logger.debug('Done!')
|
77
|
+
rescue NetStatus::Exception => e
|
78
|
+
raise Error::Controller, e.net_status
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def action
|
83
|
+
method = get_controller
|
84
|
+
opts = {}
|
85
|
+
method.parameters.each do |req, name|
|
86
|
+
if req.to_s.start_with? 'key'
|
87
|
+
opt = config[name]
|
88
|
+
self.help unless opt = @pos_args.shift if name == :name
|
89
|
+
opts.merge!(name => opt)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
self.help unless @pos_args.empty? # only one position argument
|
93
|
+
|
94
|
+
method.parameters.empty? ? method.call : method.call(**opts)
|
95
|
+
end
|
96
|
+
|
97
|
+
def get_controller
|
98
|
+
def get_subcontroller_option
|
99
|
+
key = :"#{self.class.get_split_class_name.first}_name"
|
100
|
+
config[key] unless config[key].nil?
|
101
|
+
end
|
102
|
+
|
103
|
+
node = CONTROLLERS_MODULE
|
104
|
+
names = self.class.get_split_class_name
|
105
|
+
|
106
|
+
names.each do |n|
|
107
|
+
c_name = n.capitalize.to_sym
|
108
|
+
m_name = n.to_sym
|
109
|
+
|
110
|
+
if node.respond_to? :constants and node.constants.include? c_name
|
111
|
+
node = node.const_get(c_name)
|
112
|
+
elsif node.respond_to? :instance_methods and node.instance_methods(false).include? m_name
|
113
|
+
params = node.instance_method(:initialize).parameters
|
114
|
+
|
115
|
+
opts = {}
|
116
|
+
params.each do |req, name|
|
117
|
+
if req.to_s.start_with? 'key'
|
118
|
+
if name == :name
|
119
|
+
opt = get_subcontroller_option
|
120
|
+
elsif config.key? name
|
121
|
+
opt = config[name]
|
122
|
+
end
|
123
|
+
opts.merge!(name => opt) unless opt.nil?
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
CONTROLLER_BASE_OPTIONS.each {|opt| opts.merge!(opt => config[opt]) unless config[opt].nil? }
|
128
|
+
opts.merge!(logger: @logger)
|
129
|
+
return node.new(**opts).method(m_name)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
raise Error::Base.new('Method doesn\'t found')
|
133
|
+
end
|
134
|
+
|
135
|
+
class << self
|
136
|
+
def start(args)
|
137
|
+
def clear_args(args, cmd)
|
138
|
+
split_toggle_case_name(cmd).length.times{ args.shift }
|
139
|
+
args
|
140
|
+
end
|
141
|
+
|
142
|
+
prepend
|
143
|
+
cmd, node = get_cmd_and_node(args)
|
144
|
+
args = clear_args(args, cmd)
|
145
|
+
cmd.new(args, node).run
|
146
|
+
end
|
147
|
+
|
148
|
+
def prepend
|
149
|
+
set_commands_hierarchy
|
150
|
+
set_banners
|
151
|
+
end
|
152
|
+
|
153
|
+
def set_banners(node=@@commands_hierarchy, path=[])
|
154
|
+
node.each do |k,v|
|
155
|
+
path_ = path.dup
|
156
|
+
path_ << k
|
157
|
+
if v.is_a? Hash
|
158
|
+
set_banners(v, path_)
|
159
|
+
else
|
160
|
+
v.banner("sx #{path_.join(' ')}#{" <#{path.last}>" if v.has_required_param?}#{' (options)' unless v.options.empty?}")
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def has_required_param?
|
166
|
+
false
|
167
|
+
end
|
168
|
+
|
169
|
+
def set_commands_hierarchy
|
170
|
+
def get_commands
|
171
|
+
COMMANDS_MODULE.constants.select {|c| Class === COMMANDS_MODULE.const_get(c) }.sort
|
172
|
+
end
|
173
|
+
|
174
|
+
@@commands_hierarchy = get_commands.inject({}) do |h,k|
|
175
|
+
node = h
|
176
|
+
parts = split_toggle_case_name(k)
|
177
|
+
parts.each do |cmd|
|
178
|
+
node = (node[cmd] ||= (cmd == parts.last) ? COMMANDS_MODULE.const_get(k) : {})
|
179
|
+
end
|
180
|
+
h
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def get_split_class_name
|
185
|
+
self.split_toggle_case_name(self.name.split('::').last)
|
186
|
+
end
|
187
|
+
|
188
|
+
def split_toggle_case_name(klass)
|
189
|
+
klass.to_s.gsub(/([[:lower:]])([[:upper:]])/, '\1 \2').split(' ').map(&:downcase)
|
190
|
+
end
|
191
|
+
|
192
|
+
def get_cmd_and_node(args)
|
193
|
+
def positional_arguments(args)
|
194
|
+
args.select { |arg| arg =~ /^([[:alnum:]\_\-]+)$/ }
|
195
|
+
end
|
196
|
+
|
197
|
+
args = positional_arguments(args)
|
198
|
+
node = @@commands_hierarchy
|
199
|
+
path = []
|
200
|
+
key = ''
|
201
|
+
cmd = nil
|
202
|
+
while arg = args.shift and cmd.nil?
|
203
|
+
res = node.keys.select { |k| k.start_with? arg }
|
204
|
+
|
205
|
+
case res.count
|
206
|
+
when 1
|
207
|
+
key = res.first
|
208
|
+
cmd = node[key] if node[key].is_a? Class
|
209
|
+
when 0
|
210
|
+
break
|
211
|
+
else
|
212
|
+
raise Error::AmbiguousCommand.new(path: path, commands: res)
|
213
|
+
end
|
214
|
+
|
215
|
+
path << key
|
216
|
+
node = node[key]
|
217
|
+
end
|
218
|
+
|
219
|
+
cmd ||= self
|
220
|
+
node = { key => node }
|
221
|
+
|
222
|
+
[cmd, node]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|