rascal 0.1.0 → 0.3.2

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: 814d874743694d11422907bf02213100735789bb30c4f6a04d5bf57d3a686541
4
- data.tar.gz: 77a43969306a5d45e84a8f7a4e3518604b09989701afc4829188ae6385ef464d
3
+ metadata.gz: cd535de9c0092cf4ab69d5e279e8cb0e19ec682d74e915844a781db8e7e2bb53
4
+ data.tar.gz: ce84b237c9302f56f810a03b3bf95711b279f3a931687d5d29bd21bbb4f325ca
5
5
  SHA512:
6
- metadata.gz: f076c894c0bebe868de8f56764ce47d2bd54ed8052550aa4595c48238515db324f5582f0f0f612976b81e06f99597bd76d303f8b2171ada400b221280c7ca4ae
7
- data.tar.gz: e2ac5cf785f08ab3f1adfafde4c2bd8e6e0a2bb72ebb740b279d584379341915f4e595c5b987a1b8ecb00236cc7f50321e449074c83223cb62a3618ce6d88c7a
6
+ metadata.gz: d2d95fdaf90bab2efc7e3987d142f37653526f30e6026a8a2d056cf85c8bb780b47251d85e8102faac8a0d4b715459c1dcec2d7e5f20d8fb413150778872844d
7
+ data.tar.gz: c5f35334569ea8be40d4f474aef6734c52289f33517dc7c96cbae432a2c02fccbb5bd906c1273ff077ddb21be89dcbd29b3a729c96853f26afb07dea9439e8a0
@@ -12,5 +12,5 @@ notifications:
12
12
  email:
13
13
  - fail@makandra.de
14
14
  install:
15
- - gem install bundler:2.0.1
15
+ - gem install bundler:2.1.4
16
16
  - bundle install --no-deployment --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
@@ -4,6 +4,32 @@ All notable changes to this project will be documented here.
4
4
 
5
5
  Rascal follows semantic versioning. This has little consequence pre 1.0, so expect breaking changes.
6
6
 
7
+ ## 0.3.2 (2020-10-23)
8
+
9
+ - Fix broken `rascal shell` command.
10
+
11
+
12
+ ## 0.3.1 (2020-10-01)
13
+
14
+ - Pass env variables to service containers.
15
+
16
+
17
+ ## 0.3.0 (2020-09-23)
18
+
19
+ - Mount /repo into all service volumes
20
+
21
+
22
+ ## 0.2.1 (2019-04-10)
23
+
24
+ - Prefix names with directory name, to avoid conflicts between projects.
25
+
26
+
27
+ ## 0.2.0 (2019-04-10)
28
+
29
+ - Add `--all` flag for `rascal clean`.
30
+ - Add `rascal update` command.
31
+ - Allow rascal specific per job config.
32
+
7
33
 
8
34
  ## 0.1.0 (2019-03-21)
9
35
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rascal (0.1.0)
4
+ rascal (0.3.2)
5
5
  thor (~> 0.20.3)
6
6
 
7
7
  GEM
@@ -107,4 +107,4 @@ DEPENDENCIES
107
107
  rspec
108
108
 
109
109
  BUNDLED WITH
110
- 2.0.1
110
+ 2.1.4
data/README.md CHANGED
@@ -30,14 +30,18 @@ You need to add some extra information to your `.gitlab-ci.yml`. A working versi
30
30
 
