dockdev 0.3.5 → 0.3.7

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd58441c3c23468da88cb8dda2167fd2a621c2101683b8f73188f1c577a339bf
4
- data.tar.gz: df62a7f794e385be419c7a0268195bc299e01969e24332642b3e99c0065309cc
3
+ metadata.gz: f10f5e3e749c0edc610864688598f8f02f658bdf46eb9206ef3df56401afda6b
4
+ data.tar.gz: 962af3ef6fab3e4d0f804ce7fb20a99da4729288d8649e93fe6eba24ffe21b8f
5
5
  SHA512:
6
- metadata.gz: fddea10a05a055038ad5f017bda47658d0a935cf446276bd89d410cd8971e09fe0edd3a36eb288a151876aa784a0b81da597e72d9d29eb037a427fe005e5778a
7
- data.tar.gz: cd8266f7605440f2c11aa8d789161a1720b92263367cbbcefdb42196e7e14addb3d8a82dcd6b1f1f72af83a091e75f8eb01ec0a6bca640847f03e153be6f4df8
6
+ metadata.gz: a181e0af91cbb7323ba47e7615fd0c521d89330d440baa0e0a0ecb36b995177e31ab1bf91137e049bea367012f0b6377043f05f860dba210daee7eeeabbae24e
7
+ data.tar.gz: 1d5c2dc52c6e91735e076c3f2221838b0bc0e9060e0f292548ec20d3e4ff15f4db77eb40ea747cc71bfcf195b811fb756cac163db39c6b9066e6e646e659f89a
@@ -0,0 +1,111 @@
1
+
2
+ require 'yaml'
3
+
4
+ require 'tty/prompt'
5
+
6
+ module Dockdev
7
+ module Context
8
+ class DockerCompose
9
+
10
+ def self.init_path(path)
11
+ DockerCompose.new(path)
12
+ end
13
+
14
+ def initialize(path)
15
+ @path = path
16
+ @parsed = false
17
+ @mounts = {}
18
+ @ports = {}
19
+ @pmt = TTY::Prompt.new
20
+ end
21
+
22
+ def is_context?
23
+ not find_docker_compose.empty?
24
+ end
25
+
26
+ def find_docker_compose
27
+ Dir.glob(File.join(@path,"docker-compose.*")).grep(/\.(yml|yaml)$/)
28
+ end
29
+
30
+ def parse_docker_compose
31
+ if not @parsed
32
+ fdc = find_docker_compose
33
+
34
+ begin
35
+ if not fdc.empty?
36
+ load_dc = @pmt.yes?("\n docker-compose file found. Load config? ".magenta)
37
+
38
+ if not load_dc
39
+ @parsed = true
40
+ return [@mounts, @ports]
41
+ end
42
+ end
43
+
44
+ if fdc.length > 1
45
+ @selected = @pmt.multi_select(" Please select docker-compose file(s) to parse for running config : ".magenta) do |mn|
46
+ fdc.each do |f|
47
+ mn.choice File.basename(f), f
48
+ end
49
+ end
50
+ else
51
+ @selected = fdc
52
+ end
53
+
54
+ rescue TTY::Reader::InputInterrupt
55
+ # Ctrl-C is pressed... exit
56
+ exit(-1)
57
+ end
58
+
59
+ @selected.each do |dcf|
60
+ logger.debug " Processing docker-compose : #{dcf}"
61
+ dcc = YAML.load(File.read(dcf))
62
+ dcc.each do |k,v|
63
+ next if k == "version"
64
+ v.each do |kk,vv|
65
+ vv.each do |kkk, vvv|
66
+ if kkk == "volumes"
67
+ vvv.each do |vs|
68
+ logger.debug "Extracting mount point from #{dcf} : #{vs}"
69
+ vvs = vs.split(":")
70
+ @mounts[File.expand_path(vvs[0])] = vvs[1]
71
+ end
72
+ elsif kkk == "ports"
73
+ vvv.each do |vs|
74
+ logger.debug "Extracting ports from #{dcf} : #{vs}"
75
+ ps = vs.split(":")
76
+ @ports[ps[0]] = ps[1]
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ end
84
+
85
+ @parsed = true
86
+ end
87
+
88
+ [@mounts, @ports]
89
+ end
90
+
91
+ def process_mount(opts = {}, &block)
92
+ mounts, _ = parse_docker_compose
93
+ mounts
94
+ end
95
+
96
+ def process_port(opts = {}, &block)
97
+ _, ports = parse_docker_compose
98
+ ports
99
+ end
100
+
101
+ private
102
+ def logger
103
+ Dockdev.logger(:ctx_docker_compose)
104
+ end
105
+
106
+ end
107
+ end
108
+ end
109
+
110
+ Dockdev::Context::ContextManager.instance.register(:docker_compose, Dockdev::Context::DockerCompose)
111
+
@@ -11,6 +11,8 @@ module Dockdev
11
11
 
