dev_dock 0.1.3 → 0.2.0

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: 1bf342db116adc7552aa15815f9e5c72407c2df0ec20b68b5ac07854cc4b90e0
4
- data.tar.gz: b10c63014b4a78b3e3b201004c8ca849e00a64120ab4552bdd4b55d703bb487c
3
+ metadata.gz: 010bb5ac9923609562ed9d55ca2d841832b568916e72779b05610a84842b61f6
4
+ data.tar.gz: 11d8dc854c1e714a9d54e062be1f5d128b04560dac34178fd36fc8d3d9be816f
5
5
  SHA512:
6
- metadata.gz: 254607c4792d77eb9e1efefe9c8eb59a119f24c9c9f54225a6c6cf12b4e13822ef0a6d505fad1c756701afc284cc25f552e2a585673c6bd7ee0abc35aed6a95f
7
- data.tar.gz: a773de32b234716665ade28235ce1a034ba5ceabccce38c95c08477335d58b2616f4da3ea6fba7d79158ff32be405935685c79c5ace863573194ce056dc8e787
6
+ metadata.gz: e39ca6d9855d58bec50f06c696bb9eb2a738e5d99585b1ddfc92fa78bbcacfd24b26385d6f63f3e85e5702713681ffac543881693c3bdf7f97b09f8faad2a5cb
7
+ data.tar.gz: 3467307e94de12974464484fa398f0a57f075bbe06c9cbfdddb804449f01db203c4ec9081b6786fc35ed2ace9bf27371039035946c408c73ab18177a7d37794e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dev_dock (0.1.3)
4
+ dev_dock (0.2.0)
5
5
  docker-api (~> 1.34)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -9,7 +9,11 @@ A command utility to manage containerized development environments.
9
9
 
10
10
  ## Usage
11
11
 
12
- Run `dev_dock --help` for full instructions.
12
+ Spin up a development container with `dev_dock start <container>`, for example:
13
+
14
+ ```bash
15
+ dev_dock start aghost7/nodejs-dev:carbon
16
+ ```
13
17
 
14
18
  ## Development
15
19
 
data/bin/dev_dock CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'dev_dock'
4
+ require 'dev_dock/options'
4
5
 
5
6
  def help(code = 1)
6
7
  helpfile = File.expand_path('../../help.txt', __FILE__)
@@ -12,16 +13,18 @@ if ARGV[0] == "-h" or ARGV[0] == "--help"
12
13
  help(0)
13
14
  end
14
15
 
15
- if ARGV.length != 2
16
- help
17
- end
16
+ options = DevDock::Options.new(ARGV)
17
+ options.parse
18
18
 
19
- subcommand = ARGV.shift
19
+ if options.error
20
+ puts options.error
21
+ help
22
+ end
20
23
 
21
- if subcommand == "start"
22
- DevDock::start ARGV[0]
23
- elsif subcommand == "purge"
24
- DevDock::purge ARGV[0]
24
+ if options.subcommand == "start"
25
+ DevDock::start options
26
+ elsif options.subcommand == "purge"
27
+ DevDock::purge options
25
28
  else
26
29
  help
27
30
  end
data/help.txt CHANGED
@@ -1,10 +1,19 @@
1
- dev_dock <command> <options>
1
+ dev_dock <subcommand> [options...] <image>
2
2
 
3
3
  subcommands:
4
4
 
5
5
  start <image>
6
6
  Start a development session.
7
7
 
8
+ options:
9
+
10
+ -v <Volume Specification>, --volume <Volume Specification>
11
+ Mount a specific volume, uses same syntax as docker's volume option.
12
+
13
+ -e <List>, --env <List>
14
+ Specifies additional environment variables for the container. Syntax
15
+ is identical to docker's.
16
+
8
17
  purge <image>
9
18
  Kill your container and remove all volumes tied to it.
10
19
 
@@ -5,28 +5,29 @@ require 'dev_dock/volumes'
5
5
 
6
6
  module DevDock
7
7
 
8
- class DevContainer
8
+ class DevContainer
9
9
 