31
31
  ```
32
32
  # settings here override job settings
33
- .rascal:
34
- repo_dir: /repo
35
- variables:
33
+ .rascal: # add rascal specific config here
34
+ repo_dir: /repo # /repo is the default
35
+ variables: # extra env variables
36
36
  BUNDLE_PATH: /cache/bundle
37
- volumes:
38
- cache: /cache
37
+ volumes: # mount these volumes
38
+ cache: /cache # we will always mount a /builds volume
39
39
  before_shell:
40
- - bundle check
40
+ - bundle check # run this when starting a shell
41
+ jobs:
42
+ rspec: # override settings for a specific job
43
+ variables:
44
+ BUNDLE_GEMFILE = /repo/Gemfile
41
45
 
42
46
  .environment: &environment
43
47
  image: registry.makandra.de/makandra/ci-images/test-env:2.5
@@ -53,7 +57,6 @@ You need to add some extra information to your `.gitlab-ci.yml`. A working versi
53
57
  variables:
54
58
  BUNDLE_PATH: ./bundle/vendor
55
59
  DATABASE_URL: postgresql://pg_user@pg-db/test-db
56
- DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: "true"
57
60
  REDIS_URL: redis://redis
58
61
  PROMPT: CI env
59
62
  cache:
@@ -73,6 +76,27 @@ rspec:
73
76
  Then, in your project root, run `rascal shell rspec`.
74
77
 
75
78
 
79
+ ### Commands
80
+
81
+ #### rascal shell <job>
82
+
83
+ Start a docker container (plus required services) and open an interactive shell.
84
+
85
+ Currently requires a "bash" to exist.
86
+
87
+
88
+ #### rascal clean <job> | --all [--volumes]
89
+
90
+ Stop and remove all created containers, services, networks for either the given or all jobs.
91
+
92
+ If `--volumes` is given, also remove all cached volumes.
93
+
94
+
95
+ #### rascal update <job> | --all
96
+
97
+ Update all images for the given job, or all jobs.
98
+
99
+
76
100
  ## License
77
101
 
78
102
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -2,9 +2,10 @@ require 'thor'
2
2
 
3
3
  module Rascal
4
4
  module CLI
5
- autoload :Base, 'rascal/cli/base'
6
- autoload :Clean, 'rascal/cli/clean'
7
- autoload :Main, 'rascal/cli/main'
8
- autoload :Shell, 'rascal/cli/shell'
5
+ autoload :Base, 'rascal/cli/base'
6
+ autoload :Clean, 'rascal/cli/clean'
7
+ autoload :Main, 'rascal/cli/main'
8
+ autoload :Shell, 'rascal/cli/shell'
9
+ autoload :Update, 'rascal/cli/update'
9
10
  end
10
11
  end
@@ -19,19 +19,38 @@ module Rascal
19
19
  end
20
20
 
21
21
  def find_environment(environment_name)
22
- if (definition = EnvironmentsDefinition.detect(config_location))
23
- if (environment = definition.environment(environment_name))
24
- return environment
22
+ definition = environment_definition
23
+ if (environment = definition.environment(environment_name))
24
+ return environment
25
+ else
26
+ available_environments = definition.available_environment_names.join(', ')
27
+ if environment_name
28
+ fail_with_error("Unknown environment #{environment_name}. Available: #{available_environments}.")
25
29
  else
26
- available_environments = definition.available_environment_names.join(', ')
27
- if environment_name
28
- fail_with_error("Unknown environment #{environment_name}. Available: #{available_environments}.")
29
- else
30
- fail_with_error("Missing environment. Available: #{available_environments}.")
31
- end
30
+ fail_with_error("Missing environment. Available: #{available_environments}.")
31
+ end
32
+ end
33
+ end
34
+
35
+ def each_environment(name, &block)
36
+ return enum_for(:each_environment) unless block_given?
37
+
38
+ if name == :all
39
+ definition = environment_definition
40
+ definition.available_environment_names.each do |environment_name|
41
+ yield definition.environment(environment_name)
32
42
  end
43
+ else
44
+ yield find_environment(name)
45
+ end
46
+ end
47
+
48
+ def environment_definition
49
+ if (definition = EnvironmentsDefinition.detect(config_location))
50
+ definition
33
51
  else
34
52
  fail_with_error("Could not find an environment definition in current working directory.")
53
+ nil
35
54
  end
36
55
  end
37
56
  end
@@ -4,12 +4,19 @@ module Rascal
4
4
  module CLI
5
5
  class Clean < Base
6
6
  def initialize(thor, options, environment_name)
7
- @environment_name = environment_name
7
+ @environment_name = if options[:all]
8
+ fail_with_error('Cannot give --all and an environment name!') if environment_name
9
+ :all
10
+ else
11
+ environment_name
12
+ end
8
13
  super(thor, options)
9
14
  end
10
15
 
11
16
  def run
12
- find_environment(@environment_name)&.clean
17
+ each_environment(@environment_name) do |environment|
18
+ environment.clean(clean_volumes: @options[:volumes])
19
+ end
13
20
  end
14
21
  end
15
22
  end
@@ -31,15 +31,37 @@ module Rascal
31
31
  map "shell" => "_shell"
32
32
  desc 'shell ENVIRONMENT', 'Start a docker shell for the given environment'
33
33
  def _shell(environment_name = nil)
34
- Shell.new(self, options, environment_name).run
34
+ handle_error do
35
+ Shell.new(self, options, environment_name).run
36
+ end
35
37
  end
36
38
 
37
39
  desc 'clean ENVIRONMENT', 'Stop and remove docker containers for the given environment'
40
+ method_option :volumes, type: :boolean, default: false, desc: 'Remove (cache) volumes'
41
+ method_option :all, type: :boolean, default: false, desc: 'Clean all environments'
38
42
  def clean(environment_name = nil)
39
- Clean.new(self, options, environment_name).run
43
+ handle_error do
44
+ Clean.new(self, options, environment_name).run
45
+ end
46
+ end
47
+
48
+ desc 'update ENVIRONMENT', 'Update all docker images'
49
+ method_option :all, type: :boolean, default: false, desc: 'update all available environments'
50
+ def update(environment_name = nil)
51
+ handle_error do
52
+ Update.new(self, options, environment_name).run
53
+ end
40
54
  end
41
55
 
42
- class_option :config_file, aliases: ['-c'], default: '.', required: true, banner: 'path to configuration file or directory containing it'
56
+ class_option :config_file, aliases: ['-c'], default: '.', required: true, desc: 'path to configuration file or directory containing it'
57
+
58
+ private
59
+
60
+ def handle_error
61
+ yield
62
+ rescue Rascal::Error => e
63
+ raise Thor::Error, e.message
64
+ end
43
65
  end
44
66
  end
45
67
  end
@@ -0,0 +1,24 @@
1
+ require 'rascal'
2
+
3
+ module Rascal
4
+ module CLI
5
+ class Update < Base
6
+ def initialize(thor, options, environment_name)
7
+ @environment_name = if options[:all]
8
+ fail_with_error('Cannot give --all and an environment name!') if environment_name
9
+ :all
10
+ else
11
+ environment_name
12
+ end
13
+ super(thor, options)
14
+ end
15
+
16
+ def run
17
+ images = []
18
+ each_environment(@environment_name) do |environment|
19
+ images += environment.update(skip: images)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -3,6 +3,8 @@ module Rascal
3
3
  class Container
4
4
  include IOHelper
5
5
 
6
+ attr_reader :image
7
+
6
8
  def initialize(name, image)
7
9
  @name = name
8
10
  @prefixed_name = "#{NAME_PREFIX}#{name}"
@@ -26,7 +28,7 @@ module Rascal
26
28
  'container',
27
29
  'inspect',
28
30
  id,
29
- output: :json
31
+ output: :json,
30
32
  ).first
31
33
  !!container_info.dig('State', 'Running')
32
34
  else
@@ -38,9 +40,9 @@ module Rascal
38
40
  !!id
39
41
  end
40
42
 
41
- def start(network: nil, network_alias: nil)
43
+ def start(network: nil, network_alias: nil, volumes: [], env: {})
42
44
  say "Starting container for #{@name}"
43
- create(network: network, network_alias: network_alias) unless exists?
45
+ create(network: network, network_alias: network_alias, volumes: volumes, env: env) unless exists?
44
46
  Docker.interface.run(
45
47
  'container',
46
48
  'start',
@@ -48,34 +50,65 @@ module Rascal
48
50
  )
49
51
  end
50
52
 
51
- def create(network: nil, network_alias: nil)
53
+ def create(network: nil, network_alias: nil, volumes: [], env: {})
52
54
  @id = Docker.interface.run(
53
55
  'container',
54
56
  'create',
55
57
  '--name', @prefixed_name,
58
+ *(volumes.flat_map { |v| ['-v', v.to_param] }),
59
+ *env_args(env),
56
60
  *(['--network', network.id] if network),
57
61
  *(['--network-alias', network_alias] if network_alias),
58
62
  @image,
59
- output: :id
63
+ output: :id,
60
64
  )
61
65
  end
62
66
 
63
67
  def run_and_attach(*command, env: {}, network: nil, volumes: [], working_dir: nil, allow_failure: false)
64
- Docker.interface.run_and_attach(@image, *command,
65
- env: env,
66
- stdout: stdout,
67
- stderr: stderr,
68
- stdin: stdin,
69
- network: network&.id,
70
- volumes: volumes,
71
- working_dir: working_dir,
72
- allow_failure: allow_failure
68
+ Docker.interface.run_and_attach(
69
+ 'container',
70
+ 'run',
71
+ '--rm',
72
+ '-a', 'STDOUT',
73
+ '-a', 'STDERR',
74
+ '-a', 'STDIN',
75
+ '--interactive',
76
+ '--tty',
77
+ *(['-w', working_dir] if working_dir),
78
+ *(volumes.flat_map { |v| ['-v', v.to_param] }),
79
+ *env_args(env),
80
+ *(['--network', network.id] if network),
81
+ @image,
82
+ *command,
83
+ redirect_io: {
84
+ out: stdout,
85
+ err: stderr,
86
+ in: stdin,
87
+ },
88
+ allow_failure: allow_failure,
73
89
  )
74
90
  end
75
91
 
76
92
  def clean
77
- stop_container if running?
78
- remove_container if exists?
93
+ if running?
94
+ say "Stopping container for #{@name}"
95
+ stop_container
96
+ end
97
+ if exists?
98
+ say "Removing container for #{@name}"
99
+ remove_container
100
+ end
101
+ end
102
+
103
+ def update(skip: [])
104
+ return if skip.include?(@image)
105
+ say "Updating image #{@image}"
106
+ Docker.interface.run(
107
+ 'pull',
108
+ @image,
109
+ stdout: stdout,
110
+ )
111
+ @image
79
112
  end
80
113
 
81
114
  private
@@ -87,7 +120,7 @@ module Rascal
87
120
  '--all',
88
121
  '--quiet',
89
122
  '--filter', "name=^/#{@prefixed_name}$",
90
- output: :id
123
+ output: :id,
91
124
  )
92
125
  end
93
126
 
@@ -116,6 +149,10 @@ module Rascal
116
149
  id,
117
150
  )
118
151
  end
152
+
153
+ def env_args(env)
154
+ env.flat_map { |key, value| ['-e', "#{key}=#{value}"] }
155
+ end
119
156
  end
120
157
  end
121
158
  end
@@ -6,7 +6,7 @@ module Rascal
6
6
  class Interface
7
7
  class Error < Rascal::Error; end
8
8
 
9
- def run(*command, output: :ignore, stdout: nil, redirect_io: {}, allow_failure: false)
9
+ def run(*command, output: :ignore, stdout: nil, allow_failure: false)
10
10
  save_stdout = ''
11
11
  save_stderr = ''
12
12
  exit_status = nil
@@ -22,60 +22,11 @@ module Rascal
22
22
  unless allow_failure || exit_status.success?
23
23
  raise Error, "docker command '#{command.join(' ')}' failed with error:\n#{save_stderr}"
24
24
  end
25
- case output
26
- when :json
27
- begin
28
- JSON.parse(save_stdout)
29
- rescue JSON::ParserError
30
- raise Error, "could not parse output of docker command '#{command.join(' ')}':\n#{save_stdout}"
31
- end
32
- when :id
33
- save_stdout[/[0-9a-f]+/]
34
- when :ignore
35
- nil
36
- else
37
- raise ArgumentError, 'unknown option for :output'
38
- end
25
+ parse_output(output, save_stdout, save_stderr, command: command.join(' '))
39
26
  end
40
27
 
41
- def run_and_attach(image, *command, stdout: nil, stderr: nil, stdin: nil, env: {}, network: nil, volumes: [], working_dir: nil, allow_failure: false)
42
- process_redirections = {}
43
- args = []
44
- if stdout
45
- process_redirections[:out] = stdout
46
- args += ['-a', 'STDOUT']
47
- end
48
- if stderr
49
- process_redirections[:err] = stderr
50
- args += ['-a', 'STDERR']
51
- end
52
- if stdin
53
- process_redirections[:in] = stdin
54
- args += ['-a', 'STDIN', '--interactive', '--tty']
55
- end
56
- if working_dir
57
- args += ['-w', working_dir.to_s]
58
- end
59
- volumes.each do |volume|
60
- args += ['-v', volume.to_param]
61
- end
62
- env.each do |key, value|
63
- args += ['-e', "#{key}=#{value}"]
64
- end
65
- if network
66
- args += ['--network', network.to_s]
67
- end
68
- exit_status = spawn(
69
- env,
70
- 'docker',
71
- 'container',
72
- 'run',
73
- '--rm',
74
- *args,
75
- image.to_s,
76
- *stringify_command(command),
77
- process_redirections,
78
- )
28
+ def run_and_attach(*command, stdout: nil, stderr: nil, stdin: nil, env: {}, network: nil, volumes: [], working_dir: nil, redirect_io: {}, allow_failure: false)
29
+ exit_status = spawn(env, 'docker', *stringify_command(command), redirect_io)
79
30
  unless allow_failure || exit_status.success?
80
31
  raise Error, "docker container run failed"
81
32
  end
@@ -106,6 +57,23 @@ module Rascal
106
57
  rescue IOError
107
58
  end
108
59
  end
60
+
61
+ def parse_output(output, stdout, stderr, command:)
62
+ case output
63
+ when :json
64
+ begin
65
+ JSON.parse(stdout)
66
+ rescue JSON::ParserError
67
+ raise Error, "could not parse output of docker command '#{command}':\n#{stdout}"
68
+ end
69
+ when :id
70
+ stdout[/[0-9a-f]+/]
71
+ when :ignore
72
+ nil
73
+ else
74
+ raise ArgumentError, 'unknown option for :output'
75
+ end
76
+ end
109
77
  end
110
78
  end
111
79
  end
@@ -2,6 +2,7 @@ module Rascal
2
2
  module Docker
3
3
  module Volume
4
4
  class Base
5
+ include IOHelper
5
6
  end
6
7
 
7
8
  class Named < Base
@@ -15,10 +16,23 @@ module Rascal
15
16
  end
16
17
 
17
18
  def clean
19
+ if exists?
20
+ say "Removing volume #{@prefixed_name}"
21
+ Docker.interface.run(
22
+ 'volume',
23
+ 'rm',
24
+ @prefixed_name,
25
+ )
26
+ end
27
+ end
28
+
29
+ def exists?
18
30
  Docker.interface.run(
19
31
  'volume',
20
- 'rm',
21
- @prefixed_name,
32
+ 'ls',
33
+ '--quiet',
34
+ '--filter', "name=^#{@prefixed_name}$",
35
+ output: :id,
22
36
  )
23
37
  end
24
38
  end
@@ -1,22 +1,23 @@
1
1
  module Rascal
2
2
  class Environment
3
- attr_reader :name
3
+ attr_reader :name, :network, :container, :env_variables, :services, :volumes, :working_dir, :before_shell
4
4
 
5
- def initialize(name, image:, env_variables: {}, services: [], volumes: [], before_shell: [], working_dir: nil)
5
+ def initialize(full_name, name:, image:, env_variables: {}, services: [], volumes: [], before_shell: [], after_shell: [], working_dir: nil)
6
6
  @name = name
7
- @network = Docker::Network.new(name)
8
- @container = Docker::Container.new(name, image)
7
+ @network = Docker::Network.new(full_name)
8
+ @container = Docker::Container.new(full_name, image)
9
9
  @env_variables = env_variables
10
10
  @services = services
11
11
  @volumes = volumes
12
12
  @working_dir = working_dir
13
13
  @before_shell = before_shell
14
+ @after_shell = after_shell
14
15
  end
15
16
 
16
17
  def run_shell
17
18
  download_missing
18
19
  start_services
19
- command = [*@before_shell, 'bash'].join(';')
20
+ command = [*@before_shell, 'bash', *@after_shell].join(';')
20
21
  @container.run_and_attach('bash', '-c', command,
21
22
  env: @env_variables,
22
23
  network: @network,
@@ -26,10 +27,17 @@ module Rascal
26
27
  )
27
28
  end
28
29
 
29
- def clean
30
+ def clean(clean_volumes: false)
30
31
  @services.each(&:clean)
31
32
  @network.clean
32
- @volumes.each(&:clean)
33
+ @volumes.each(&:clean) if clean_volumes
34
+ end
35
+
36
+ def update(skip: [])
37
+ [
38
+ *@services.collect { |s| s.update(skip: skip) },
39
+ *@container.update(skip: skip),
40
+ ]
33
41
  end
34
42
 
35
43
  private
@@ -35,7 +35,9 @@ module Rascal
35
35
  def initialize(config_path)
36
36
  @info = parse_definition(config_path.read)
37
37
  @repo_dir = config_path.parent
38
+ @base_name = @repo_dir.basename
38
39
  @rascal_config = @info.fetch('.rascal', {})
40
+ @rascal_environment_config = @rascal_config.delete('jobs') || {}
39
41
  end
40
42
 
41
43
  def environment(name)
@@ -51,21 +53,34 @@ module Rascal
51
53
  private
52
54
 
53
55
  def parse_definition(yaml)
54
- YAML.safe_load(yaml, [], [], true)
56
+ if Psych::VERSION >= '3.1'
57
+ YAML.safe_load(yaml, aliases: true)
58
+ else
59
+ YAML.safe_load(yaml, [], [], true)
60
+ end
55
61
  end
56
62
 
57
63
  def environments
58
64
  @environments ||= begin
59
65
  @info.collect do |key, environment_config|
60
- config = Config.new(deep_merge(environment_config, @rascal_config), key)
61
- docker_repo_dir = config.get('repo_dir')
62
- unless key.start_with?('.')
63
- Environment.new(key,
66
+ config = Config.new(deep_merge(environment_config, @rascal_config, @rascal_environment_config[key] || {}), key)
67
+ docker_repo_dir = config.get('repo_dir', '/repo')
68
+ unless key.start_with?('.') || config.get('hide', false)
69
+ name = config.get('name', key)
70
+ full_name = "#{@base_name}-#{name}"
71
+ shared_volumes = [build_repo_volume(docker_repo_dir), build_builds_volume(full_name)]
72
+ env_variables = (config.get('variables', {}))
73
+ Environment.new(full_name,
74
+ name: name,
64
75
  image: config.get('image'),
65
- env_variables: (config.get('variables', {})),
66
- services: build_services(key, config.get('services', [])),
67
- volumes: [build_repo_volume(docker_repo_dir), *build_volumes(key, config.get('volumes', {}))],
76
+ volumes: [
77
+ *shared_volumes,
78
+ *build_volumes(full_name, config.get('volumes', {}))
79
+ ],
80
+ env_variables: env_variables,
81
+ services: build_services(full_name, config.get('services', []), volumes: shared_volumes, env_variables: env_variables),
68
82
  before_shell: config.get('before_shell', []),
83
+ after_shell: config.get('after_shell', []),
69
84
  working_dir: docker_repo_dir,
70
85
  )
71
86
  end
@@ -73,9 +88,9 @@ module Rascal
73
88
  end
74
89
  end
75
90
 
76
- def deep_merge(hash1, hash2)
91
+ def deep_merge(hash1, hash2, *other)
92
+ result = {}
77
93
  if hash1.is_a?(Hash) && hash2.is_a?(Hash)
78
- result = {}
79
94
  hash1.each do |key1, value1|
80
95
  if hash2.has_key?(key1)
81
96
  result[key1] = deep_merge(value1, hash2[key1])
@@ -86,18 +101,24 @@ module Rascal
86
101
  hash2.each do |key2, value2|
87
102
  result[key2] ||= value2
88
103
  end
89
- result
90
104
  else
91
- hash2
105
+ result = hash2
106
+ end
107
+ if other.any?
108
+ deep_merge(result, *other)
109
+ else
110
+ result
92
111
  end
93
112
  end
94
113
 
95
- def build_services(name, services)
114
+ def build_services(name, services, volumes: [], env_variables: {})
96
115
  services.collect do |service_config|
97
116
  service_alias = service_config['alias']
98
117
  Service.new("#{name}_#{service_alias}",
99
118
  alias_name: service_config['alias'],
100
119
  image: service_config['name'],
120
+ volumes: volumes,
121
+ env_variables: env_variables,
101
122
  )
102
123
  end
103
124
  end
@@ -106,6 +127,10 @@ module Rascal
106
127
  Docker::Volume::Bind.new(@repo_dir, docker_repo_dir)
107
128
  end
108
129
 
130
+ def build_builds_volume(name)
131
+ Docker::Volume::Named.new("#{name}-builds", '/builds')
132
+ end
133
+
109
134
  def build_volumes(name, volume_config)
110
135
  volume_config.collect do |volume_name, docker_path|
111
136
  Docker::Volume::Named.new("#{name}-#{volume_name}", docker_path)
@@ -1,11 +1,13 @@
1
1
  module Rascal
2
2
  class Service
3
- attr_reader :name
3
+ attr_reader :name, :container, :alias, :env_variables
4
4
 
5
- def initialize(name, image:, alias_name:)
5
+ def initialize(name, env_variables: {}, image:, alias_name:, volumes: [])
6
6
  @name = name
7
7
  @container = Docker::Container.new(name, image)
8
8
  @alias = alias_name
9
+ @volumes = volumes
10
+ @env_variables = env_variables
9
11
  end
10
12
 
11
13
  def download_missing
@@ -14,12 +16,16 @@ module Rascal
14
16
 
15
17
  def start_if_stopped(network: nil)
16
18
  unless @container.running?
17
- @container.start(network: network, network_alias: @alias)
19
+ @container.start(network: network, network_alias: @alias, volumes: @volumes, env: @env_variables)
18
20
  end
19
21
  end
20
22
 
21
23
  def clean
22
24
  @container.clean
23
25
  end
26
+
27
+ def update(**args)
28
+ @container.update(**args)
29
+ end
24
30
  end
25
31
  end
@@ -1,3 +1,3 @@
1
1
  module Rascal
2
- VERSION = "0.1.0"
2
+ VERSION = "0.3.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rascal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Kraze
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-21 00:00:00.000000000 Z
11
+ date: 2020-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -56,6 +56,7 @@ files:
56
56
  - lib/rascal/cli/clean.rb
57
57
  - lib/rascal/cli/main.rb
58
58
  - lib/rascal/cli/shell.rb
59
+ - lib/rascal/cli/update.rb
59
60
  - lib/rascal/docker.rb
60
61
  - lib/rascal/docker/container.rb
61
62
  - lib/rascal/docker/interface.rb
@@ -90,7 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
91
  - !ruby/object:Gem::Version
91
92
  version: '0'
92
93
  requirements: []
93
- rubygems_version: 3.0.3
94
+ rubygems_version: 3.1.4
94
95
  signing_key:
95
96
  specification_version: 4
96
97
  summary: Spin up CI environments locally.