12
12
  def initialize(path)
13
13
  @path = path
14
+ @mounts = {}
15
+ @ports = {}
14
16
  end
15
17
 
16
18
  def is_context?
@@ -21,9 +23,11 @@ module Dockdev
21
23
  Dir.glob(File.join(@path,"Gemfile"))
22
24
  end
23
25
 
24
- def process_mount(mount_hash, dir_inside_docker = "/opt")
26
+ def process_mount(opts = { dir_inside_docker: "/opt" })
25
27
 
26
- if not mount_hash.nil? and mount_hash.is_a?(Hash)
28
+ if @mounts.empty?
29
+
30
+ dir_inside_docker = opts[:dir_inside_docker]
27
31
 
28
32
  script = ["#!/bin/bash"]
29
33
  #script << "alias be > /dev/null 2>&1 && echo 'alias be=bundle exec' >> ~/.bashrc"
@@ -40,7 +44,7 @@ module Dockdev
40
44
  src = d.source
41
45
  if src.path.to_s != "."
42
46
  pathInsideDocker = File.join(dir_inside_docker, d.name)
43
- mount_hash[src.path.expand_path.to_s] = pathInsideDocker
47
+ @mounts[src.path.expand_path.to_s] = pathInsideDocker
44
48
  script << "bundle config --global local.#{d.name} #{pathInsideDocker}"
45
49
  #res[d.name] = src.path.expand_path.to_s
46
50
  end
@@ -55,7 +59,12 @@ module Dockdev
55
59
 
56
60
  end
57
61
 
58
- mount_hash
62
+ @mounts
63
+
64
+ end
65
+
66
+ def process_port(opts = {})
67
+ @ports
59
68
  end
60
69
 
61
70
  end
@@ -15,12 +15,11 @@ module Dockdev
15
15
  end
16
16
 
17
17
  def get_context(path)
18
- ctx = nil
18
+ ctx = []
19
19
  @ctx.values.each do |v|
20
20
  vv = v.init_path(path)
21
21
  if vv.is_context?
22
- ctx = vv
23
- break
22
+ ctx << vv
24
23
  end
25
24
  end
26
25
  ctx
data/lib/dockdev/image.rb CHANGED
@@ -1,6 +1,10 @@
1
1
 
2
2
  require 'docker/cli'
3
3
 
4
+ require 'securerandom'
5
+
6
+ require_relative 'user_info'
7
+
4
8
  module Dockdev
5
9
  class Image
6
10
  include TR::CondUtils
@@ -20,22 +24,39 @@ module Dockdev
20
24
  end
21
25
 
22
26
  def new_container(cont_name, opts = {})
27
+
23
28
  optss = {
24
29
  interactive: true,
25
30
  tty: true,
26
- container_name: cont_name
31
+ container_name: cont_name,
32
+ match_user: TR::RTUtils.on_linux?
27
33
  }
28
34
  optss.merge!(opts)
35
+
29
36
  @cmd_fact.create_container_from_image(@image_name, optss).run
37
+
30
38
  end
