dockerun 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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