kontena-plugin-shell 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +2 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +191 -0
- data/README.md +105 -0
- data/bin/kosh +37 -0
- data/kontena-plugin-shell.gemspec +26 -0
- data/kosh.gif +0 -0
- data/lib/kontena/plugin/shell.rb +16 -0
- data/lib/kontena/plugin/shell/callbacks/stack_file.rb +31 -0
- data/lib/kontena/plugin/shell/command.rb +85 -0
- data/lib/kontena/plugin/shell/commands/batch.rb +29 -0
- data/lib/kontena/plugin/shell/commands/batch_do.rb +30 -0
- data/lib/kontena/plugin/shell/commands/context_top.rb +22 -0
- data/lib/kontena/plugin/shell/commands/context_up.rb +15 -0
- data/lib/kontena/plugin/shell/commands/debug.rb +29 -0
- data/lib/kontena/plugin/shell/commands/exit.rb +20 -0
- data/lib/kontena/plugin/shell/commands/help.rb +43 -0
- data/lib/kontena/plugin/shell/commands/kontena.rb +57 -0
- data/lib/kontena/plugin/shell/completer.rb +216 -0
- data/lib/kontena/plugin/shell/context.rb +59 -0
- data/lib/kontena/plugin/shell/session.rb +115 -0
- data/lib/kontena/plugin/shell/shell_command.rb +10 -0
- data/lib/kontena/plugin/shell/version.rb +7 -0
- data/lib/kontena_cli_plugin.rb +11 -0
- metadata +127 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
module Kontena::Plugin
|
2
|
+
module Shell
|
3
|
+
class Context
|
4
|
+
|
5
|
+
attr_reader :context
|
6
|
+
|
7
|
+
def initialize(context)
|
8
|
+
@context = normalize(context)
|
9
|
+
end
|
10
|
+
|
11
|
+
def up
|
12
|
+
context.pop
|
13
|
+
end
|
14
|
+
|
15
|
+
def top
|
16
|
+
context.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
def concat(tokens)
|
20
|
+
arg_index = tokens.index { |a| a == '--' || a.start_with?('-') } || tokens.size
|
21
|
+
context.concat(tokens[0..arg_index-1])
|
22
|
+
end
|
23
|
+
|
24
|
+
def <<(token)
|
25
|
+
context << token
|
26
|
+
end
|
27
|
+
|
28
|
+
def empty?
|
29
|
+
context.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def first
|
33
|
+
context.first
|
34
|
+
end
|
35
|
+
|
36
|
+
def context=(context)
|
37
|
+
@command = nil
|
38
|
+
@context = context
|
39
|
+
end
|
40
|
+
|
41
|
+
def normalize(context)
|
42
|
+
return [] if context.nil?
|
43
|
+
context.kind_of?(String) ? context.shellsplit : context
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
context.join(' ')
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_a
|
51
|
+
context
|
52
|
+
end
|
53
|
+
|
54
|
+
def +(arr)
|
55
|
+
context + Array(arr)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'kontena/plugin/shell/context'
|
2
|
+
require 'kontena/plugin/shell/command'
|
3
|
+
require 'kontena/plugin/shell/completer'
|
4
|
+
require 'shellwords'
|
5
|
+
require 'readline'
|
6
|
+
|
7
|
+
module Kontena::Plugin
|
8
|
+
module Shell
|
9
|
+
class Session
|
10
|
+
|
11
|
+
attr_reader :context
|
12
|
+
|
13
|
+
def initialize(context)
|
14
|
+
@context = Context.new(context)
|
15
|
+
read_history
|
16
|
+
end
|
17
|
+
|
18
|
+
def history_file
|
19
|
+
ENV['KOSH_HISTORY'] || File.join(Dir.home, '.kosh_history')
|
20
|
+
end
|
21
|
+
|
22
|
+
def read_history
|
23
|
+
File.readlines(history_file).each { |line| Readline::HISTORY.push(line.chomp) } if File.exist?(history_file)
|
24
|
+
end
|
25
|
+
|
26
|
+
def run_command(buf)
|
27
|
+
tokens = buf.split(/\s(?=(?:[^"]|"[^"]*")*$)/).map(&:strip)
|
28
|
+
runner = Shell.command(tokens.first) || Shell.command(context.first) || Kontena::Plugin::Shell::KontenaCommand
|
29
|
+
command = runner.new(context, tokens, self)
|
30
|
+
old_trap = trap('INT', Proc.new { Thread.main[:command_thread] && Thread.main[:command_thread].kill })
|
31
|
+
Thread.main[:command_thread] = Thread.new do
|
32
|
+
command.run
|
33
|
+
end
|
34
|
+
Thread.main[:command_thread].join
|
35
|
+
trap('INT', old_trap)
|
36
|
+
end
|
37
|
+
|
38
|
+
def run
|
39
|
+
puts File.read(__FILE__)[/__END__$(.*)/m, 1]
|
40
|
+
puts "Kontena Shell v#{Kontena::Plugin::Shell::VERSION} (c) 2017 Kontena"
|
41
|
+
puts pastel.blue("Enter 'help' to see a list of commands or 'help <command>' to get help on a specific command.")
|
42
|
+
|
43
|
+
stty_save = `stty -g`.chomp rescue nil
|
44
|
+
at_exit do
|
45
|
+
File.write(history_file, Readline::HISTORY.to_a.uniq.last(100).join("\n"))
|
46
|
+
system('stty', stty_save) if stty_save
|
47
|
+
end
|
48
|
+
|
49
|
+
Readline.completion_proc = Proc.new do |word|
|
50
|
+
line = Readline.line_buffer
|
51
|
+
tokens = line.shellsplit
|
52
|
+
tokens.pop unless word.empty?
|
53
|
+
|
54
|
+
if context.empty? && tokens.empty?
|
55
|
+
completions = Kontena::MainCommand.recognised_subcommands.flat_map(&:names) + Shell.commands.keys
|
56
|
+
else
|
57
|
+
command = Shell.command(context.first || tokens.first || 'kontena')
|
58
|
+
if command
|
59
|
+
if command.completions.first.respond_to?(:call)
|
60
|
+
completions = command.completions.first.call(context, tokens, word)
|
61
|
+
else
|
62
|
+
completions = Array(command.completions)
|
63
|
+
end
|
64
|
+
else
|
65
|
+
completions = []
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
word.empty? ? completions : completions.select { |c| c.start_with?(word) }
|
70
|
+
end
|
71
|
+
|
72
|
+
while buf = Readline.readline(prompt, true)
|
73
|
+
if buf.strip.empty?
|
74
|
+
Readline::HISTORY.pop
|
75
|
+
else
|
76
|
+
run_command(buf)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
puts
|
80
|
+
puts pastel.green("Bye!")
|
81
|
+
end
|
82
|
+
|
83
|
+
def pastel
|
84
|
+
Kontena.pastel
|
85
|
+
end
|
86
|
+
|
87
|
+
def config
|
88
|
+
Kontena::Cli::Config
|
89
|
+
end
|
90
|
+
|
91
|
+
def prompt
|
92
|
+
"#{master_name}/#{grid_name} #{pastel.yellow(context)} #{caret} "
|
93
|
+
end
|
94
|
+
|
95
|
+
def caret
|
96
|
+
pastel.white('>')
|
97
|
+
end
|
98
|
+
|
99
|
+
def master_name
|
100
|
+
config.current_master ? pastel.green(config.current_master.name) : pastel.red('<no master>')
|
101
|
+
end
|
102
|
+
|
103
|
+
def grid_name
|
104
|
+
config.current_grid ? pastel.green(config.current_grid) : pastel.red('<no grid>')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
__END__
|
110
|
+
_ _
|
111
|
+
| | _____ _ __ | |_ ___ _ __ __ _
|
112
|
+
| |/ / _ \| '_ \| __/ _ \ '_ \ / _` |
|
113
|
+
| < (_) | | | | || __/ | | | (_| |
|
114
|
+
|_|\_\___/|_| |_|\__\___|_| |_|\__,_|
|
115
|
+
-------------------------------------
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'kontena/plugin/shell'
|
2
|
+
|
3
|
+
class Kontena::Plugin::Shell::ShellCommand < Kontena::Command
|
4
|
+
|
5
|
+
parameter "[CONTEXT] ...", "Jump to context", attribute_name: :context_list
|
6
|
+
|
7
|
+
def execute
|
8
|
+
Kontena::Plugin::Shell::Session.new(context_list).run
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
path = Pathname.new(__FILE__).dirname.realpath.to_s
|
3
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
4
|
+
|
5
|
+
require 'kontena_cli' unless Object.const_defined?(:Kontena) && Kontena.const_defined?(:Cli)
|
6
|
+
|
7
|
+
require 'kontena/plugin/shell'
|
8
|
+
require 'kontena/plugin/shell/shell_command'
|
9
|
+
require 'kontena/plugin/shell/callbacks/stack_file'
|
10
|
+
|
11
|
+
Kontena::MainCommand.register("shell", "Kontena shell", Kontena::Plugin::Shell::ShellCommand)
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: kontena-plugin-shell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kontena, Inc.
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-04-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kontena-cli
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.0.rc1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.0.rc1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.11'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.5'
|
69
|
+
description: Interactive shell for Kontena CLI aka KOSH
|
70
|
+
email:
|
71
|
+
- info@kontena.io
|
72
|
+
executables:
|
73
|
+
- kosh
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".travis.yml"
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.md
|
83
|
+
- bin/kosh
|
84
|
+
- kontena-plugin-shell.gemspec
|
85
|
+
- kosh.gif
|
86
|
+
- lib/kontena/plugin/shell.rb
|
87
|
+
- lib/kontena/plugin/shell/callbacks/stack_file.rb
|
88
|
+
- lib/kontena/plugin/shell/command.rb
|
89
|
+
- lib/kontena/plugin/shell/commands/batch.rb
|
90
|
+
- lib/kontena/plugin/shell/commands/batch_do.rb
|
91
|
+
- lib/kontena/plugin/shell/commands/context_top.rb
|
92
|
+
- lib/kontena/plugin/shell/commands/context_up.rb
|
93
|
+
- lib/kontena/plugin/shell/commands/debug.rb
|
94
|
+
- lib/kontena/plugin/shell/commands/exit.rb
|
95
|
+
- lib/kontena/plugin/shell/commands/help.rb
|
96
|
+
- lib/kontena/plugin/shell/commands/kontena.rb
|
97
|
+
- lib/kontena/plugin/shell/completer.rb
|
98
|
+
- lib/kontena/plugin/shell/context.rb
|
99
|
+
- lib/kontena/plugin/shell/session.rb
|
100
|
+
- lib/kontena/plugin/shell/shell_command.rb
|
101
|
+
- lib/kontena/plugin/shell/version.rb
|
102
|
+
- lib/kontena_cli_plugin.rb
|
103
|
+
homepage: https://github.com/kontena/kontena-plugin-shell
|
104
|
+
licenses:
|
105
|
+
- Apache-2.0
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.4.5
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: Kontena interactive shell plugin
|
127
|
+
test_files: []
|