31
39
 
32
40
  def build(dockerfile, opts = {})
41
+
42
+ dockerfilePath = dockerfile
43
+ if is_transfer_user?(opts)
44
+ cont = append_transfer_user_in_dockerfile(dockerfile)
45
+ dockerfilePath = generated_dockerfile
46
+ File.open(dockerfilePath, "w") do |f|
47
+ f.write cont
48
+ end
49
+ end
50
+
33
51
  optss = {
34
52
  context_root: opts[:root],
35
- dockerfile: dockerfile
53
+ dockerfile: dockerfilePath
36
54
  }
37
55
  optss.merge!(opts)
38
56
  @cmd_fact.build_image(@image_name, optss).run
57
+
58
+ FileUtils.rm(generated_dockerfile) if File.exist?(generated_dockerfile) and not is_keep_generated_dockerfile?
59
+
39
60
  end
40
61
 
41
62
  def destroy
@@ -47,5 +68,67 @@ module Dockdev
47
68
  end
48
69
  end
49
70
 
71
+
72
+ private
73
+ def logger
74
+ Dockdev.logger(:dockdev_image)
75
+ end
76
+
77
+ def is_keep_generated_dockerfile?
78
+ v = ENV["DOCKDEV_KEEP_GENERATED_DOCKERFILE"]
79
+ is_empty?(v) ? false : (v.downcase == "true") ? true : false
80
+ end
81
+
82
+ def generated_dockerfile
83
+ "Dockerfile-dockdev"
84
+ end
85
+
86
+ def is_transfer_user?(opts = {})
87
+ if TR::RTUtils.on_linux?
88
+ true
89
+ else
90
+ (opts[:match_user].nil? || not_bool?(opts[:match_user])) ? false : opts[:match_user]
91
+ end
92
+ end
93
+
94
+ def append_transfer_user_in_dockerfile(file)
95
+ if File.exist?(file)
96
+ logger.debug "Append transfer user in dockerfile '#{file}'"
97
+ res = []
98
+ cont = File.read(file)
99
+ indx = cont =~ /CMD/
100
+ if indx != nil
101
+
102
+ res << cont[0...indx]
103
+ res << transfer_user_command
104
+ res << cont[indx..-1]
105
+
106
+ else
107
+
108
+ res << cont
109
+ res << transfer_user_command
110
+
111
+ end
112
+
113
+ res.join
114
+
115
+ else
116
+ ""
117
+ end
118
+ end
119
+
120
+ def transfer_user_command
121
+
122
+ ui = UserInfo.user_info
123
+ gi = UserInfo.group_info
124
+
125
+ res = []
126
+ res << "RUN apt-get update && apt-get install -y sudo"
127
+ res << "RUN groupadd -f -g #{gi[:gid]} #{gi[:group_name]} && useradd -u #{ui[:uid]} -g #{gi[:gid]} -m #{ui[:login]} && usermod -aG sudo #{ui[:login]} && echo '#{ui[:login]} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers"
128
+ res << "USER #{ui[:login]}"
129
+ res.join("\n")
130
+
131
+ end
132
+
50
133
  end
51
134
  end
@@ -0,0 +1,36 @@
1
+
2
+ require 'etc'
3
+
4
+ module Dockdev
5
+ module UserInfo
6
+ include TR::CondUtils
7
+
8
+ def self.user_info(login = nil)
9
+ login = Etc.getlogin if is_empty?(login)
10
+ res = { login: login }
11
+ begin
12
+ res[:uid] = Etc.getpwnam(login).uid
13
+ rescue Exception => ex
14
+ res[:uid] = nil
15
+ end
16
+ res
17
+ end
18
+
19
+ def self.group_info(login = nil)
20
+ login = Etc.getlogin if is_empty?(login)
21
+ res = { }
22
+ begin
23
+ gnm = Etc.getgrnam(login)
24
+ res[:group_name] = gnm.name
25
+ res[:gid] = gnm.gid
26
+ rescue Exception => ex
27
+ p ex
28
+ res[:group_name] = ""
29
+ res[:gid] = nil
30
+ end
31
+ res
32
+ end
33
+
34
+ end
35
+ end
36
+
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dockdev
4
- VERSION = "0.3.5"
4
+ VERSION = "0.3.7"
5
5
  end
