superhosting 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|