10
- def initialize(image_name)
11
- @image = DevDock::DevImage.new(image_name)
12
- @volumes = DevDock::DevVolumes.new(@image)
13
- @name = DevDock::Util::snake_case("dev_dock_#{image_name}")
14
- end
10
+ def initialize(options)
11
+ @options = options
12
+ @image = DevDock::DevImage.new(options.image_name)
13
+ @volumes = DevDock::DevVolumes.new(@image)
14
+ @name = DevDock::Util::snake_case("dev_dock_#{options.image_name}")
15
+ end
15
16
 
16
- def image
17
- @image
18
- end
17
+ def image
18
+ @image
19
+ end
19
20
 
20
- def volumes
21
- @volumes
22
- end
21
+ def volumes
22
+ @volumes
23
+ end
23
24
 
24
25
  def docker_group
25
26
  docker_line = File
26
27
  .read('/etc/group')
27
28
  .lines
28
29
  .find { |line| line.start_with?('docker') }
29
- group = docker_line and docker_line.split(':')[2]
30
+ group = docker_line and docker_line.split(':')[1]
30
31
  if docker_line.nil?
31
32
  group = docker_line
32
33
  else
@@ -36,61 +37,74 @@ module DevDock
36
37
  group
37
38
  end
38
39
 
39
- def exist?
40
- Docker::Container.get(@name)
41
- true
42
- rescue Docker::Error::NotFoundError
43
- false
44
- end
45
-
46
- # kill container
47
- def kill
48
- Docker::Container.get(@name).kill
49
- end
50
-
51
- def enable_x11(arguments)
52
- arguments.push '-v'
53
- arguments.push '/tmp/.X11-unix:/tmp/.X11-unix:ro'
54
- arguments.push '-e'
55
- arguments.push 'DISPLAY'
56
- end
57
-
58
- def run
59
- arguments = [
60
- 'docker',
61
- 'run',
62
- '--privileged',
63
- '--name', @name,
40
+ def exist?
41
+ Docker::Container.get(@name)
42
+ true
43
+ rescue Docker::Error::NotFoundError
44
+ false
45
+ end
46
+
47
+ # kill container
48
+ def kill
49
+ Docker::Container.get(@name).kill
50
+ end
51
+
52
+ def enable_x11(arguments)
53
+ if File.exist? '/tmp/.X11-unix'
54
+ Log::debug('X11 socket file found')
55
+ arguments.push '-v'
56
+ arguments.push '/tmp/.X11-unix:/tmp/.X11-unix:ro'
57
+ arguments.push '-e'
58
+ arguments.push 'DISPLAY'
59
+ else
60
+ Log::debug('Did not find X11 socket file')
61
+ end
62
+ end
63
+
64
+ def run
65
+ arguments = [
66
+ 'docker',
67
+ 'run',
68
+ '--privileged',
69
+ '--name', @name,
64
70
  '--group-add', docker_group,
65
- '--net=host',
66
- '--rm',
67
- '-ti',
68
- '--detach-keys',
69
- 'ctrl-q,ctrl-q',
70
- '-e', 'GH_USER',
71
- '-e', 'GH_PASS',
72
- '-v', '/run/docker.sock:/var/run/docker.sock'
73
- ]
74
-
75
- ['workspaces', '.gitconfig', '.ssh'].each do |directory|
76
- arguments.push '-v', "#{ENV['HOME']}/#{directory}:/home/#{@image.user}/#{directory}"
77
- end
78
-
79
- if RUBY_PLATFORM == "x86_64-linux"
80
- enable_x11(arguments)
81
- arguments.push '-v', '/etc/localhost:/etc/localhost:ro'
82
- end
83
-
84
- @volumes.list.each do |volume|
85
- arguments.push '--mount', "source=#{volume.name},target=#{volume.path}"
86
- end
87
-
88
- arguments.push @image.name
89
-
90
- arguments.push 'tmux'
91
- arguments.push 'new'
92
-
93
- exec *arguments
94
- end
95
- end
71
+ '--net=host',
72
+ '--rm',
73
+ '-ti',
74
+ '--detach-keys',
75
+ 'ctrl-q,ctrl-q',
76
+ '-e', 'GH_USER',
77
+ '-e', 'GH_PASS',
78
+ '-v', '/run/docker.sock:/var/run/docker.sock'
79
+ ]
80
+
81
+ ['workspaces', '.gitconfig', '.ssh'].each do |directory|
82
+ arguments.push '-v', "#{ENV['HOME']}/#{directory}:/home/#{@image.user}/#{directory}"
83
+ end
84
+
85
+ if RUBY_PLATFORM.start_with?("x86_64-linux")
86
+ enable_x11(arguments)
87
+ arguments.push '-v', '/etc/localhost:/etc/localhost:ro'
88
+ end
89
+
90
+ @volumes.list.each do |volume|
91
+ arguments.push '--mount', "source=#{volume.name},target=#{volume.path}"
92
+ end
93
+
94
+ @options.volumes.each do |volume|
95
+ arguments.push '-v', volume
96
+ end
97
+
98
+ @options.environment.each do |environment|
99
+ arguments.push '-e', environment
100
+ end
101
+
102
+ arguments.push @image.name
103
+
104
+ arguments.push 'tmux'
105
+ arguments.push 'new'
106
+
107
+ exec *arguments
108
+ end
109
+ end
96
110
  end
