config_o_mat 0.1.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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/Gemfile +26 -0
  7. data/Gemfile.lock +56 -0
  8. data/LICENSE +202 -0
  9. data/NOTICE +2 -0
  10. data/README.md +15 -0
  11. data/Rakefile +35 -0
  12. data/bin/config_o_mat-configurator +49 -0
  13. data/bin/config_o_mat-meta_configurator +49 -0
  14. data/config_o_mat.gemspec +49 -0
  15. data/design/configurator_lifecycle_test.dot +91 -0
  16. data/design/original_design.md +45 -0
  17. data/lib/config_o_mat/configurator/cond/first_run.rb +29 -0
  18. data/lib/config_o_mat/configurator/cond/next_state.rb +29 -0
  19. data/lib/config_o_mat/configurator/cond/profiles_to_apply.rb +29 -0
  20. data/lib/config_o_mat/configurator/cond/retries_left.rb +37 -0
  21. data/lib/config_o_mat/configurator/cond/services_to_reload.rb +29 -0
  22. data/lib/config_o_mat/configurator/cond.rb +17 -0
  23. data/lib/config_o_mat/configurator/memory.rb +93 -0
  24. data/lib/config_o_mat/configurator/op/apply_all_profiles.rb +35 -0
  25. data/lib/config_o_mat/configurator/op/commit_staged_profile.rb +35 -0
  26. data/lib/config_o_mat/configurator/op/compile_templates.rb +41 -0
  27. data/lib/config_o_mat/configurator/op/connect_to_appconfig.rb +35 -0
  28. data/lib/config_o_mat/configurator/op/generate_all_templates.rb +66 -0
  29. data/lib/config_o_mat/configurator/op/next_tick.rb +48 -0
  30. data/lib/config_o_mat/configurator/op/notify_systemd_start.rb +29 -0
  31. data/lib/config_o_mat/configurator/op/parse_cli.rb +93 -0
  32. data/lib/config_o_mat/configurator/op/refresh_all_profiles.rb +63 -0
  33. data/lib/config_o_mat/configurator/op/refresh_profile.rb +65 -0
  34. data/lib/config_o_mat/configurator/op/reload_one_service.rb +73 -0
  35. data/lib/config_o_mat/configurator/op/stage_one_profile.rb +33 -0
  36. data/lib/config_o_mat/configurator/op/wait_retry.rb +41 -0
  37. data/lib/config_o_mat/configurator/op.rb +17 -0
  38. data/lib/config_o_mat/configurator.rb +122 -0
  39. data/lib/config_o_mat/flip_flopper/cond/service_status.rb +29 -0
  40. data/lib/config_o_mat/flip_flopper/cond.rb +17 -0
  41. data/lib/config_o_mat/flip_flopper/memory.rb +51 -0
  42. data/lib/config_o_mat/flip_flopper/op/check_service_status.rb +72 -0
  43. data/lib/config_o_mat/flip_flopper/op/determine_running_instance.rb +56 -0
  44. data/lib/config_o_mat/flip_flopper/op/report_failure.rb +36 -0
  45. data/lib/config_o_mat/flip_flopper/op/start_activating_instance.rb +34 -0
  46. data/lib/config_o_mat/flip_flopper/op/stop_activating_instance.rb +34 -0
  47. data/lib/config_o_mat/flip_flopper/op/stop_initial_instance.rb +34 -0
  48. data/lib/config_o_mat/flip_flopper/op.rb +17 -0
  49. data/lib/config_o_mat/flip_flopper.rb +46 -0
  50. data/lib/config_o_mat/meta_configurator/memory.rb +73 -0
  51. data/lib/config_o_mat/meta_configurator/op/generate_systemd_config.rb +80 -0
  52. data/lib/config_o_mat/meta_configurator/op/parse_meta_cli.rb +103 -0
  53. data/lib/config_o_mat/meta_configurator/op.rb +17 -0
  54. data/lib/config_o_mat/meta_configurator.rb +44 -0
  55. data/lib/config_o_mat/shared/cond/early_exit.rb +29 -0
  56. data/lib/config_o_mat/shared/cond.rb +17 -0
  57. data/lib/config_o_mat/shared/op/load_meta_config.rb +188 -0
  58. data/lib/config_o_mat/shared/op.rb +17 -0
  59. data/lib/config_o_mat/shared/systemd_interface.rb +93 -0
  60. data/lib/config_o_mat/shared/types.rb +248 -0
  61. data/lib/config_o_mat/version.rb +19 -0
  62. data/lib/version.rb +19 -0
  63. data/systemd/teak-configurator-restart-service@.path +27 -0
  64. data/systemd/teak-configurator-restart-service@.service +21 -0
  65. data/systemd/teak-configurator-start-service@.path +27 -0
  66. data/systemd/teak-configurator-start-service@.service +21 -0
  67. data/systemd/teak-configurator-stop-service@.path +27 -0
  68. data/systemd/teak-configurator-stop-service@.service +21 -0
  69. data/systemd/teak-configurator.service +68 -0
  70. data/systemd/teak-metaconfigurator.service +57 -0
  71. metadata +213 -0
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/op_base'
18
+
19
+ module ConfigOMat
20
+ module Op
21
+ class StartActivatingInstance < LifecycleVM::OpBase
22
+ reads :service, :activating_instance, :runtime_directory
23
+
24
+ def call
25
+ instance_name = "#{service}#{activating_instance}"
26
+ file_path = File.join(runtime_directory, "#{instance_name}.start")
27
+
28
+ logger&.notice(:service_start, name: instance_name)
29
+
30
+ FileUtils.touch(file_path)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/op_base'
18
+
19
+ module ConfigOMat
20
+ module Op
21
+ class StopActivatingInstance < LifecycleVM::OpBase
22
+ reads :service, :activating_instance, :runtime_directory
23
+
24
+ def call
25
+ instance_name = "#{service}#{activating_instance}"
26
+ file_path = File.join(runtime_directory, "#{instance_name}.stop")
27
+
28
+ logger&.notice(:service_stop, name: instance_name)
29
+
30
+ FileUtils.touch(file_path)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/op_base'
18
+
19
+ module ConfigOMat
20
+ module Op
21
+ class StopInitialInstance < LifecycleVM::OpBase
22
+ reads :service, :running_instance, :runtime_directory
23
+
24
+ def call
25
+ instance_name = "#{service}#{running_instance}"
26
+ file_path = File.join(runtime_directory, "#{instance_name}.stop")
27
+
28
+ logger&.notice(:service_stop, name: instance_name)
29
+
30
+ FileUtils.touch(file_path)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ Dir[File.join(__dir__, 'op', '*')].sort.each { |file| require file }
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm'
18
+
19
+ require 'config_o_mat/flip_flopper/op'
20
+ require 'config_o_mat/flip_flopper/cond'
21
+ require 'config_o_mat/flip_flopper/memory'
22
+
23
+ module ConfigOMat
24
+ module FlipFlopper
25
+ class VM < LifecycleVM::VM
26
+ memory_class ConfigOMat::FlipFlopper::Memory
27
+
28
+ on :start, do: Op::DetermineRunningInstance, then: :start_activating_instance
29
+ on :start_activating_instance, do: Op::StartActivatingInstance, then: :wait_for_service_start
30
+ on :wait_for_service_start, do: Op::CheckServiceStatus, then: {
31
+ case: Cond::ServiceStatus,
32
+ when: {
33
+ starting: :wait_for_service_start,
34
+ started: :stop_initial_service,
35
+ failed: :fail,
36
+ timed_out: :abort
37
+ }
38
+ }
39
+
40
+ on :stop_initial_service, do: Op::StopInitialInstance, then: :exit
41
+ on :fail, do: Op::ReportFailure, then: :exit
42
+
43
+ on :abort, do: Op::StopActivatingInstance, then: :fail
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/memory'
18
+
19
+ module ConfigOMat
20
+ module MetaConfigurator
21
+ class Memory < LifecycleVM::Memory
22
+ attr_accessor :argv, :env, :early_exit, :configuration_directory, :runtime_directory,
23
+ :systemd_directory, :logs_directory, :profile_defs,
24
+ :template_defs, :service_defs, :dependencies, :refresh_interval,
25
+ :client_id, :retry_count, :retries_left, :retry_wait,
26
+ :region, :systemd_interface
27
+
28
+ def initialize(
29
+ argv: [],
30
+ env: {},
31
+ early_exit: false,
32
+ configuration_directory: nil,
33
+ runtime_directory: nil,
34
+ logs_directory: nil,
35
+ systemd_directory: nil,
36
+ profile_defs: {},
37
+ template_defs: {},
38
+ service_defs: {},
39
+ dependencies: {},
40
+ refresh_interval: 5,
41
+ client_id: '',
42
+ logger: nil,
43
+ retry_count: 3,
44
+ retries_left: 3,
45
+ retry_wait: 2,
46
+ region: nil,
47
+ systemd_interface: nil
48
+ )
49
+ super()
50
+
51
+ @argv = argv
52
+ @env = env
53
+ @early_exit = early_exit
54
+ @configuration_directory = configuration_directory
55
+ @runtime_directory = runtime_directory
56
+ @logs_directory = logs_directory
57
+ @systemd_directory = systemd_directory
58
+ @profile_defs = profile_defs
59
+ @template_defs = template_defs
60
+ @service_defs = service_defs
61
+ @dependencies = dependencies
62
+ @refresh_interval = refresh_interval
63
+ @client_id = client_id
64
+ @logger = logger
65
+ @retry_count = retry_count
66
+ @retries_left = retries_left
67
+ @retry_wait = retry_wait
68
+ @region = region
69
+ @systemd_interface = systemd_interface
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/op_base'
18
+
19
+ require 'fileutils'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class GenerateSystemdConfig < LifecycleVM::OpBase
24
+ DROPIN_FILE_NAME = '99_teak_configurator.conf'
25
+
26
+ reads :template_defs, :service_defs, :runtime_directory, :systemd_directory, :systemd_interface
27
+
28
+ def call
29
+ grouped_restart_modes = service_defs.values.group_by(&:restart_mode)
30
+ restarts = grouped_restart_modes[:restart]
31
+ flip_flops = grouped_restart_modes[:flip_flop]
32
+
33
+ enable_restarts(restarts) if restarts
34
+ enable_flip_flops(flip_flops) if flip_flops
35
+
36
+ systemd_interface.daemon_reload
37
+ end
38
+
39
+ private
40
+
41
+ def write_dropin(unit, service)
42
+ dropin = %([Service]\n)
43
+ service.templates.each do |tmpl|
44
+ template = template_defs[tmpl.to_sym]
45
+ dropin += %(LoadCredential=#{template.dst}:#{File.join(runtime_directory, template.dst)}\n)
46
+ end
47
+
48
+ dropin_dir = File.join(systemd_directory, "#{unit}.service.d")
49
+
50
+ FileUtils.mkdir_p(dropin_dir)
51
+ File.open(File.join(dropin_dir, DROPIN_FILE_NAME), 'w') { |f| f.write(dropin) }
52
+ end
53
+
54
+ def enable_restarts(services)
55
+ units = []
56
+ services.each do |service|
57
+ unit = service.systemd_unit
58
+ units << unit
59
+
60
+ write_dropin(unit, service)
61
+ end
62
+
63
+ systemd_interface.enable_restart_paths(units)
64
+ end
65
+
66
+ def enable_flip_flops(services)
67
+ units = []
68
+ services.each do |service|
69
+ unit = service.systemd_unit
70
+ units << "#{unit}1"
71
+ units << "#{unit}2"
72
+
73
+ write_dropin(unit, service)
74
+ end
75
+
76
+ systemd_interface.enable_start_stop_paths(units)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/op_base'
18
+
19
+ require 'optparse'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class ParseMetaCli < LifecycleVM::OpBase
24
+ DEFAULT_SYSTEMD_DIRECTORY = '/run/systemd/system'
25
+
26
+ reads :argv, :env
27
+ writes :configuration_directory, :runtime_directory, :logs_directory, :systemd_directory, :early_exit
28
+
29
+ # Add expand_path to string because the safe accessor is nice to use.
30
+ module CoreExt
31
+ refine String do
32
+ def expand_path
33
+ File.expand_path(self)
34
+ end
35
+ end
36
+ end
37
+
38
+ using CoreExt
39
+
40
+ def call
41
+ self.early_exit = false
42
+
43
+ parser = OptionParser.new do |opts|
44
+ opts.on('-v', '--version', 'Display the version') do
45
+ self.early_exit = true
46
+ end
47
+
48
+ opts.on('-h', '--help', 'Prints this help') do
49
+ puts opts
50
+ self.early_exit = true
51
+ end
52
+
53
+ opts.on(
54
+ '-c', '--configuration-directory directory',
55
+ 'Read configuration from the given directory instead of from $CONFIGURATION_DIRECTORY'
56
+ ) do |dir|
57
+ self.configuration_directory = dir
58
+ end
59
+
60
+ opts.on(
61
+ '-r', '--runtime-directory directory',
62
+ 'Use the given directory for writing templates instead of $RUNTIME_DIRECTORY'
63
+ ) do |dir|
64
+ self.runtime_directory = dir
65
+ end
66
+
67
+ opts.on(
68
+ '-l', '--logs-directory directory',
69
+ 'Use the given directory for writing log files instead of $LOGS_DIRECTORY'
70
+ ) do |dir|
71
+ self.logs_directory = dir
72
+ end
73
+
74
+ opts.on(
75
+ '-s', '--systemd-directory directory',
76
+ "Write out systemd configuration to the given directory instead of #{DEFAULT_SYSTEMD_DIRECTORY}"
77
+ ) do |dir|
78
+ self.systemd_directory = dir
79
+ end
80
+ end
81
+
82
+ parser.parse(argv)
83
+
84
+ self.configuration_directory ||= env['CONFIGURATION_DIRECTORY']
85
+ self.runtime_directory ||= env['RUNTIME_DIRECTORY']
86
+ self.logs_directory ||= env['LOGS_DIRECTORY']
87
+ self.systemd_directory ||= DEFAULT_SYSTEMD_DIRECTORY
88
+
89
+ self.configuration_directory = configuration_directory&.expand_path
90
+ end
91
+
92
+ def validate
93
+ return if early_exit
94
+
95
+ if configuration_directory.nil? || configuration_directory.empty?
96
+ error :configuration_directory, 'must be present'
97
+ end
98
+
99
+ error :runtime_directory, 'must be present' if runtime_directory.nil? || runtime_directory.empty?
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ Dir[File.join(__dir__, 'op', '*')].sort.each { |file| require file }
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm'
18
+
19
+ require 'config_o_mat/shared/op'
20
+ require 'config_o_mat/shared/cond'
21
+ require 'config_o_mat/meta_configurator/op'
22
+ require 'config_o_mat/meta_configurator/memory'
23
+
24
+ module ConfigOMat
25
+ module MetaConfigurator
26
+ class VM < LifecycleVM::VM
27
+ VERSION = "0.0.1"
28
+
29
+ memory_class ConfigOMat::MetaConfigurator::Memory
30
+
31
+ on :start, do: Op::ParseMetaCli, then: {
32
+ case: Cond::EarlyExit,
33
+ when: {
34
+ true => :exit,
35
+ false => :reading_meta_config
36
+ }
37
+ }
38
+
39
+ on :reading_meta_config, do: Op::LoadMetaConfig, then: :generating_systemd_config
40
+
41
+ on :generating_systemd_config, do: Op::GenerateSystemdConfig, then: :exit
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'lifecycle_vm/cond_base'
18
+
19
+ module ConfigOMat
20
+ module Cond
21
+ class EarlyExit < LifecycleVM::CondBase
22
+ reads :early_exit
23
+
24
+ def call
25
+ early_exit
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2021 Teak.io, Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # https://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ Dir[File.join(__dir__, 'cond', '*')].sort.each { |file| require file }