data/lib/dockdev.rb CHANGED
@@ -38,22 +38,46 @@ module Dockdev
38
38
  wss = Workspace.new(ws)
39
39
  if img.has_image?
40
40
  mount = { root => File.join("/opt",File.basename(root)) }
41
- if not ctx.nil?
42
- mount = ctx.process_mount(mount)
43
- logger.debug "Mount points by context : #{mount}"
41
+ port = {}
42
+ ctx.each do |cctx|
43
+ mnts = cctx.process_mount(dir_inside_docker: "/opt")
44
+ logger.debug "Mount points by context : #{mnts}"
45
+
46
+ mount.merge!(mnts) if not mnts.empty?
47
+
48
+ prt = cctx.process_port
49
+ port.merge!(prt) if not prt.empty?
50
+
51
+ logger.debug "Ports by context #{cctx} : #{prt}"
44
52
  end
45
53
 
46
- img.new_container(cont.name, command: cmd, mounts: mount)
54
+ param = { command: cmd, mounts: mount }
55
+ param[:ports] = port if not port.empty?
56
+
57
+ img.new_container(cont.name, param)
58
+
47
59
  elsif wss.has_dockerfile?
48
60
  img.build(wss.dockerfile)
49
61
 
50
62
  mount = { root => File.join("/opt",File.basename(root)) }
51
- if not ctx.nil?
52
- mount = ctx.process_mount(mount)
53
- logger.debug "Mount points by context : #{mount}"
63
+ port = {}
64
+ ctx.each do |cctx|
65
+ mnt = cctx.process_mount(dir_inside_docker: "/opt")
66
+ mount.merge!(mnt) if not mnt.empty?
67
+
68
+ logger.debug "Mount points by context #{cctx} : #{mnt}"
69
+
70
+ prt = cctx.process_port
71
+ port.merge!(prt) if not prt.empty?
72
+
73
+ logger.debug "Ports by context #{cctx} : #{prt}"
54
74
  end
55
75
 
56
- img.new_container(cont.name, command: cmd, mounts: mount)
76
+ param = { command: cmd, mounts: mount }
77
+ param[:ports] = port if not port.empty?
78
+
79
+ img.new_container(cont.name, param)
80
+
57
81
  else
58
82
  raise Error, "\n No image and no Dockerfile found to build the image found. Operation aborted. \n\n".red
59
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dockdev
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-12-24 00:00:00.000000000 Z
11
+ date: 2024-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: teLogger
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.1'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pastel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.8'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.8'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: release-gem
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -112,15 +126,17 @@ files:
112
126
  - lib/dockdev.rb
113
127
  - lib/dockdev/container.rb
114
128
  - lib/dockdev/context.rb
129
+ - lib/dockdev/context/docker-compose.rb
115
130
  - lib/dockdev/context/rubygems.rb
116
131
  - lib/dockdev/image.rb
132
+ - lib/dockdev/user_info.rb
117
133
  - lib/dockdev/version.rb
118
134
  - lib/dockdev/workspace.rb
119
135
  - sig/dockdev.rbs
120
136
  homepage: ''
121
137
  licenses: []
122
138
  metadata: {}
123
- post_install_message:
139
+ post_install_message:
124
140
  rdoc_options: []
125
141
  require_paths:
126
142
  - lib
@@ -135,8 +151,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
151
  - !ruby/object:Gem::Version
136
152
  version: '0'
137
153
  requirements: []
138
- rubygems_version: 3.5.1
139
- signing_key:
154
+ rubygems_version: 3.5.3
155
+ signing_key:
140
156
  specification_version: 4
141
157
  summary: ''
142
158
  test_files: []