@@ -2,37 +2,37 @@ require 'docker'
2
2
 
3
3
  module DevDock
4
4
 
5
- class DevImage
6
-
7
- def initialize(name)
8
- @name = name
9
- @container_config = nil
10
- end
11
-
12
- def name
13
- @name
14
- end
15
-
16
- def exist?
17
- Docker::Image::exist?(@name)
18
- end
19
-
20
- def pull
21
- # for some reason pulling images isn't part of the api?
22
- `docker pull #{name}`
23
- end
24
-
25
- def container_config
26
- if @container_config.nil?
27
- image = Docker::Image.get(@name)
28
- @container_config = image.json['ContainerConfig']
29
- end
30
- @container_config
31
- end
32
-
33
- def user
34
- return container_config['User']
35
- end
36
-
37
- end
5
+ class DevImage
6
+
7
+ def initialize(image_name)
8
+ @name = image_name
9
+ @container_config = nil
10
+ end
11
+
12
+ def name
13
+ @name
14
+ end
15
+
16
+ def exist?
17
+ Docker::Image::exist?(@name)
18
+ end
19
+
20
+ def pull
21
+ # for some reason pulling images isn't part of the api?
22
+ `docker pull #{@name}`
23
+ end
24
+
25
+ def container_config
26
+ if @container_config.nil?
27
+ image = Docker::Image.get(@name)
28
+ @container_config = image.json['ContainerConfig']
29
+ end
30
+ @container_config
31
+ end
32
+
33
+ def user
34
+ return container_config['User']
35
+ end
36
+
37
+ end
38
38
  end
data/lib/dev_dock/log.rb CHANGED
@@ -1,13 +1,13 @@
1
1
  module DevDock
2
- module Log
3
- def self.info(*stuff)
4
- puts *stuff
5
- end
2
+ module Log
3
+ def self.info(*stuff)
4
+ puts *stuff
5
+ end
6
6
 
7
- def self.debug(*stuff)
8
- if ENV['DEV_DOCK_DEBUG'] == '1'
9
- puts *stuff
10
- end
11
- end
12
- end
7
+ def self.debug(*stuff)
8
+ if ENV['DEV_DOCK_DEBUG'] == '1'
9
+ puts *stuff
10
+ end
11
+ end
12
+ end
13
13
  end
