dockerkit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f938406c52b63b22d7dc3af287d33e5231c8256d
4
+ data.tar.gz: 97486a2baf49fc7d987a85b578625a493c7a42d8
5
+ SHA512:
6
+ metadata.gz: 90f1caa5e4109ea580e17dade20a593abadd2abcb5abc6c016aaa506e74a812232dc7f43dd0c495fc8aa2a9feff44ccf83219511fa92bf7f1ff0a62a80b93d28
7
+ data.tar.gz: a56e4a9400a506c9b1fda282edb04ea9a974f9e7c3a976f3985c3712bd6a749b2308dcc7bcd020d5c6bc29be33f1e211c2f42568322c00c23964ec23a7cd75a6
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 shaoyang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Dockerkit
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/dockerkit`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'dockerkit'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install dockerkit
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/shao4phone@gmail.com/dockerkit.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/bin/dk ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require "dockerkit"
4
+ Dockerkit::Base.start
data/lib/alias.yml ADDED
@@ -0,0 +1,9 @@
1
+ mysql: docker run -d --rm -p3306:3306 --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
2
+ mongo: docker run -d --rm -p27017:27017 --name mongo mongo
3
+ postgres: docker run -d --rm -p5432:5432 --name postgres postgres
4
+ bash: dk exec -o "'-it'" --cmd "/bin/bash"
5
+ sh: dk exec -o "'-it'" --cmd "/bin/sh"
6
+ lsv: docker volume ls
7
+ v: docker volume
8
+ lsn: docker network ls
9
+ net: docker network
@@ -0,0 +1,3 @@
1
+ DOCKER_CONFIG_FILE = 'docker.rc.yml'.freeze
2
+ DOCKER_FILE = 'Dockerfile'.freeze
3
+ DOCKER_COMPOSE_FILE = 'docker-compose.yml'.freeze
@@ -0,0 +1,110 @@
1
+ module ContainerTasks
2
+ extend ActiveSupport::Concern
3
+ module ClassMethods
4
+ end
5
+
6
+ included do
7
+ desc 'lsc [KEYWORD] [-n nk] [-i ik]', <<-LONG
8
+ 'list all container which container name match the patten'
9
+ example:
10
+ dk lsc #list all containers
11
+ dk lsc test #list all containers which include string test;
12
+ dk lsc test -n nk #list all containers which include test and name include nk;
13
+ dk lsc test -i ik #list all containers which include test and image include ik;
14
+ dk lsc -n nk -i tk #list all containers which name include nk and image include ik
15
+ LONG
16
+ method_option :name, type: :string, aliases: 'n'
17
+ method_option :image, type: :string, aliases: 'i'
18
+ def lsc(keyword = nil)
19
+ ret = Container.find(keyword: keyword, name: options['name'], image: options['image'])
20
+ Container.print_table(ret)
21
+ end
22
+
23
+ desc 'del [KEYWORD] [-n nk] [-i ik]', <<-LONG
24
+ 'delete all containers which container data match the patten'
25
+ example:
26
+ dk del #delete all containers
27
+ dk del test #delete all containers which include string test;
28
+ dk del test -n nk #delete all containers which include test and name include nk;
29
+ dk del test -i ik #delete all containers which include test and image include ik;
30
+ dk del -n nk -i tk #delete all containers which name include nk and image include ik
31
+ LONG
32
+ method_option :name, type: :string, aliases: 'n'
33
+ method_option :image, type: :string, aliases: 'i'
34
+ def del(keyword = nil)
35
+ ret = Container.find(keyword: keyword, name: options['name'], image: options['image'])
36
+ Container.print_table(ret)
37
+ say('The listed containers will be deleted, ARE YOU SURE.'.blue)
38
+ answer = ask('(y=YES;q=QUIT;i=ASK one by one)', limited_to: %w[y q i])
39
+ return if answer == 'q'
40
+ ret.each do |container|
41
+ if answer == 'i'
42
+ say(container.to_s)
43
+ each_answer = ask('going to delete? (y=YES,n=NO,q=QUIT):')
44
+ next if each_answer == 'n'
45
+ break if each_answer == 'q'
46
+ end
47
+ container.del
48
+ end
49
+ end
50
+ map rm: :del
51
+ map rmc: :del
52
+
53
+
54
+
55
+ desc 'exec [KEYWORD] [-n nk] [-i ik] [--opts] [--cmd] [-s]', <<-LONG
56
+ select container which container_name match the patten and select some to run
57
+ example:
58
+ dk exec\
59
+ #list all container and select some to exec
60
+
61
+ dk exec test\
62
+ #list all container which include string test and select one to exec;
63
+
64
+ dk exec test -n nk\
65
+ #list all container which include test and name include nk and select one to exec;
66
+
67
+ dk exec test -t tk\
68
+ #list all container which include test and tag include tk and select one to exec;
69
+
70
+ dk exec -n nk -t tk\
71
+ #list all container which repository include nk and tag include tk and select one to push;
72
+
73
+ dk exec --opts "'-i -t --name test'" --cmd '/bin/bash'\
74
+ #NOTE opts and cmd option ,use "''" to quot as sample
75
+ #list all container and exec as opts -it --name test and command is /bin/bash
76
+
77
+ dk exec --opts "'-i -t'" --cmd '/bin/bash' -s test.bash\
78
+ #NOTE opts and cmd option ,use "''" to quot as sample
79
+ #list all container and exec as opts -it --name test and command is /bin/bash
80
+ #and save the command as alias and alias name is test.bash
81
+ LONG
82
+ method_option :opts, type: :string, aliases: 'o'
83
+ method_option :cmd, type: :string, aliases: 'c'
84
+ method_option :name, type: :string, aliases: 'n'
85
+ method_option :image, type: :string, aliases: 'i'
86
+ method_option :alias, type: :string, aliases: 's'
87
+
88
+ def exec(keyword = nil)
89
+ ret = Container.find(keyword: keyword, name: options['name'], image: options['image'])
90
+
91
+ if ret.count > 1
92
+ Container.print_table(ret) { |item, index| "[#{index + 1}]#{item}" }
93
+ question = ['please select one container to run:'].unshift(' ').unshift(' ').join("\n")
94
+ say(question.blue)
95
+ answer = ask('(q=QUIT;n=)', limited_to: ['q', *('1'..ret.count.to_s).to_a])
96
+ return if answer == 'q'
97
+ end
98
+
99
+
100
+ command = options['cmd'] || ask_with_default('Any command you want to run?', 'echo hello')
101
+ opts = options['opts'] || ask_with_default('Any option you want to set?', '-it')
102
+ index=(answer&.to_i||1)-1
103
+ xcommand=ret[index].exec(opts, command)
104
+ run(["dk","alias",options['alias'],xcommand].join(" ")) if options['alias']
105
+ run(xcommand.join(" "))
106
+ end
107
+
108
+
109
+ end
110
+ end
@@ -0,0 +1,206 @@
1
+ module ImageTasks
2
+ extend ActiveSupport::Concern
3
+ module ClassMethods
4
+ end
5
+
6
+ included do
7
+ desc 'ls [KEYWORD] [-n nk] [-t tk]', <<-LONG
8
+ 'list all images which image_name match the patten'
9
+ example:
10
+ dk ls #list all images
11
+ dk ls test #search all images which include string test;
12
+ dk ls test -n nk #search all images which include test and name include nk;
13
+ dk ls test -t tk #search all images include test and tag include tk;
14
+ dk ls -n nk -t tk #search all images which repository include nk and tag include tk
15
+ LONG
16
+ method_option :name, type: :string, aliases: 'n'
17
+ method_option :tag, type: :string, aliases: 't'
18
+ def ls(keyword = nil)
19
+ ret = Image.find(keyword: keyword, name: options['name'], tag: options['tag'])
20
+ Image.print_table(ret)
21
+ # print_table([ret.unshift(Image.headers)])
22
+ end
23
+
24
+ desc 'rmi [KEYWORD] [-n nk] [-t tk]', <<-LONG
25
+ 'delete images which image_name match the patten'
26
+ example:
27
+ dk rmi #delete all images
28
+ dk rmi test #delete all images which include string test;
29
+ dk rmi test -n nk #delete all images which include test and name include nk;
30
+ dk rmi test -t tk #delete all images which include test and tag include tk;
31
+ dk rmi -n nk -t tk #delete all images which repository include nk and tag include tk
32
+ LONG
33
+ method_option :name, type: :string, aliases: 'n'
34
+ method_option :tag, type: :string, aliases: 't'
35
+ def rmi(keyword = nil)
36
+ ret = Image.find(keyword: keyword, name: options['name'], tag: options['tag'])
37
+ Image.print_table(ret)
38
+ say('The listed images will be deleted, ARE YOU SURE?'.blue)
39
+ answer = ask('(y=YES;q=QUIT;i=ASK one by one)', limited_to: %w[y q i])
40
+ return if answer == 'q'
41
+ ret.each do |image|
42
+ if answer == 'i'
43
+ say(image.to_s)
44
+ each_answer = ask('going to delete? (y=YES,n=NO,q=QUIT):')
45
+ next if each_answer == 'n'
46
+ break if each_answer == 'q'
47
+ end
48
+ image.del
49
+ end
50
+ end
51
+
52
+ desc 'pull [IMAGENAME] [-as one two three]', <<-LONG
53
+ 'pull ruby:2.3.4 -l myruby ruby:2.3'
54
+ LONG
55
+ method_option :local, type: :array, aliases: 'l'
56
+ def pull(name)
57
+ Image.pull(name)
58
+ binding.pry
59
+ if options['local']
60
+ options['local'].each do |new_name|
61
+ Image.tag(name, new_name)
62
+ end
63
+ end
64
+ end
65
+
66
+ desc 'push [KEYWORD] [-n nk] [-t tk]', <<-LONG
67
+ 'select images which image_name match the patten and select some to push'
68
+ example:
69
+ dk push #list all images and select some to push
70
+ dk push test #list all images which include string test and select some to push;
71
+ dk push test -n nk #list all images which include test and name include nk and select some to push;
72
+ dk push test -t tk #list all images which include test and tag include tk and select some to push;
73
+ dk push -n nk -t tk #list all images which repository include nk and tag include tk and select some to push;
74
+ LONG
75
+ method_option :name, type: :string, aliases: 'n'
76
+ method_option :tag, type: :string, aliases: 't'
77
+ def push(keyword = nil)
78
+ ret = Image.find(keyword: keyword, name: options['name'], tag: options['tag'])
79
+ Image.print_table(ret)
80
+ say('The listed images will be pushed, ARE YOU SURE?'.blue)
81
+ answer = ask('(y=YES;q=QUIT;i=ASK one by one)', limited_to: %w[y q i])
82
+ return if answer == 'q'
83
+ ret.each do |image|
84
+ if answer == 'i'
85
+ say(image.to_s)
86
+ each_answer = ask('going to push? (y=YES,n=NO,c=YES and change repository name,q=QUIT):')
87
+ next if each_answer == 'n'
88
+ break if each_answer == 'q'
89
+ if each_answer == 'c'
90
+ new_rep = ask_with_default('New repository?', image.image_name)
91
+ Image.tag(image.image_name, new_rep)
92
+ image.repository, image.tag = new_rep.split(':')
93
+ end
94
+ end
95
+ image.push
96
+ end
97
+ end
98
+
99
+ desc 'tag [IMAGENAME] [-t one two three]', <<-LONG
100
+ tag image as new images
101
+
102
+ samples:
103
+
104
+ tag ruby:2.3.4 -t a:2.3.4 haha:2.3.4
105
+ LONG
106
+ method_option :as, type: :array
107
+ def tag(name)
108
+ image = search_with_ask(name, Image, 'which image you want to tag?')
109
+ say(image.to_s)
110
+ option ||= {}
111
+ new_image_name = option['as'] || ask('new image name?')
112
+ Image.tag(image.image_name, new_image_name)
113
+ end
114
+
115
+ desc 'xrun [KEYWORD] [-n nk] [-t tk] [--opts] [--cmd] [-s]', <<-LONG
116
+ select images which image_name match the patten and select some to run
117
+ example:
118
+ dk xrun\
119
+ #list all images and select some to run
120
+
121
+ dk xrun test\
122
+ #list all images which include string test and select one to run;
123
+
124
+ dk xrun test -n nk\
125
+ #list all images which include test and name include nk and select one to run;
126
+
127
+ dk xrun test -t tk\
128
+ #list all images which include test and tag include tk and select one to xrun;
129
+
130
+ dk xrun -n nk -t tk\
131
+ #list all images which repository include nk and tag include tk and select one to push;
132
+
133
+ dk xrun --opts "'-i -t --name test'" --cmd '/bin/bash'\
134
+ #NOTE opts and cmd option ,use "''" to quot as sample
135
+ #list all images and run as opts -it --name test and command is /bin/bash
136
+
137
+ dk xrun --opts "'-i -t --name test'" --cmd '/bin/bash' -s test.bash\
138
+ #NOTE opts and cmd option ,use "''" to quot as sample
139
+ #list all images and run as opts -it --name test and command is /bin/bash
140
+ #and save the command as alias and alias name is test.bash
141
+ LONG
142
+ method_option :opts, type: :string, aliases: 'o'
143
+ method_option :cmd, type: :string, aliases: 'c'
144
+ method_option :name, type: :string, aliases: 'n'
145
+ method_option :tag, type: :string, aliases: 't'
146
+ method_option :alias, type: :string, aliases: 's'
147
+
148
+ def xrun(keyword = nil)
149
+ ret = Image.find(keyword: keyword, name: options['name'], tag: options['tag'])
150
+ if ret.count==0
151
+ repository,tag=keyword.split(":")
152
+ ret=[Image.new(repository:repository,tag:tag)]
153
+ end
154
+
155
+ if ret.count > 1
156
+ Image.print_table(ret) { |item, index| "[#{index + 1}]#{item}" }
157
+ question = ['please select one image to run:'].unshift(' ').unshift(' ').join("\n")
158
+ say(question.blue)
159
+ answer = ask('(q=QUIT;n=)', limited_to: ['q', *('1'..ret.count.to_s).to_a])
160
+ return if answer == 'q'
161
+ end
162
+
163
+
164
+ command = options['cmd'] || ask_with_default('Any command you want to run?', '')
165
+ opts = options['opts'] || ask_with_default('Any option you want to set?', '-d')
166
+ index=(answer&.to_i||1)-1
167
+ xcommand=ret[index].launch(opts, command)
168
+ run(["dk","alias",options['alias'],xcommand].join(" ")) if options['alias']
169
+ run(xcommand.join(" "))
170
+ end
171
+
172
+ desc 'build [-d ./docker]', <<-LONG
173
+ build docker file
174
+
175
+ sample:
176
+
177
+ dk build -d ./docker
178
+ LONG
179
+ method_option :dir, type: :string, aliases: 'd', default: '.'
180
+ def build
181
+ dir = options['dir']
182
+ invoke(:init) if file_not_exist?("#{dir}/#{DOCKER_CONFIG_FILE}")
183
+ load_config(dir) do |config|
184
+ Image.build(DOCKER_FILE, config[:repository_urls].map { |url| "#{url}/#{config[:image_name]}" })
185
+ end
186
+ end
187
+
188
+ desc 'release [-d ./docker]', <<-LONG
189
+ release docker file
190
+
191
+ sample:
192
+
193
+ dk release -d ./docker
194
+ LONG
195
+ method_option :dir, type: :string, aliases: 'd', default: '.'
196
+ def release
197
+ dir = options['dir']
198
+ invoke(:init) if file_not_exist?("#{dir}/#{DOCKER_CONFIG_FILE}")
199
+ load_config(dir) do |config|
200
+ config[:repository_urls].map { |url| "#{url}/#{config[:image_name]}" }.each do |image_name|
201
+ Image.push(image_name)
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,3 @@
1
+ module Dockerkit
2
+ VERSION = "0.1.0"
3
+ end
data/lib/dockerkit.rb ADDED
@@ -0,0 +1,147 @@
1
+ require 'dockerkit/version'
2
+ require 'thor'
3
+ require 'colorize'
4
+ require 'pry-byebug'
5
+ require 'active_support'
6
+ require 'active_support/core_ext'
7
+ require 'yaml'
8
+ require 'erubis'
9
+ Dir[File.dirname(__FILE__) + '/models/*.rb'].each { |file| require file }
10
+ Dir[File.dirname(__FILE__) + '/concerns/*.rb'].each { |file| require file }
11
+
12
+ class Hammer < Thor
13
+ include Thor::Actions
14
+ end
15
+
16
+ def hammer
17
+ Hammer.new
18
+ end
19
+
20
+ module Dockerkit
21
+ class Base < Thor
22
+ include Thor::Actions
23
+ include ContainerTasks
24
+ include ImageTasks
25
+
26
+ source_root File.dirname(__FILE__)
27
+
28
+ desc 'alias [NAME] [CMD]', <<-LONG
29
+ alias name with a cmd
30
+
31
+ Sample:
32
+ dk alias #list all alias
33
+ dk alias ls.mongo dk ls mongo #aliase ls.mongo as command 'dk ls mongo'
34
+ dk alias ls.mongo -d #delete alias ls.mongo
35
+ LONG
36
+ method_option :delete, type: :boolean, aliases: 'd'
37
+ method_option :help, type: :boolean, aliases: 'h'
38
+
39
+ def alias(name = nil, *cmds)
40
+ return say((Alias.all[name] || "No such Alias:#{name}").red) if options['help']
41
+ return Alias.list_alias unless name
42
+ return Alias.delete_alias(name) if name && options['delete']
43
+ return Alias.create_alias(name, cmds) if cmds
44
+ end
45
+
46
+ desc 'init [-d ./docker]', <<-LONG
47
+ init current folder for a docker related project
48
+
49
+
50
+ SAMPLE:
51
+ init -d ./docker #init docker-compose , dockerfile, and dockerconfig in ./docker path
52
+ LONG
53
+
54
+ method_option :dir, type: :string, aliases: 'd', default: '.'
55
+ def init
56
+ dir = options['dir']
57
+ load_config(dir) do |config|
58
+ config[:image_name] = ask_with_default('Image name?', "#{File.basename(Dir.getwd)}:latest")
59
+ config[:repository_urls] = multi_ask('Add new repository_url?')
60
+ end
61
+ inside(dir) do
62
+ init_dockerfile if file_not_exist?(DOCKER_FILE.to_s) && ask('Need Create Dockerfile?'.red, limited_to: %w[y n]) == 'y'
63
+ init_docker_compose_file if file_not_exist?(DOCKER_COMPOSE_FILE.to_s) && ask('Need Create docker-compose file?'.red, limited_to: %w[y n]) == 'y'
64
+ end
65
+ end
66
+
67
+ desc '_[DOCKERCOMMAND]', 'invoke docker command directly'
68
+
69
+ desc '[ALIAS_NAME]', 'invoke alias'
70
+ def method_missing(method, *args)
71
+ return Alias.run(method.to_s, args) if Alias.all.key?(method.to_s)
72
+ return send(:docker, *args.unshift(method.to_s.gsub(/^_/, ''))) if method.to_s.start_with?('_')
73
+ end
74
+
75
+ private
76
+
77
+ def init_dockerfile(dir = '.')
78
+ load_config(dir) do |config|
79
+ config[:author] = ask_with_default('Author is ?', ENV['USER'].camelize)
80
+ config[:base_image] = ask_with_default('Base Image?', 'alpine')
81
+ config[:deamon_cmd] = ask_with_default('Deamon CMD?', 'tail -f /dev/null')
82
+ @config = config
83
+ template("#{self.class.source_root}/templates/Dockerfile", DOCKER_FILE)
84
+ end
85
+ end
86
+
87
+ def init_docker_compose_file(dir = '.')
88
+ load_config(dir) do |config|
89
+ config[:service_name] = ask_with_default('Service Name is ?', 'app')
90
+ @config = config
91
+ template("#{self.class.source_root}/templates/docker-compose.yml", DOCKER_COMPOSE_FILE)
92
+ end
93
+ end
94
+
95
+ def search_with_ask(name, klass, question)
96
+ ret = klass.search(name)
97
+ return ret.first if ret.size == 1
98
+ unless ret.empty?
99
+ q = ret.each_with_index.map { |image, i| "[#{i + 1}] #{image}" }
100
+ q.unshift(klass.headers)
101
+ # print_table(q)
102
+ say(q.join(''))
103
+ answer = ask(question, limited_to: ('1'..ret.size.to_s).to_a.unshift('q'))
104
+ return if answer == 'q'
105
+ ret[answer.to_i - 1]
106
+ end
107
+ end
108
+
109
+ def ask_with_default(question, default)
110
+ answer = ask("#{question.red} [default:#{default.blue}]:").chomp
111
+ answer.empty? ? default : answer
112
+ end
113
+
114
+ def load_config(dir)
115
+ inside dir do
116
+ create_file(DOCKER_CONFIG_FILE) unless File.exist?(DOCKER_CONFIG_FILE)
117
+ config = YAML.load_file(DOCKER_CONFIG_FILE) || {}
118
+ if block_given?
119
+ yield config
120
+ create_file(DOCKER_CONFIG_FILE, config.to_yaml)
121
+ end
122
+ end
123
+ end
124
+
125
+ def file_not_exist?(file)
126
+ !File.exist?(file)
127
+ end
128
+
129
+ def multi_ask(question)
130
+ ret = []
131
+ answer = 'start'
132
+ until answer.empty?
133
+ answer = ask("#{question.red},(ENTER directly will end the question)").chomp
134
+ ret.push answer unless answer.empty?
135
+ end
136
+ ret
137
+ end
138
+
139
+ def docker(*args)
140
+ hammer.run("docker #{args.join(' ')}")
141
+ end
142
+
143
+ def precheck
144
+ true
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,52 @@
1
+ class Alias
2
+ def self.all
3
+ default_yml = "#{__dir__}/../alias.yml"
4
+ extend_yml = "#{ENV['HOME']}/.dk/alias.yml"
5
+ default_alias = YAML.load_file(default_yml) || {}
6
+
7
+ extend_alias = File.exist?(extend_yml) ? YAML.load_file(extend_yml) : {}
8
+ ret = {}.merge(default_alias).merge(extend_alias)
9
+ end
10
+
11
+ def self.list_alias
12
+ hammer.say 'Aliases:'
13
+ all.each do |name, cmd|
14
+ hammer.say(" #{name} ##{cmd}")
15
+ end
16
+ end
17
+
18
+ def self.create_alias(name, cmds)
19
+ extend_yml = "#{ENV['HOME']}/.dk/alias.yml"
20
+ extend_alias = File.exist?(extend_yml) ? YAML.load_file(extend_yml) : {}
21
+ extend_alias[name] = cmds.join(' ')
22
+ File.open(extend_yml, 'w') { |f| f.write extend_alias.to_yaml }
23
+ end
24
+
25
+ def self.delete_alias(name)
26
+ extend_yml = "#{ENV['HOME']}/.dk/alias.yml"
27
+ extend_alias = File.exist?(extend_yml) ? YAML.load_file(extend_yml) : {}
28
+ extend_alias.delete(name)
29
+ File.open(extend_yml, 'w') { |f| f.write extend_alias.to_yaml }
30
+ end
31
+
32
+ def self.run(name, args)
33
+ hash_opts, options = parse(args)
34
+ begin
35
+ command = Erubis::Eruby.new(options.unshift(all[name]).join(' ')).result(hash_opts)
36
+ hammer.run(command)
37
+ rescue => e
38
+ missed_opts = /`(.*)'/.match(e.message).captures.map { |i| "#{i}:<#{i}>" }.join(',')
39
+ hammer.say("pls provide opts #{missed_opts}")
40
+ end
41
+ end
42
+
43
+ def self.parse(args)
44
+ regexp = /:/
45
+ hash_opts = args.select { |item| regexp.match(item) }
46
+ options = args - hash_opts
47
+ split_options = Thor::Options.split(options)
48
+ hash_opts_obj = hash_opts.map { |item| item.split(':') }.to_h
49
+ hash_opts_obj['args'] = options.unshift('')
50
+ ret = [hash_opts_obj, split_options]
51
+ end
52
+ end
@@ -0,0 +1,58 @@
1
+ module Base
2
+ extend ActiveSupport::Concern
3
+ module ClassMethods
4
+ def raw_lines
5
+ hammer.run(command, capture: true).lines
6
+ end
7
+
8
+ def load(lines = raw_lines)
9
+ @headers = lines.first
10
+ @items = lines[1..-1].map do |line|
11
+ create(line)
12
+ end
13
+ end
14
+
15
+ def all
16
+ load
17
+ end
18
+
19
+ def headers_raw
20
+ @headers
21
+ end
22
+
23
+ def search(*keywords)
24
+ keyword, = keywords
25
+ keyword ||= '.'
26
+ regexp = /#{keyword}/i
27
+ ret = load.reject do |item|
28
+ item.regexp = regexp
29
+ regexp.match(item.raw).nil?
30
+ end
31
+ ret
32
+ end
33
+
34
+ def print_table(data)
35
+ hammer.say @headers
36
+ ret = data.each_with_index.map do |item, index|
37
+ item = yield(item, index) if block_given?
38
+ item.to_s
39
+ end.join('')
40
+ hammer.say ret
41
+ end
42
+
43
+ def run(*cmds)
44
+ hammer.run(cmds.join(' '))
45
+ end
46
+ end
47
+
48
+ included do
49
+ attr_accessor :raw, :regexp
50
+ def to_s
51
+ @raw.gsub!(@regexp, '\0'.yellow) if @regexp
52
+ end
53
+
54
+ def run(*cmds)
55
+ hammer.run(cmds.join(' '))
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,75 @@
1
+ require 'thor'
2
+ class Container
3
+ include Base
4
+ attr_accessor :id, :image_str, :command, :created, :status, :ports, :name, :regexp_repo, :regexp_name
5
+ def self.command
6
+ 'docker ps -a'
7
+ end
8
+
9
+ def self.find(keyword:, name:, image:)
10
+ return all unless keyword || name || image
11
+ ret = keyword ? search(keyword) : all
12
+ if image
13
+ regexp_repo = /#{image}/i
14
+ ret = ret.select do |container|
15
+ container.regexp_repo = regexp_repo
16
+ regexp_repo.match container.image_str
17
+ end
18
+ end
19
+ if name
20
+ regexp_name = /#{name}/i
21
+ ret = ret.select do |container|
22
+ container.regexp_name = regexp_name
23
+ regexp_name.match container.name
24
+ end
25
+ end
26
+ ret
27
+ end
28
+
29
+ def self.create(line)
30
+ id, image_str, command, created, status, ports, name = line.chomp.split(' ' * 2).reject(&:empty?).map(&:strip)
31
+ ret = new(
32
+ id: id,
33
+ image_str: image_str,
34
+ command: command,
35
+ created: created,
36
+ status: status,
37
+ ports: ports,
38
+ name: name,
39
+ raw: line
40
+ )
41
+ ret
42
+ end
43
+
44
+ def initialize(**params)
45
+ @id = params[:id]
46
+ @image_str = params[:image_str]
47
+ @command = params[:command]
48
+ @created = params[:created]
49
+ @status = params[:status]
50
+ @ports = params[:ports]
51
+ @name = params[:name]
52
+ @raw = params[:raw]
53
+ end
54
+
55
+ def del
56
+ run("docker rm -f #{id}")
57
+ end
58
+
59
+ def exec(exec_opts, command)
60
+ [
61
+ 'docker exec',
62
+ exec_opts,
63
+ name,
64
+ command
65
+ ]
66
+ end
67
+
68
+ def to_s
69
+ @raw.gsub!(@regexp, &:yellow) if @regexp
70
+ @raw.sub!(/ #{image_str} /) { |_| image_str.gsub(@regexp_repo, '\0'.red) } if @regexp_repo
71
+ @raw.gsub!(/#{name}$/) { |name| name.gsub(@regexp_name, '\0'.blue) } if @regexp_name
72
+
73
+ @raw
74
+ end
75
+ end
@@ -0,0 +1,108 @@
1
+ class Image
2
+ include Base
3
+ attr_accessor :id, :repository, :tag, :created, :size, :regexp_repo, :regexp_tag
4
+ def self.headers
5
+ {
6
+ repository: 'REPOSITORY',
7
+ tag: 'TAG',
8
+ id: 'IMAGE ID',
9
+ created: 'CREATED',
10
+ size: 'SIZE'
11
+ }
12
+ end
13
+
14
+ def self.command
15
+ 'docker images'
16
+ end
17
+
18
+ def self.launch(image_name, run_opts, command)
19
+ ['docker', 'run', run_opts, image_name, command]
20
+ end
21
+
22
+ def self.build(dockerfile, *tags)
23
+ run 'docker',
24
+ 'build',
25
+ '--force-rm',
26
+ '-f',
27
+ dockerfile,
28
+ '-t',
29
+ tags.join(' -t '),
30
+ '.'
31
+ end
32
+
33
+ def self.find(keyword:, name:, tag:)
34
+ return all unless keyword || name || tag
35
+ ret = keyword ? search(keyword) : all
36
+ if name
37
+ regexp_repo = /#{name}/i
38
+ ret = ret.select do |image|
39
+ image.regexp_repo = regexp_repo
40
+ regexp_repo.match image.repository
41
+ end
42
+ end
43
+ if tag
44
+ regexp_tag = /#{tag}/i
45
+ ret = ret.select do |image|
46
+ image.regexp_tag = regexp_tag
47
+ regexp_tag.match image.tag
48
+ end
49
+ end
50
+ ret
51
+ end
52
+
53
+ def self.push(image_name)
54
+ run("docker push #{image_name}")
55
+ end
56
+
57
+ def self.create(line)
58
+ repository, tag, id, created, size = line.chomp.split(' ' * 2).reject(&:empty?).map(&:strip)
59
+ ret = new(repository: repository, tag: tag, id: id, created: created, size: size, raw: line)
60
+ ret
61
+ end
62
+
63
+ def initialize(**params)
64
+ @repository = params[:repository]
65
+ @tag = params[:tag]
66
+ @id = params[:id]
67
+ @created = params[:created]
68
+ @size = params[:size]
69
+ @raw = params[:raw]
70
+ end
71
+
72
+ def del
73
+ run("docker rmi -f #{image_name}")
74
+ end
75
+
76
+ def self.pull(name)
77
+ run("docker pull #{name}")
78
+ end
79
+
80
+ def push
81
+ self.class.push(image_name)
82
+ end
83
+
84
+ def self.tag(name, *as_names)
85
+ run("docker tag #{name} #{as_names.join(' ')}")
86
+ end
87
+
88
+ def image_name
89
+ "#{repository}:#{tag || 'latest'}"
90
+ end
91
+
92
+ def launch(run_opts, command)
93
+ self.class.launch(image_name, run_opts, command)
94
+ end
95
+
96
+ def to_a(*cols)
97
+ cols = Image.headers.keys if cols.empty?
98
+ ret = cols.map { |col| send(col).strip }
99
+ ret
100
+ end
101
+
102
+ def to_s
103
+ @raw.gsub!(@regexp, &:yellow) if @regexp
104
+ @raw.sub!(repository, repository.gsub(@regexp_repo, '\0'.red)) if @regexp_repo
105
+ @raw.gsub!(/#{tag}$/) { |tag| tag.gsub(@regexp_tag, '\0'.blue) } if @regexp_tag
106
+ @raw
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ FROM '<%=@config[:base_image]%>'
2
+ MAINTAINER <%=@config[:author]%>
3
+ CMD <%=@config[:deamon_cmd]%>
@@ -0,0 +1,15 @@
1
+ version: '2.1'
2
+ services:
3
+ <%=@config[:service_name]%>:
4
+ image: <%=@config[:image_name]%>
5
+ # environment:
6
+ # ports:
7
+ # - 9191:3000
8
+ # links:
9
+ # - db:db
10
+ # depends_on:
11
+ # "db":
12
+ # condition: service_healthy
13
+ # volumes:
14
+ # - ../:/usr/src/app
15
+ command: <%=@config[:deamon_cmd]%>
metadata ADDED
@@ -0,0 +1,186 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dockerkit
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - shaoyang
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.15'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.15'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-byebug
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: thor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: colorize
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: activesupport
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: erubis
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: 'dockerkit '
140
+ email:
141
+ - shao4phone@gmail.com
142
+ executables:
143
+ - dk
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - LICENSE.txt
148
+ - README.md
149
+ - bin/dk
150
+ - lib/alias.yml
151
+ - lib/concerns/constants.rb
152
+ - lib/concerns/container_tasks.rb
153
+ - lib/concerns/image_tasks.rb
154
+ - lib/dockerkit.rb
155
+ - lib/dockerkit/version.rb
156
+ - lib/models/alias.rb
157
+ - lib/models/base.rb
158
+ - lib/models/container.rb
159
+ - lib/models/image.rb
160
+ - lib/templates/Dockerfile
161
+ - lib/templates/docker-compose.yml
162
+ homepage: http://github.com/yushaoyang
163
+ licenses:
164
+ - MIT
165
+ metadata: {}
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ required_rubygems_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ requirements: []
181
+ rubyforge_project:
182
+ rubygems_version: 2.6.11
183
+ signing_key:
184
+ specification_version: 4
185
+ summary: dockerkit
186
+ test_files: []