dockerun 0.1.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,107 @@
1
+
2
+
3
+ require 'tty/prompt'
4
+
5
+ require 'docker/cli'
6
+
7
+ require_relative '../config'
8
+
9
+ require_relative '../docker_command_factory_helper'
10
+ require_relative '../cli_prompt'
11
+
12
+ module Dockerun
13
+ module Command
14
+ class ResetImage
15
+ include TTY::Option
16
+ include TR::CondUtils
17
+
18
+ include DockerCommandFactoryHelper
19
+ include CliHelper::CliPrompt
20
+
21
+ usage do
22
+ program "dockerun"
23
+ command "reset-image"
24
+ desc "Delete images (and its containers) and start again"
25
+ end
26
+
27
+ def run(&block)
28
+
29
+ if params[:help]
30
+ print help
31
+ exit(0)
32
+
33
+ else
34
+
35
+ config = ::Dockerun::Config.from_storage
36
+
37
+ if config.isConfigFileAvail?
38
+
39
+ skip = cli.no?("Reset docker image (together with the relative container) ? ")
40
+ if not skip
41
+
42
+ selImg = nil
43
+ if is_empty?(config.image_names)
44
+ STDOUT.puts "No image found"
45
+
46
+ elsif config.image_names.length == 1
47
+ selImg = config.image_names.first
48
+ else
49
+
50
+ selImg = cli.select("Please select which image you want to reset : ") do |m|
51
+ config.image_names.each do |n|
52
+ m.choice n,n
53
+ end
54
+ end
55
+
56
+ end
57
+
58
+ if not selImg.nil?
59
+
60
+ # start from container first
61
+ config.container_names(selImg).each do |cn|
62
+ dcFact.stop_container(cn).run
63
+ dcFact.delete_container(cn).run
64
+ end
65
+
66
+ STDOUT.puts "#{config.container_names(selImg).length} container(s) from image '#{selImg}' deleted"
67
+
68
+ res = dcFact.delete_image(selImg).run
69
+ if not res.failed?
70
+ STDOUT.puts "Image '#{selImg}' successfully deleted."
71
+ config.remove_image(selImg)
72
+ config.to_storage
73
+ STDOUT.puts "Image '#{selImg}' removed from history file"
74
+ else
75
+ STDERR.puts "Image '#{selImg}' deletion failed. Error was : #{res.err_stream}"
76
+ removeFromHist = cli.yes?("Image '#{selImg}' failed. Do you want to remove from the history file?")
77
+ if removeFromHist
78
+ config.remove_image(selImg)
79
+ config.to_storage
80
+ STDOUT.puts "Image '#{selImg}' removed from history file"
81
+ else
82
+ STDOUT.puts "Image '#{selImg}' shall remain in the history file"
83
+ end
84
+ end
85
+
86
+
87
+ end
88
+
89
+ if is_empty?(config.image_names)
90
+ ::Dockerun::Config.remove
91
+ STDOUT.puts "Dockerun workspace config removed"
92
+ end
93
+
94
+ else
95
+ STDOUT.puts "Reset docker image operation aborted"
96
+ end
97
+
98
+ else
99
+ STDOUT.puts "Not a dockerun workspace"
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,135 @@
1
+
2
+ require_relative '../config'
3
+ require_relative '../docker_container_helper'
4
+
5
+ require_relative '../cli_prompt'
6
+ require_relative '../docker_command_factory_helper'
7
+
8
+ require_relative '../docker_image_helper'
9
+
10
+ module Dockerun
11
+ module Command
12
+
13
+ class Run
14
+ include TTY::Option
15
+ include TR::CondUtils
16
+ include CommandHelper::DockerContainerHelper
17
+ include DockerCommandFactoryHelper
18
+ include CommandHelper::DockerImageHelper
19
+
20
+ usage do
21
+ program "dockerun"
22
+ command "run"
23
+ desc "Run docker instance from here"
24
+ end
25
+
26
+ argument :command_for_docker do
27
+ optional
28
+ desc "Command to be passed to docker"
29
+ end
30
+
31
+ def run(&block)
32
+ if params[:help]
33
+ print help
34
+ exit(0)
35
+
36
+ else
37
+
38
+ # find history file
39
+ config = ::Dockerun::Config.from_storage
40
+
41
+ imageName = nil
42
+
43
+ if config.image_names.length == 0
44
+ imageName = nil
45
+ elsif config.image_names.length == 1
46
+ imageName = config.image_names.first
47
+ else
48
+ selImg = cli.select("Please select one of the Docker image options below : ") do |m|
49
+ config.image_names.each do |n|
50
+ m.choice n, n
51
+ end
52
+
53
+ m.choice "New image", :new
54
+ end
55
+
56
+ case selImg
57
+ when :new
58
+ imageName = cli.ask("Please provide a new image name : ", required: true)
59
+ else
60
+ imageName = selImg
61
+ end
62
+ end
63
+
64
+
65
+ imageName = build_image_if_not_exist(imageName) do |ops, val|
66
+ case ops
67
+ when :new_image_name
68
+ cli.ask("Please provide a new image name : ", required: true)
69
+ when :image_exist
70
+ reuse = cli.yes? "Image '#{val}' already exist. Using existing image?"
71
+ # proceed or not , new name
72
+ [reuse, val]
73
+ else
74
+
75
+ end
76
+ end
77
+
78
+ config.add_image(imageName)
79
+
80
+ contNames = config.container_names(imageName)
81
+
82
+ selContName = nil
83
+ if contNames.length == 0
84
+ selContName = nil
85
+ elsif contNames.length == 1
86
+ selContName = contNames.first
87
+ else
88
+ sel = cli.select("Please select one of the container operations below : ") do |m|
89
+ contNames.each do |n|
90
+ m.choice n,n
91
+ end
92
+
93
+ m.choice "New Container", :new
94
+ end
95
+
96
+ case sel
97
+ when :new
98
+
99
+ else
100
+ selContName = sel
101
+ end
102
+ end
103
+
104
+ selContName = run_docker_container(imageName, selContName) do |ops, *args|
105
+ case ops
106
+ when :new_container_name
107
+ cli.ask("Please provide a new container name : ", required: true)
108
+ when :container_name_exist
109
+ cli.yes?("Container name '#{args.first}' already exist. Proceed with existing?")
110
+ when :volume_mapping_required?
111
+ cli.yes?("Is there any volume mapping required? ")
112
+ when :source_prompt
113
+ cli.ask("Directory to share with docker : ", required: true)
114
+ when :destination_prompt
115
+ src = args.first
116
+ srcDir = File.basename(src)
117
+ cli.ask("Directory to show inside docker : ", required: true, value: "/opt/#{srcDir}")
118
+ when :add_mount_to_container
119
+ config.add_mount_to_container(imageName, *args)
120
+ when :add_more_volume_mapping?
121
+ cli.yes?("Add more volume mapping?")
122
+ end
123
+ end
124
+
125
+ config.add_container(imageName, selContName)
126
+
127
+ config.to_storage
128
+
129
+ end
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+ end
@@ -0,0 +1,94 @@
1
+
2
+ require 'tty/prompt'
3
+ require 'docker/cli'
4
+
5
+ require_relative '../config'
6
+ require_relative '../docker_container_helper'
7
+
8
+ require_relative '../docker_command_factory_helper'
9
+ require_relative '../cli_prompt'
10
+
11
+ module Dockerun
12
+ module Command
13
+ class RunNewContainer
14
+ include TTY::Option
15
+ include TR::CondUtils
16
+ include CommandHelper::DockerContainerHelper
17
+
18
+ include DockerCommandFactoryHelper
19
+ include CliHelper::CliPrompt
20
+
21
+
22
+ usage do
23
+ program "dockerun"
24
+ command "run-new-container"
25
+ desc "Run new container from same image"
26
+ end
27
+
28
+ def run
29
+
30
+ if params[:help]
31
+ print help
32
+ exit(0)
33
+
34
+ else
35
+
36
+ config = ::Dockerun::Config.from_storage
37
+
38
+ imageName = nil
39
+ if is_empty?(config.image_names)
40
+ STDERR.puts "Image name not availab eyet"
41
+ exit(1)
42
+ elsif config.image_names == 1
43
+ imageName = config.image_names.first
44
+ else
45
+ imageName = cli.select("Please select the new container shall be based on which image : ") do |m|
46
+ config.image_names.each do |n|
47
+ m.choice n,n
48
+ end
49
+ end
50
+ end
51
+
52
+ contName = run_docker_container(imageName, nil) do |ops, *args|
53
+ case ops
54
+ when :new_container_name
55
+ cli.ask("Please provide a new container name : ", required: true)
56
+ when :container_name_exist
57
+ cli.yes?("Container name '#{args.first}' already exist. Proceed with existing?")
58
+ when :volume_mapping_required?
59
+ cli.yes?("Is there any volume mapping required? ")
60
+ when :source_prompt
61
+ cli.ask("Directory to share with docker : ", required: true)
62
+ when :destination_prompt
63
+ src = args.first
64
+ srcDir = File.basename(src)
65
+ cli.ask("Directory to show inside docker : ", required: true, value: "/opt/#{srcDir}")
66
+ when :add_mount_to_container
67
+ config.add_mount_to_container(imageName, *args)
68
+ when :add_more_volume_mapping?
69
+ cli.yes?("Add more volume mapping?")
70
+ end
71
+ end
72
+
73
+ #contName = nil
74
+ #loop do
75
+ # contName = cli.ask("Please provide a new container name : ", required: true)
76
+ # res = dcFact.find_from_all_container(contName).run
77
+ # if not res[:result].failed? and not_empty?(res[:outStream])
78
+ # STDERR.puts "Given container name '#{contName}' already taken. Please try again"
79
+ # else
80
+ # break
81
+ # end
82
+ #end
83
+
84
+ #create_new_docker_container(config, contName, dcFact. cli)
85
+ config.add_container(imageName, contName)
86
+ config.to_storage
87
+
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,89 @@
1
+
2
+ require_relative '../config'
3
+ require_relative '../docker_container_helper'
4
+
5
+ require_relative '../cli_prompt'
6
+ require_relative '../docker_command_factory_helper'
7
+
8
+ require_relative '../docker_image_helper'
9
+
10
+ module Dockerun
11
+ module Command
12
+
13
+ class RunNewImage
14
+ include TTY::Option
15
+ include TR::CondUtils
16
+ include CommandHelper::DockerContainerHelper
17
+ include DockerCommandFactoryHelper
18
+ include CommandHelper::DockerImageHelper
19
+
20
+ usage do
21
+ program "dockerun"
22
+ command "run-new-image"
23
+ desc "Run with new image"
24
+ end
25
+
26
+ argument :command_for_docker do
27
+ optional
28
+ desc "Command to be passed to docker"
29
+ end
30
+
31
+ def run(&block)
32
+ if params[:help]
33
+ print help
34
+ exit(0)
35
+
36
+ else
37
+
38
+ # find history file
39
+ config = ::Dockerun::Config.from_storage
40
+
41
+ imageName = build_image_if_not_exist(imageName) do |ops, val|
42
+ case ops
43
+ when :new_image_name
44
+ cli.ask("Please provide a new image name : ", required: true)
45
+ when :image_exist
46
+ reuse = cli.yes? "Image '#{val}' already exist. Using existing image?"
47
+ # proceed or not , new name
48
+ [reuse, val]
49
+ else
50
+
51
+ end
52
+ end
53
+
54
+ config.add_image(imageName)
55
+
56
+ contNames = config.container_names(imageName)
57
+
58
+ selContName = run_docker_container(imageName, selContName) do |ops, *args|
59
+ case ops
60
+ when :new_container_name
61
+ cli.ask("Please provide a new container name : ", required: true)
62
+ when :container_name_exist
63
+ cli.yes?("Container name '#{args.first}' already exist. Proceed with existing?")
64
+ when :volume_mapping_required?
65
+ cli.yes?("Is there any volume mapping required? ")
66
+ when :source_prompt
67
+ cli.ask("Directory to share with docker : ", required: true)
68
+ when :destination_prompt
69
+ src = args.first
70
+ srcDir = File.basename(src)
71
+ cli.ask("Directory to show inside docker : ", required: true, value: "/opt/#{srcDir}")
72
+ when :add_mount_to_container
73
+ config.add_mount_to_container(imageName, *args)
74
+ when :add_more_volume_mapping?
75
+ cli.yes?("Add more volume mapping?")
76
+ end
77
+ end
78
+
79
+ config.add_container(imageName, selContName)
80
+
81
+ config.to_storage
82
+
83
+ end
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,97 @@
1
+
2
+ require 'yaml'
3
+
4
+ module Dockerun
5
+ class Config
6
+ include TR::CondUtils
7
+
8
+ FILENAME = ".dockerun".freeze
9
+
10
+ def self.from_storage
11
+ path = File.join(Dir.getwd, FILENAME)
12
+ if File.exist?(path)
13
+ cont = nil
14
+ File.open(path,"r") do |f|
15
+ cont = f.read
16
+ end
17
+
18
+ Config.new(YAML.load(cont), true)
19
+ else
20
+ Config.new({}, false)
21
+ end
22
+ end
23
+
24
+ def self.remove
25
+ path = File.join(Dir.getwd, FILENAME)
26
+ FileUtils.rm(path) if File.exist?(path)
27
+ end
28
+
29
+ def initialize(configHash = { }, configFileAvail = false)
30
+ @config = configHash
31
+ @images = @config[:images]
32
+ @confFileAvail = configFileAvail
33
+ @images = { } if @images.nil?
34
+ end
35
+
36
+ def isConfigFileAvail?
37
+ @confFileAvail
38
+ end
39
+
40
+ def image_names
41
+ @images.keys
42
+ end
43
+
44
+ def add_image(name)
45
+ @images[name] = { } if not_empty?(name) and not @images.keys.include?(name)
46
+ end
47
+
48
+ def remove_image(name)
49
+ @images.delete(name)
50
+ end
51
+
52
+ def container_names(imageName)
53
+ @images[imageName].keys
54
+ end
55
+
56
+ def container_configs(imageName, name)
57
+ @images[imageName].nil? ? {} : @images[imageName][name].nil? ? {} : @images[imageName][name]
58
+ end
59
+
60
+ def add_container(imageName, name)
61
+ @images[imageName] = { } if @images[imageName].nil?
62
+ @images[imageName][name] = {} if @images[imageName][name].nil?
63
+ end
64
+
65
+ def remove_container(imageName, name)
66
+ if not @images[imageName].nil?
67
+ @images[imageName].delete(name)
68
+ end
69
+ end
70
+
71
+ def add_mount_to_container(imageName, container, mount)
72
+ add_container(imageName, container)
73
+ @images[imageName][container][:mount] = [] if @images[imageName][container][:mount].nil?
74
+ @images[imageName][container][:mount] << mount
75
+ end
76
+
77
+ def mount_of_container(container)
78
+ res = @containers[container]
79
+ if is_empty?(res) or is_empty?(res[:mount])
80
+ []
81
+ else
82
+ res[:mount]
83
+ end
84
+ end
85
+
86
+ def to_storage
87
+ res = { images: @images }
88
+
89
+ path = File.join(Dir.getwd, FILENAME)
90
+ File.open(path,"w") do |f|
91
+ f.write YAML.dump(res)
92
+ end
93
+ end
94
+ alias_method :save, :to_storage
95
+
96
+ end
97
+ end
@@ -0,0 +1,15 @@
1
+
2
+ require 'docker/cli'
3
+
4
+ module Dockerun
5
+ module DockerCommandFactoryHelper
6
+
7
+ def dcFact
8
+ if @dcFact.nil?
9
+ @dcFact = Docker::Cli::CommandFactory.new
10
+ end
11
+ @dcFact
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,111 @@
1
+
2
+ require_relative 'docker_command_factory_helper'
3
+
4
+ module Dockerun
5
+ module CommandHelper
6
+ module DockerContainerHelper
7
+ include DockerCommandFactoryHelper
8
+
9
+ class DockerContainerBuildFailed < StandardError; end
10
+ class DockerContainerStartFailed < StandardError; end
11
+
12
+ def run_docker_container(image_name, container_name, &block)
13
+
14
+ raise DockerContainerBuildFailed, "block is required" if not block
15
+ raise DockerContainerBuildFailed, "Image name is required" if is_empty?(image_name)
16
+
17
+ reuse = nil
18
+
19
+ if is_empty?(container_name)
20
+ container_name = block.call(:new_container_name)
21
+ loop do
22
+ st, _ = is_container_exist?(container_name)
23
+ if st
24
+ reuse = block.call(:container_name_exist, container_name)
25
+ break if reuse
26
+ container_name = block.call(:new_container_name)
27
+ else
28
+ break
29
+ end
30
+ end
31
+
32
+ else
33
+ st, _ = is_container_exist?(container_name)
34
+ if st
35
+ reuse = true
36
+ else
37
+ # if not found shall drop into the next block's else clause
38
+ end
39
+ end
40
+
41
+ if reuse == true
42
+
43
+ res = dcFact.find_running_container(container_name).run
44
+ if not res.failed? and res.is_out_stream_empty?
45
+ # not running
46
+ ress = dcFact.start_container(container_name).run
47
+ raise DockerContainerStartFailed, "Failed to start container '#{container_name}'. Error was : #{ress.err_stream}" if ress.failed?
48
+ end
49
+
50
+ ucmd = cli.ask("Command to be run inside the container. Empty to attach to existing session : ", value: "/bin/bash")
51
+ if is_empty?(ucmd)
52
+ dcFact.attach_container(container_name).run
53
+ else
54
+ dcFact.run_command_in_running_container(container_name, ucmd, tty: true, interactive: true).run
55
+ end
56
+
57
+ else
58
+
59
+ reqVolMap = block.call(:volume_mapping_required?)
60
+ mount = []
61
+ if reqVolMap
62
+
63
+ loop do
64
+
65
+ src = block.call(:source_prompt)
66
+ dest = block.call(:destination_prompt, src)
67
+ mount << { src => dest }
68
+ block.call(:add_mount_to_container, container_name, mount.last)
69
+ repeat = block.call(:add_more_volume_mapping?)
70
+ break if not repeat
71
+
72
+ end
73
+
74
+ end
75
+
76
+ dcFact.create_container_from_image(image_name, interactive: true, tty: true, container_name: container_name, mount: mount).run
77
+
78
+ end
79
+
80
+ container_name
81
+
82
+ end
83
+
84
+ private
85
+ def is_container_exist?(name)
86
+ if not_empty?(name)
87
+ res = dcFact.find_from_all_container(name).run
88
+ raise DockerContainerBuildFailed, "Failed to find container. Error was : #{res.err_stream}" if res.failed?
89
+
90
+ if res.is_out_stream_empty?
91
+ # nothing found
92
+ [false, ""]
93
+ else
94
+ [true, res.out_stream]
95
+ end
96
+ else
97
+ [false, nil]
98
+ end
99
+ end
100
+
101
+ def run_container(name)
102
+
103
+ res = dcFact.start_container(name)
104
+ raise DockerContainerStartFailed, "Failed to start docker container name '#{name}'. Error was : #{res.err_stream}" if res.failed?
105
+
106
+ end
107
+
108
+
109
+ end
110
+ end
111
+ end