@@ -0,0 +1,83 @@
1
+ module DevDock
2
+
3
+ class Options
4
+
5
+ def initialize(argv)
6
+ @volumes = []
7
+ @environment = []
8
+ @subcommand = nil
9
+ @error = nil
10
+ @argv = argv
11
+ end
12
+
13
+ def parse
14
+ parse_subcommand @argv[0]
15
+ if not @error
16
+ if @subcommand == "start"
17
+ parse_options @argv.slice(1, @argv.length)
18
+ end
19
+ if not @error
20
+ @image_name = @argv.last
21
+ end
22
+ end
23
+ end
24
+
25
+ def parse_subcommand(arg)
26
+ if arg == 'start' or arg == 's'
27
+ @subcommand = 'start'
28
+ elsif arg == 'purge' or arg == 'p'
29
+ @subcommand = 'purge'
30
+ else
31
+ @error = "Invalid subcommand #{arg}"
32
+ end
33
+ end
34
+
35
+ def parse_options(argv)
36
+ i = 0
37
+ while argv[i + 1]
38
+ arg = argv[i]
39
+ if arg == '--volume' or arg == '-v'
40
+ @volumes.push argv[i + 1]
41
+ i += 1
42
+ elsif arg == '--env' or arg == '-e'
43
+ if not argv[i + 2] or not argv[i + 1]
44
+ @error = "Invalid use of option #{arg}"
45
+ break
46
+ else
47
+ @environment.push argv[i + 1]
48
+ i += 1
49
+ end
50
+ else
51
+ @error = "Invalid option: #{arg}"
52
+ break
53
+ end
54
+ i += 1
55
+ end
56
+ end
57
+
58
+ def subcommand
59
+ @subcommand
60
+ end
61
+
62
+ def error
63
+ @error
64
+ end
65
+
66
+ def volumes
67
+ @volumes
68
+ end
69
+
70
+ def image_name
71
+ @image_name
72
+ end
73
+
74
+ def environment
75
+ @environment
76
+ end
77
+
78
+ def inspect
79
+ "Subcommand: #{@subcommand}, Image: #{@image_name}, Volumes: #{volumes}, Environment: "
80
+ end
81
+
82
+ end
83
+ end
data/lib/dev_dock/util.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module DevDock
2
- module Util
3
- def self.snake_case(characters)
4
- characters.downcase.gsub(/\W/, '_')
5
- end
6
- end
2
+ module Util
3
+ def self.snake_case(characters)
4
+ characters.downcase.gsub(/\W/, '_')
5
+ end
6
+ end
7
7
  end
8
8
 
@@ -1,3 +1,3 @@
1
1
  module DevDock
2
- VERSION = "0.1.3"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -7,92 +7,92 @@ require 'dev_dock/log'
7
7
 
8
8
  module DevDock
9
9
 
10
- # Volume which is needed for the development environment
11
- class DevVolume
12
- def initialize(image_name, path)
13
- @path = path
14
- @name = DevDock::Util::snake_case("dev_dock_#{image_name}#{path}")
15
- end
10
+ # Volume which is needed for the development environment
11
+ class DevVolume
12
+ def initialize(image_name, path)
13
+ @path = path
14
+ @name = DevDock::Util::snake_case("dev_dock_#{image_name}#{path}")
15
+ end
16
16
 
17
- def name
18
- @name
19
- end
17
+ def name
18
+ @name
19
+ end
20
20
 
21
- def path
22
- @path
23
- end
21
+ def path
22
+ @path
23
+ end
24
24
 
25
- # returns true if the volume exists
26
- def exist?
27
- volumes = Docker::Util.parse_json(Docker.connection.get('/volumes'))["Volumes"]
28
- Log::debug("Volumes in docker: #{volumes}")
29
- volumes.any? { |volume| volume['Name'] == @name }
30
- end
25
+ # returns true if the volume exists
26
+ def exist?
27
+ volumes = Docker::Util.parse_json(Docker.connection.get('/volumes'))["Volumes"]
28
+ Log::debug("Volumes in docker: #{volumes}")
29
+ volumes.any? { |volume| volume['Name'] == @name }
30
+ end
31
31
 
32
- # creates the volume if it does not exist
33
- def create
34
- Log::debug("Checking volume #{@name} for path #{@path}")
35
- if !exist?
36
- Log::info("Creating volume #{@name}")
37
- Docker::Volume.create(@name)
38
- end
39
- end
32
+ # creates the volume if it does not exist
33
+ def create
34
+ Log::debug("Checking volume #{@name} for path #{@path}")
35
+ if !exist?
36
+ Log::info("Creating volume #{@name}")
37
+ Docker::Volume.create(@name)
38
+ end
39
+ end
40
40
 
41
- # removes the volume if it exists
42
- def remove
43
- Log::debug("Checking volume #{@name} for path #{@path}")
44
- if exist?
45
- Log::info("Removing volume #{@name})")
46
- Docker::Volume.get(@name).remove
47
- end
48
- end
49
- end
41
+ # removes the volume if it exists
42
+ def remove
43
+ Log::debug("Checking volume #{@name} for path #{@path}")
44
+ if exist?
45
+ Log::info("Removing volume #{@name})")
46
+ Docker::Volume.get(@name).remove
47
+ end
48
+ end
49
+ end
50
50
 
