dockerfish 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/dockerfish +161 -0
- data/lib/dockerfish.rb +584 -0
- metadata +46 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d0b92c9f014ead6e102e8355c92276e3145ccbad
|
4
|
+
data.tar.gz: aadbc378a49b01534d0f6c8a98c89a7c220b1ebe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8d769840e583e4dadc85282291a326bcdddd9ce155290846b3f16f3093aee91051e79c3341a80e1ea3401a50a69ce7ea0e24e753fe77dba7509385d6e0a9915f
|
7
|
+
data.tar.gz: 2e9531a69795fd2f98ae3bbc885fe01f5b4222a9fca81e7eb784a0da032887fbfe916c988c533ceb59c73346f0ebec0e4fb9c56ad5ae9dec6cc367798ab2ab37
|
data/bin/dockerfish
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
########################################################################
|
4
|
+
# #
|
5
|
+
# Author: Brian Hood #
|
6
|
+
# Description: DockerFish Automation #
|
7
|
+
# #
|
8
|
+
# #
|
9
|
+
########################################################################
|
10
|
+
|
11
|
+
require File.expand_path(File.join(
|
12
|
+
File.dirname(__FILE__),
|
13
|
+
"../lib/dockerfish.rb"))
|
14
|
+
|
15
|
+
# GetOptLong remove argv value after processing so store to i can use it lower down.
|
16
|
+
argvstore = ARGV[0].to_s
|
17
|
+
|
18
|
+
trap("INT") {
|
19
|
+
puts "\nSee you soon !"
|
20
|
+
exit
|
21
|
+
}
|
22
|
+
|
23
|
+
def bookmarks(file)
|
24
|
+
puts "\e[1;32mBookmarks\e[0m\ "
|
25
|
+
puts "\e[1;32m=========\e[0m\ "
|
26
|
+
puts ""
|
27
|
+
def read(file)
|
28
|
+
b = 1
|
29
|
+
@bookmarks = Array.new
|
30
|
+
File.open("#{file}", 'r') {|n|
|
31
|
+
n.each_line {|l|
|
32
|
+
puts "\e[1;36m#{b})\e[0m\ #{l}"
|
33
|
+
@bookmarks[b] = l.split(" ")[1]
|
34
|
+
b = b + 1
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
if File.exists?("#{file}")
|
39
|
+
read(file)
|
40
|
+
else
|
41
|
+
# Add Localhost to your favourites as an example
|
42
|
+
File.open("#{file}", 'w') {|n|
|
43
|
+
n.puts("localhost http://localhost:2375")
|
44
|
+
}
|
45
|
+
read(file)
|
46
|
+
end
|
47
|
+
while buf4 = Readline.readline("\e[1;33m\Enter Bookmark>\e[0m\ ", true)
|
48
|
+
puts @bookmarks[buf4.to_i]
|
49
|
+
@bookmarkhost = @bookmarks[buf4.to_i]
|
50
|
+
break
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
opts = GetoptLong.new(
|
56
|
+
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
57
|
+
[ '--url', '-u', GetoptLong::OPTIONAL_ARGUMENT ],
|
58
|
+
[ '--bookmarks', '-b', GetoptLong::NO_ARGUMENT ],
|
59
|
+
[ '--start', '-s', GetoptLong::REQUIRED_ARGUMENT ],
|
60
|
+
[ '--stop', '-p', GetoptLong::REQUIRED_ARGUMENT ],
|
61
|
+
[ '--create', '-c', GetoptLong::REQUIRED_ARGUMENT ],
|
62
|
+
[ '--contimage', '-i', GetoptLong::REQUIRED_ARGUMENT ]
|
63
|
+
)
|
64
|
+
|
65
|
+
opts.each do |opt, arg|
|
66
|
+
case opt
|
67
|
+
when '--help'
|
68
|
+
helper = "\e[1;34mWelcome to DockerFish Version #{VERSION}\e[0m\ \n"
|
69
|
+
helper << "\e[1;34m=================================\e[0m\ "
|
70
|
+
helper << %q[
|
71
|
+
|
72
|
+
-h, --help:
|
73
|
+
show help
|
74
|
+
|
75
|
+
-u, -url Docker Host URL:
|
76
|
+
Note: Docker Host must of API Enabled to connect
|
77
|
+
Example: http://10.0.0.1:2375
|
78
|
+
|
79
|
+
Defaults to http://localhost:2375
|
80
|
+
|
81
|
+
-b, --bookmarks
|
82
|
+
Create .bookmarks file format
|
83
|
+
|
84
|
+
Example:
|
85
|
+
|
86
|
+
localhost http://127.0.0.1:2375
|
87
|
+
remoteserver http://10.0.2.15:2375
|
88
|
+
|
89
|
+
-c --create
|
90
|
+
Create container from image
|
91
|
+
|
92
|
+
-i --contimage
|
93
|
+
Create many from your container.json parameters.
|
94
|
+
|
95
|
+
# Comma separated for multiple containers supported
|
96
|
+
|
97
|
+
-s --start
|
98
|
+
Start up container name / Id
|
99
|
+
|
100
|
+
-p --stop
|
101
|
+
Stop container name / Id
|
102
|
+
]
|
103
|
+
puts helper
|
104
|
+
exit
|
105
|
+
when '--bookmarks'
|
106
|
+
bookmarks("#{BOOKMARKSFILE}")
|
107
|
+
when '--url'
|
108
|
+
@dockerurl = arg
|
109
|
+
when '--start'
|
110
|
+
@action = "start"
|
111
|
+
@container = arg
|
112
|
+
when '--stop'
|
113
|
+
@action = "stop"
|
114
|
+
@container = arg
|
115
|
+
when '--create'
|
116
|
+
@action = "create"
|
117
|
+
@container = arg
|
118
|
+
when '--contimage'
|
119
|
+
@image = arg
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class Integer
|
124
|
+
|
125
|
+
def to_filesize
|
126
|
+
conv = [ 'B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB' ];
|
127
|
+
scale = 1024;
|
128
|
+
|
129
|
+
ndx=1
|
130
|
+
if( self < 2*(scale**ndx) ) then
|
131
|
+
return "#{(size)}#{conv[ndx-1]}"
|
132
|
+
end
|
133
|
+
size=self.to_f
|
134
|
+
[2,3,4,5,6,7].each do |ndx|
|
135
|
+
if( size < 2*(scale**ndx) ) then
|
136
|
+
return "#{'%.3f' % (size/(scale**(ndx-1)))}#{conv[ndx-1]}"
|
137
|
+
end
|
138
|
+
end
|
139
|
+
ndx=7
|
140
|
+
return "#{'%.3f' % (size/(scale**(ndx-1)))}#{conv[ndx-1]}"
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
# Client
|
146
|
+
|
147
|
+
if argvstore.size > 0
|
148
|
+
obj = FishControl.new
|
149
|
+
if defined? @action
|
150
|
+
if @image
|
151
|
+
obj.containerctl(@container, @action, @image)
|
152
|
+
else
|
153
|
+
obj.containerctl(@container, @action)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
elsif argvstore.size == 0
|
157
|
+
obj = DockerFish.new(true)
|
158
|
+
if defined? @dockerurl; obj.baseurl = @dockerurl; end
|
159
|
+
if defined? @bookmarkhost; obj.baseurl = @bookmarkhost; end
|
160
|
+
obj.apicall("menu")
|
161
|
+
end
|
data/lib/dockerfish.rb
ADDED
@@ -0,0 +1,584 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
########################################################################
|
4
|
+
# #
|
5
|
+
# Author: Brian Hood #
|
6
|
+
# Description: DockerFish Automation #
|
7
|
+
# #
|
8
|
+
# #
|
9
|
+
########################################################################
|
10
|
+
|
11
|
+
require "net/http"
|
12
|
+
require "uri"
|
13
|
+
require "json"
|
14
|
+
require "pp"
|
15
|
+
require "readline"
|
16
|
+
require 'getoptlong'
|
17
|
+
|
18
|
+
BOOKMARKSFILE = ".bookmarks"
|
19
|
+
VERSION = 0.1
|
20
|
+
|
21
|
+
=begin
|
22
|
+
|
23
|
+
Bri's TODO list
|
24
|
+
|
25
|
+
TODO: Add Export image
|
26
|
+
TODO: Fix multiple container start
|
27
|
+
TODO: Add Pull of image from Repository
|
28
|
+
TODO: Download progress bar for images
|
29
|
+
TODO: Refactor code duplication / case statement
|
30
|
+
TODO: Websocket attach with Eventmachine / Readline
|
31
|
+
|
32
|
+
=end
|
33
|
+
|
34
|
+
class DockerFish
|
35
|
+
|
36
|
+
attr_accessor :baseurl
|
37
|
+
attr_writer :image, :hostname
|
38
|
+
|
39
|
+
def initialize(splash)
|
40
|
+
@baseurl = "http://localhost:2375"
|
41
|
+
@containerjson = "container.json"
|
42
|
+
if splash == true; banner; end
|
43
|
+
end
|
44
|
+
|
45
|
+
def banner
|
46
|
+
puts "Welcome to DockerFish Version #{VERSION}"
|
47
|
+
puts "---------------------------------"
|
48
|
+
puts "Interactive CLI Docker Interface"
|
49
|
+
print "\[\e[1;31m\] |
|
50
|
+
|
|
51
|
+
,|.
|
52
|
+
,\|/.
|
53
|
+
,' .V. `.
|
54
|
+
/ . . \
|
55
|
+
/_` '_\
|
56
|
+
,' .: ;, `.
|
57
|
+
|@)| . . |(@|
|
58
|
+
,-._ `._'; . :`_,' _,-.
|
59
|
+
'-- `-\ /,-===-.\ /-' --`
|
60
|
+
(---- _| ||___|| |_ ----)
|
61
|
+
`._,-' \ `-.-' / `-._,'
|
62
|
+
`-.___,-' ap\[\e[0m\]\n"
|
63
|
+
puts ""
|
64
|
+
puts "TIPS: Please note ContainerId's / Names are interchangeable"
|
65
|
+
puts "You can also use short ContainerId's as long as there is a unique match"
|
66
|
+
puts "Start with Docker API Enabled: /usr/bin/docker --api-enable-cors=true -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -d"
|
67
|
+
puts "Add a symlink ln -s /home/brian/Projects/DockerFish/dockerfish.rb /usr/bin/dockerfish\n\n"
|
68
|
+
puts "Container Config file: #{Dir.home}/.dockerfish/#{@containerjson}\n\n"
|
69
|
+
if File.exists?("#{Dir.home}/.dockerfish/#{@containerjson}") == false
|
70
|
+
puts "\e[1;31m\WARNING: \e[0m\ \e[1;32m\ To Create Containers \e[1;33m\ mkdir #{Dir.home}/.dockerfish\e[0m\ \e[1;32m\ and copy the provided container.json into it !!!\e[0m\ \n\n"
|
71
|
+
end
|
72
|
+
puts "--help # For more information"
|
73
|
+
puts "\n"
|
74
|
+
puts "Enjoy!"
|
75
|
+
puts "\n"
|
76
|
+
puts "Coded by Brian Hood"
|
77
|
+
version
|
78
|
+
end
|
79
|
+
|
80
|
+
def apiget(url)
|
81
|
+
uri = URI.parse("#{url}")
|
82
|
+
#puts "Request URI: #{url}"
|
83
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
84
|
+
begin
|
85
|
+
response = http.request(Net::HTTP::Get.new(uri.request_uri))
|
86
|
+
rescue
|
87
|
+
puts "Error retrieving data"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def apipost(url, body="")
|
92
|
+
uri = URI.parse("#{url}")
|
93
|
+
#puts "Request URI: #{url}"
|
94
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
95
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
96
|
+
request.set_content_type("application/json")
|
97
|
+
begin
|
98
|
+
request.body = body unless body.empty?
|
99
|
+
response = http.request(request)
|
100
|
+
rescue
|
101
|
+
puts "Error posting data"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def apidelete(url)
|
106
|
+
uri = URI.parse("#{url}")
|
107
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
108
|
+
begin
|
109
|
+
response = http.request(Net::HTTP::Delete.new(uri.request_uri))
|
110
|
+
rescue
|
111
|
+
puts "Error posting data"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def version
|
116
|
+
@url = "#{@baseurl}/version"
|
117
|
+
uri = URI.parse("#{@url}")
|
118
|
+
begin
|
119
|
+
response = apiget("#{@url}")
|
120
|
+
puts "Server Info:\n\n"
|
121
|
+
j = JSON.parse(response.body)
|
122
|
+
pp j
|
123
|
+
rescue JSON::ParserError, NoMethodError
|
124
|
+
puts "Could not read JSON data"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def chooser(opts)
|
129
|
+
@url = "#{@baseurl}#{opts}"
|
130
|
+
end
|
131
|
+
|
132
|
+
def apicall(action)
|
133
|
+
|
134
|
+
case action
|
135
|
+
when action = "images"
|
136
|
+
response = apiget("#{@url}")
|
137
|
+
begin
|
138
|
+
j = JSON.parse(response.body)
|
139
|
+
rescue JSON::ParserError
|
140
|
+
puts "Could not read JSON data"
|
141
|
+
end
|
142
|
+
puts "\e[1;30mList of Docker Images\e[0m\ "
|
143
|
+
puts "\e[1;30m=====================\e[0m\ "
|
144
|
+
puts ""
|
145
|
+
0.upto(j.length - 1) {|n|
|
146
|
+
j[n].each {|s|
|
147
|
+
case s[0]
|
148
|
+
when "Created"
|
149
|
+
ftime = Time.at(s[1]).to_s
|
150
|
+
ctime = ftime[0..18]
|
151
|
+
created = "#{s[0]}: #{ctime} "
|
152
|
+
when "Id"
|
153
|
+
parentid = "#{s[0]}: #{s[1]} "
|
154
|
+
imageid = parentid[0..21]
|
155
|
+
when "RepoTags"
|
156
|
+
repotags = "#{s[0]}: #{s[1]} ".gsub("RepoTags", "Image")
|
157
|
+
when "Size"
|
158
|
+
num = s[1].to_i.to_filesize
|
159
|
+
size = "#{s[0]}: #{num} "
|
160
|
+
when "VirtualSize"
|
161
|
+
num = s[1].to_i.to_filesize
|
162
|
+
virtualsize = "#{s[0]}: #{num} "
|
163
|
+
end
|
164
|
+
print "#{created} #{imageid} #{repotags} #{size} #{virtualsize}"
|
165
|
+
}
|
166
|
+
print "\n"
|
167
|
+
}
|
168
|
+
when action = "containers"
|
169
|
+
response = apiget("#{@url}")
|
170
|
+
begin
|
171
|
+
j = JSON.parse(response.body)
|
172
|
+
rescue JSON::ParserError
|
173
|
+
puts "Could not read JSON data"
|
174
|
+
end
|
175
|
+
puts "\e[1;30mList of Docker Containers\e[0m\ "
|
176
|
+
puts "\e[1;30m=========================\e[0m\ "
|
177
|
+
puts ""
|
178
|
+
#puts j.length
|
179
|
+
0.upto(j.length - 1) {|n|
|
180
|
+
j[n].each {|s|
|
181
|
+
case s[0]
|
182
|
+
when "Command"
|
183
|
+
cmd = "#{s[0]}: #{s[1]}".strip
|
184
|
+
when "Id"
|
185
|
+
id = "#{s[0]}: #{s[1]} "
|
186
|
+
cointainerid = id[0..15].gsub("Id", "ContainerId").strip
|
187
|
+
when "Image"
|
188
|
+
image = "#{s[0]}: #{s[1]}"
|
189
|
+
when "Names"
|
190
|
+
names = "#{s[0]}: #{s[1]}".strip
|
191
|
+
when "Status"
|
192
|
+
status = "#{s[0]}: #{s[1]}"
|
193
|
+
when "Created"
|
194
|
+
ftime = Time.at(s[1]).to_s
|
195
|
+
ctime = ftime[0..18]
|
196
|
+
created = "#{s[0]}: #{ctime} ".strip
|
197
|
+
end
|
198
|
+
print "#{names} #{cointainerid} #{image} #{cmd} #{status}".gsub(" Command:", "Command:")
|
199
|
+
#pp s
|
200
|
+
}
|
201
|
+
print "\n"
|
202
|
+
}
|
203
|
+
#pp j
|
204
|
+
when action = "start"
|
205
|
+
response = apipost("#{@url}")
|
206
|
+
if response.code == "204"
|
207
|
+
puts "\e[1;30mStart Successfull\e[0m\ "
|
208
|
+
elsif response.code == "304"
|
209
|
+
puts "\e[1;30mContainer already started\e[0m\ "
|
210
|
+
elsif response.code == "404"
|
211
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
212
|
+
elsif response.code == "500"
|
213
|
+
puts "\e[1;30mServer error\e[0m\ "
|
214
|
+
end
|
215
|
+
when action = "pause"
|
216
|
+
response = apipost("#{@url}")
|
217
|
+
if response.code == "204"
|
218
|
+
puts "\e[1;30mPaused Successfull\e[0m\ "
|
219
|
+
elsif response.code == "404"
|
220
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
221
|
+
elsif response.code == "500"
|
222
|
+
puts "\e[1;30mServer error\e[0m\ "
|
223
|
+
end
|
224
|
+
when action = "unpause"
|
225
|
+
response = apipost("#{@url}")
|
226
|
+
if response.code == "204"
|
227
|
+
puts "\e[1;30mResumed Successfull\e[0m\ "
|
228
|
+
elsif response.code == "404"
|
229
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
230
|
+
elsif response.code == "500"
|
231
|
+
puts "\e[1;30mServer error\e[0m\ "
|
232
|
+
end
|
233
|
+
when action = "rename"
|
234
|
+
response = apipost("#{@url}")
|
235
|
+
if response.code == "204"
|
236
|
+
puts "\e[1;30mRenamed Successfully\e[0m\ "
|
237
|
+
elsif response.code == "404"
|
238
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
239
|
+
elsif response.code == "409"
|
240
|
+
puts "\e[1;30mName conflict with another container\e[0m\ "
|
241
|
+
elsif response.code == "500"
|
242
|
+
puts "\e[1;30mServer error\e[0m\ "
|
243
|
+
end
|
244
|
+
when action = "stop"
|
245
|
+
response = apipost("#{@url}")
|
246
|
+
if response.code == "204"
|
247
|
+
puts "\e[1;30mStopped Successfully\e[0m\ "
|
248
|
+
elsif response.code == "304"
|
249
|
+
puts "\e[1;30mContainer already stopped\e[0m\ "
|
250
|
+
elsif response.code == "404"
|
251
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
252
|
+
elsif response.code == "500"
|
253
|
+
puts "\e[1;30mServer error\e[0m\ "
|
254
|
+
end
|
255
|
+
when action = "inspect"
|
256
|
+
response = apiget("#{@url}")
|
257
|
+
begin
|
258
|
+
j = JSON.parse(response.body)
|
259
|
+
rescue JSON::ParserError
|
260
|
+
puts "Could not read JSON data"
|
261
|
+
end
|
262
|
+
pp j
|
263
|
+
when action = "remove"
|
264
|
+
response = apidelete("#{@url}")
|
265
|
+
if response.code == "204"
|
266
|
+
puts "\e[1;30mRemoved Successfully\e[0m\ "
|
267
|
+
elsif response.code == "400"
|
268
|
+
puts "\e[1;30mBad parameter\e[0m\ "
|
269
|
+
elsif response.code == "404"
|
270
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
271
|
+
elsif response.code == "500"
|
272
|
+
puts "\e[1;30mServer error\e[0m\ "
|
273
|
+
end
|
274
|
+
when action = "imageremove"
|
275
|
+
response = apidelete("#{@url}")
|
276
|
+
if response.code == "200"
|
277
|
+
puts "\e[1;30mRemoved Successfully\e[0m\ "
|
278
|
+
elsif response.code == "404"
|
279
|
+
puts "\e[1;30mNo such image\e[0m\ "
|
280
|
+
elsif response.code == "409"
|
281
|
+
puts "\e[1;30mConflict removing image\e[0m\ "
|
282
|
+
elsif response.code == "500"
|
283
|
+
puts "\e[1;30mServer error\e[0m\ "
|
284
|
+
end
|
285
|
+
when action = "imagecommit"
|
286
|
+
response = apipost("#{@url}")
|
287
|
+
if response.code == "201"
|
288
|
+
puts "\e[1;30mImage Commit Successfull\e[0m\ "
|
289
|
+
elsif response.code == "404"
|
290
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
291
|
+
elsif response.code == "500"
|
292
|
+
puts "\e[1;30mServer error\e[0m\ "
|
293
|
+
end
|
294
|
+
when action = "create"
|
295
|
+
body = String.new
|
296
|
+
File.open("#{Dir.home}/.dockerfish/#{@containerjson}", 'r') {|n|
|
297
|
+
n.each_line {|l|
|
298
|
+
body << l
|
299
|
+
}
|
300
|
+
}
|
301
|
+
body.gsub!("##hostname##", @hostname)
|
302
|
+
body.gsub!("##image##", @image)
|
303
|
+
puts body
|
304
|
+
if !defined? @name; @name = @hostname; end
|
305
|
+
response = apipost("#{@url}?name=#{@name}", body)
|
306
|
+
if response.code == "201"
|
307
|
+
puts "\e[1;30mContainer Creation Successfull\e[0m\ "
|
308
|
+
j = JSON.parse(response.body)
|
309
|
+
n = 0
|
310
|
+
0.upto(j.length - 1) {|n|
|
311
|
+
j[n].each {|s|
|
312
|
+
puts "#{s[0]}: #{s[1]}"
|
313
|
+
}
|
314
|
+
print "\n"
|
315
|
+
}
|
316
|
+
elsif response.code == "404"
|
317
|
+
puts "\e[1;30mNo such container\e[0m\ "
|
318
|
+
elsif response.code == "406"
|
319
|
+
puts "\e[1;30mImposible to attach\e[0m\ "
|
320
|
+
elsif response.code == "500"
|
321
|
+
puts "\e[1;30mServer error\e[0m\ "
|
322
|
+
end
|
323
|
+
when action = "imagehistory"
|
324
|
+
response = apiget("#{@url}")
|
325
|
+
begin
|
326
|
+
j = JSON.parse(response.body)
|
327
|
+
rescue JSON::ParserError
|
328
|
+
puts "Could not read JSON data"
|
329
|
+
end
|
330
|
+
puts "\e[1;30mImage history\e[0m\ "
|
331
|
+
puts "\e[1;30m=================\e[0m\ "
|
332
|
+
puts ""
|
333
|
+
#puts j.length
|
334
|
+
0.upto(j.length - 1) {|n|
|
335
|
+
j[n].each {|s|
|
336
|
+
case s[0]
|
337
|
+
when "Id"
|
338
|
+
id = "#{s[0]}: #{s[1]} "
|
339
|
+
cointainerid = id[0..15].strip
|
340
|
+
when "Created"
|
341
|
+
ftime = Time.at(s[1]).to_s
|
342
|
+
ctime = ftime[0..18]
|
343
|
+
created = "#{s[0]}: #{ctime} ".strip
|
344
|
+
when "CreatedBy"
|
345
|
+
createdby = "#{s[0]}: #{s[1]}"
|
346
|
+
end
|
347
|
+
print "#{id} #{created} #{createdby}"
|
348
|
+
#pp s
|
349
|
+
}
|
350
|
+
print "\n"
|
351
|
+
}
|
352
|
+
if response.code == "404"
|
353
|
+
puts "\e[1;30mNo such image\e[0m\ "
|
354
|
+
elsif response.code == "500"
|
355
|
+
puts "\e[1;30mServer error\e[0m\ "
|
356
|
+
end
|
357
|
+
when action = "containerprocs"
|
358
|
+
response = apiget("#{@url}")
|
359
|
+
begin
|
360
|
+
j = JSON.parse(response.body)
|
361
|
+
rescue JSON::ParserError
|
362
|
+
puts "Could not read JSON data"
|
363
|
+
end
|
364
|
+
pp j
|
365
|
+
when action = "search"
|
366
|
+
response = apiget("#{@url}")
|
367
|
+
begin
|
368
|
+
j = JSON.parse(response.body)
|
369
|
+
rescue JSON::ParserError
|
370
|
+
puts "Could not read JSON data"
|
371
|
+
end
|
372
|
+
puts "\e[1;30mSearch Results\e[0m\ "
|
373
|
+
puts "\e[1;30m==============\e[0m\ "
|
374
|
+
puts ""
|
375
|
+
#puts j.length
|
376
|
+
0.upto(j.length - 1) {|n|
|
377
|
+
j[n].each {|s|
|
378
|
+
case s[0]
|
379
|
+
when "description"
|
380
|
+
description = "#{s[0]}: #{s[1]} "
|
381
|
+
when "is_offical"
|
382
|
+
offical = "#{s[0]}: #{s[1]} "
|
383
|
+
when "is_automated"
|
384
|
+
automated = "#{s[0]}: #{s[1]}"
|
385
|
+
when "name"
|
386
|
+
name = "Image: \e[1;36m\ [\"#{s[1]}\"] \e[0m\ "
|
387
|
+
when "star_count"
|
388
|
+
starcount = "Star rating: #{s[1]}"
|
389
|
+
end
|
390
|
+
print "#{name} #{starcount}".lstrip
|
391
|
+
#pp s
|
392
|
+
}
|
393
|
+
print "\n"
|
394
|
+
}
|
395
|
+
if response.code == "500"
|
396
|
+
puts "\e[1;30mServer error\e[0m\ "
|
397
|
+
end
|
398
|
+
when action = "menu"
|
399
|
+
while buf = Readline.readline("\e[1;32m\DockerFish>\e[0m\ ", true)
|
400
|
+
begin
|
401
|
+
puts "\n"
|
402
|
+
puts "\e[1;38m|Our items in the boat yard|\e[0m\ \n"
|
403
|
+
puts "\e[1;38m\\==========================/\e[0m\ "
|
404
|
+
puts "\n"
|
405
|
+
puts "\e[1;36m1)\e[0m\ List Images"
|
406
|
+
puts "\e[1;36m2)\e[0m\ List Containers"
|
407
|
+
puts "\e[1;36m3)\e[0m\ Start/Restart Container"
|
408
|
+
puts "\e[1;36m4)\e[0m\ Stop Container"
|
409
|
+
puts "\e[1;36m5)\e[0m\ Rename Container"
|
410
|
+
puts "\e[1;36m6)\e[0m\ Create Container from Image"
|
411
|
+
puts "\e[1;36m7)\e[0m\ Remove Container"
|
412
|
+
puts "\e[1;36m8)\e[0m\ Inspect Container"
|
413
|
+
puts "\e[1;36m9)\e[0m\ View Image History"
|
414
|
+
puts "\e[1;36m10)\e[0m\ Search for Images"
|
415
|
+
puts "\e[1;36m11)\e[0m\ List Container processes"
|
416
|
+
puts "\e[1;36m12)\e[0m\ Remove Image"
|
417
|
+
puts "\e[1;36m13)\e[0m\ Pause container"
|
418
|
+
puts "\e[1;36m14)\e[0m\ Resume container"
|
419
|
+
puts "\e[1;36m15)\e[0m\ Create a new image from a container's changes"
|
420
|
+
puts ""
|
421
|
+
puts "m: This menu"
|
422
|
+
puts "b: Bookmarks"
|
423
|
+
puts "q: Exit Dockerfish\n"
|
424
|
+
puts "\n"
|
425
|
+
case buf
|
426
|
+
when "1"
|
427
|
+
chooser("/images/json?all=0")
|
428
|
+
#puts "#{@url}"
|
429
|
+
apicall("images")
|
430
|
+
when "2"
|
431
|
+
chooser("/containers/json?all=1")
|
432
|
+
#puts "#{@url}"
|
433
|
+
apicall("containers")
|
434
|
+
when "3"
|
435
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to Start>\e[0m\ ", true)
|
436
|
+
puts "\e[1;30mStarting Container #{buf2}\e[0m\ "
|
437
|
+
chooser("/containers/#{buf2}/restart")
|
438
|
+
#puts "#{@url}"
|
439
|
+
apicall("start")
|
440
|
+
break
|
441
|
+
end
|
442
|
+
when "4"
|
443
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to Stop>\e[0m\ ", true)
|
444
|
+
puts "\e[1;30mStopping Container #{buf2}\e[0m\ "
|
445
|
+
chooser("/containers/#{buf2}/stop")
|
446
|
+
#puts "#{@url}"
|
447
|
+
apicall("stop")
|
448
|
+
break
|
449
|
+
end
|
450
|
+
when "5"
|
451
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container To Rename>\e[0m\ ", true)
|
452
|
+
while buf3 = Readline.readline("\e[1;33m\Enter new name>\e[0m\ ", true)
|
453
|
+
chooser("/containers/#{buf2}/rename?name=#{buf3}")
|
454
|
+
break
|
455
|
+
end
|
456
|
+
#puts "#{@url}"
|
457
|
+
apicall("rename")
|
458
|
+
break
|
459
|
+
end
|
460
|
+
when "6"
|
461
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Image to use>\e[0m\ ", true)
|
462
|
+
@image = buf2
|
463
|
+
while buf3 = Readline.readline("\e[1;33m\Enter Container name(s)>\e[0m\ ", true)
|
464
|
+
chooser("/containers/create")
|
465
|
+
@hostname = buf3
|
466
|
+
apicall("create")
|
467
|
+
break
|
468
|
+
end
|
469
|
+
break
|
470
|
+
end
|
471
|
+
when "7"
|
472
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to Remove>\e[0m\ ", true)
|
473
|
+
chooser("/containers/#{buf2}")
|
474
|
+
#puts "#{@url}"
|
475
|
+
apicall("remove")
|
476
|
+
break
|
477
|
+
end
|
478
|
+
when "8"
|
479
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to Inspect>\e[0m\ ", true)
|
480
|
+
chooser("/containers/#{buf2}/json")
|
481
|
+
#puts "#{@url}"
|
482
|
+
apicall("inspect")
|
483
|
+
break
|
484
|
+
end
|
485
|
+
when "9"
|
486
|
+
while buf2 = Readline.readline("\e[1;33m\View history of image>\e[0m\ ", true)
|
487
|
+
chooser("/images/#{buf2}/history")
|
488
|
+
#puts "#{@url}"
|
489
|
+
apicall("imagehistory")
|
490
|
+
break
|
491
|
+
end
|
492
|
+
when "10"
|
493
|
+
while buf2 = Readline.readline("\e[1;33m\Search for images>\e[0m\ ", true)
|
494
|
+
chooser("/images/search?term=#{buf2}")
|
495
|
+
#puts "#{@url}"
|
496
|
+
apicall("search")
|
497
|
+
break
|
498
|
+
end
|
499
|
+
when "11"
|
500
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to query>\e[0m\ ", true)
|
501
|
+
chooser("/containers/#{buf2}/top")
|
502
|
+
#puts "#{@url}"
|
503
|
+
apicall("containerprocs")
|
504
|
+
break
|
505
|
+
end
|
506
|
+
when "12"
|
507
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Image to remove>\e[0m\ ", true)
|
508
|
+
chooser("/images/#{buf2}")
|
509
|
+
#puts "#{@url}"
|
510
|
+
apicall("imageremove")
|
511
|
+
break
|
512
|
+
end
|
513
|
+
when "13"
|
514
|
+
while buf2 = Readline.readline("\e[1;33m\Pause Container name / id>\e[0m\ ", true)
|
515
|
+
chooser("/containers/#{buf2}/pause")
|
516
|
+
#puts "#{@url}"
|
517
|
+
apicall("pause")
|
518
|
+
break
|
519
|
+
end
|
520
|
+
when "14"
|
521
|
+
while buf2 = Readline.readline("\e[1;33m\Resume Container name / id>\e[0m\ ", true)
|
522
|
+
chooser("/containers/#{buf2}/unpause")
|
523
|
+
#puts "#{@url}"
|
524
|
+
apicall("pause")
|
525
|
+
break
|
526
|
+
end
|
527
|
+
when "15"
|
528
|
+
while buf2 = Readline.readline("\e[1;33m\Enter Container to Image>\e[0m\ ", true)
|
529
|
+
while buf3 = Readline.readline("\e[1;33m\Enter your commit comment important>\e[0m\ ", true)
|
530
|
+
commentenc = URI.encode(buf3)
|
531
|
+
break
|
532
|
+
end
|
533
|
+
while buf4 = Readline.readline("\e[1;33m\Enter your Repository name>\e[0m\ ", true)
|
534
|
+
chooser("/commit?container=#{buf2}&comment=#{commentenc}&repo=#{buf4}")
|
535
|
+
break
|
536
|
+
end
|
537
|
+
#puts "#{@url}"
|
538
|
+
apicall("imagecommit")
|
539
|
+
break
|
540
|
+
end
|
541
|
+
when "m"
|
542
|
+
apicall("menu")
|
543
|
+
#when "b"
|
544
|
+
# ret = bookmarks("#{BOOKMARKSFILE}")
|
545
|
+
# @baseurl = ret
|
546
|
+
# instance_variable_set("@url", ret)
|
547
|
+
when "q"
|
548
|
+
exit
|
549
|
+
when "f"
|
550
|
+
banner
|
551
|
+
end
|
552
|
+
rescue NoMethodError
|
553
|
+
end
|
554
|
+
end
|
555
|
+
end
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
class FishControl
|
560
|
+
|
561
|
+
def initialize
|
562
|
+
@apiobj = DockerFish.new(false)
|
563
|
+
@containerjson = "container.json"
|
564
|
+
end
|
565
|
+
|
566
|
+
def containerctl(container, action, image="<none>:<none>")
|
567
|
+
if image != "<none>:<none>"
|
568
|
+
@apiobj.image = image
|
569
|
+
puts "My Image: #{image}"
|
570
|
+
end
|
571
|
+
container.split(",").each {|n|
|
572
|
+
@apiobj.hostname = "#{n}"
|
573
|
+
puts "Container: #{n} Action: #{action}"
|
574
|
+
if action == "create"
|
575
|
+
@apiobj.chooser("/containers/#{action}")
|
576
|
+
else
|
577
|
+
@apiobj.chooser("/containers/#{n}/#{action}")
|
578
|
+
end
|
579
|
+
@apiobj.apicall("#{action}")
|
580
|
+
}
|
581
|
+
exit
|
582
|
+
end
|
583
|
+
|
584
|
+
end
|
metadata
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dockerfish
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brian Hood
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A Sysadmin Tool for Docker fans!
|
14
|
+
email: brianh6854@googlemail.com
|
15
|
+
executables:
|
16
|
+
- dockerfish
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/dockerfish
|
21
|
+
- lib/dockerfish.rb
|
22
|
+
homepage: http://rubygems.org/gems/dockerfish
|
23
|
+
licenses:
|
24
|
+
- MIT
|
25
|
+
metadata: {}
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
requirements: []
|
41
|
+
rubyforge_project:
|
42
|
+
rubygems_version: 2.2.2
|
43
|
+
signing_key:
|
44
|
+
specification_version: 4
|
45
|
+
summary: Dockerfish
|
46
|
+
test_files: []
|