dev_dock 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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