51
- # Collection representing volumes needed for then development environment
52
- class DevVolumes
53
- def initialize(image)
54
- @image = image
55
- end
51
+ # Collection representing volumes needed for then development environment
52
+ class DevVolumes
53
+ def initialize(image)
54
+ @image = image
55
+ end
56
56
 
57
- def name
58
- @name
59
- end
57
+ def name
58
+ @name
59
+ end
60
60
 
61
- # returns a list of volumes with their names and paths
62
- def list
63
- if @image.container_config['Volumes'].nil?
64
- []
65
- else
66
- @image.container_config['Volumes'].keys.map do |path|
67
- DevVolume.new(@image.name, path)
68
- end
69
- end
70
- end
61
+ # returns a list of volumes with their names and paths
62
+ def list
63
+ if @image.container_config['Volumes'].nil?
64
+ []
65
+ else
66
+ @image.container_config['Volumes'].keys.map do |path|
67
+ DevVolume.new(@image.name, path)
68
+ end
69
+ end
70
+ end
71
71
 
72
- # returns the volume for the given volume path
73
- def get(path)
74
- if ! @image.container_config['Volumes'].keys.includes? path
75
- nil
76
- else
77
- DevVolume.new(@image.name, path)
78
- end
79
- end
72
+ # returns the volume for the given volume path
73
+ def get(path)
74
+ if ! @image.container_config['Volumes'].keys.includes? path
75
+ nil
76
+ else
77
+ DevVolume.new(@image.name, path)
78
+ end
79
+ end
80
80
 
81
- # creates all desired volumes based on the configuration in the image
82
- def create
83
- Log::debug 'DevVolumes::create'
84
- list.each do |volume|
85
- volume.create
86
- end
87
- end
81
+ # creates all desired volumes based on the configuration in the image
82
+ def create
83
+ Log::debug 'DevVolumes::create'
84
+ list.each do |volume|
85
+ volume.create
86
+ end
87
+ end
88
88
 
89
- # purges all related volumes
90
- def remove
91
- puts 'DevVolumes::remove'
92
- list.each do |volume|
93
- volume.remove
94
- end
95
- end
96
- end
89
+ # purges all related volumes
90
+ def remove
91
+ Log::debug 'DevVolumes::remove'
92
+ list.each do |volume|
93
+ volume.remove
94
+ end
95
+ end
96
+ end
97
97
 
98
98
  end
data/lib/dev_dock.rb CHANGED
@@ -3,24 +3,24 @@ require "dev_dock/log"
3
3
 
4
4
  module DevDock
5
5
 
6
- def self.start(name)
7
- container = DevDock::DevContainer.new(name)
6
+ def self.start(options)
7
+ container = DevDock::DevContainer.new(options)
8
8
 
9
- if not container.image.exist?
10
- Log::info('image does not exist, pulling')
11
- container.image.pull
12
- end
13
- container.volumes.create
9
+ if not container.image.exist?
10
+ Log::info('image does not exist, pulling')
11
+ container.image.pull
12
+ end
13
+ container.volumes.create
14
14
 
15
- container.run
16
- end
15
+ container.run
16
+ end
17
17
 
18
- def self.purge(name)
19
- container = DevDock::DevContainer.new(name)
20
- if container.exist?
21
- container.kill
22
- end
23
- container.volumes.remove
24
- end
18
+ def self.purge(options)
19
+ container = DevDock::DevContainer.new(options)
20
+ if container.exist?
21
+ container.kill
22
+ end
23
+ container.volumes.remove
24
+ end
25
25
 
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dev_dock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - AGhost-7
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-01 00:00:00.000000000 Z
11
+ date: 2018-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -92,6 +92,7 @@ files:
92
92
  - lib/dev_dock/container.rb
93
93
  - lib/dev_dock/image.rb
94
94
  - lib/dev_dock/log.rb
95
+ - lib/dev_dock/options.rb
95
96
  - lib/dev_dock/util.rb
96
97
  - lib/dev_dock/version.rb
97
98
  - lib/dev_dock/volumes.rb