config_o_mat 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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,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 FirstRun < LifecycleVM::CondBase
22
+ reads :run_count
23
+
24
+ def call
25
+ run_count.zero?
26
+ end
27
+ end
28
+ end
29
+ 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 NextState < LifecycleVM::CondBase
22
+ reads :next_state
23
+
24
+ def call
25
+ next_state
26
+ end
27
+ end
28
+ end
29
+ 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 ProfilesToApply < LifecycleVM::CondBase
22
+ reads :profiles_to_apply
23
+
24
+ def call
25
+ !profiles_to_apply.empty?
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,37 @@
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 RetriesLeft < LifecycleVM::CondBase
22
+ reads :error_op, :retries_left, :applying_profile
23
+
24
+ def call
25
+ logger&.error(:op_failure, op: error_op.class.name, errors: error_op.errors)
26
+
27
+ # If we aren't currently applying a profile then there's nothing for us to retry.
28
+ return false if applying_profile.nil?
29
+
30
+ # If we're out of retries, well, no more retrying
31
+ return false if retries_left.zero?
32
+
33
+ true
34
+ end
35
+ end
36
+ end
37
+ 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 ServicesToReload < LifecycleVM::CondBase
22
+ reads :services_to_reload
23
+
24
+ def call
25
+ !services_to_reload.empty?
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 }
@@ -0,0 +1,93 @@
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 Configurator
21
+ class Memory < LifecycleVM::Memory
22
+ attr_accessor :argv, :env, :early_exit, :configuration_directory,
23
+ :runtime_directory, :logs_directory, :run_count, :profile_defs,
24
+ :template_defs, :service_defs, :dependencies, :refresh_interval,
25
+ :client_id, :compiled_templates, :applied_profiles, :applying_profile,
26
+ :generated_templates, :services_to_reload, :profiles_to_apply,
27
+ :last_refresh_time, :next_state, :retry_count, :retries_left, :retry_wait,
28
+ :region, :appconfig_client, :systemd_interface
29
+
30
+ def initialize(
31
+ argv: [],
32
+ env: {},
33
+ early_exit: false,
34
+ configuration_directory: nil,
35
+ runtime_directory: nil,
36
+ logs_directory: nil,
37
+ run_count: 0,
38
+ profile_defs: {},
39
+ template_defs: {},
40
+ service_defs: {},
41
+ dependencies: {},
42
+ refresh_interval: 5,
43
+ client_id: '',
44
+ logger: nil,
45
+ compiled_templates: {},
46
+ applied_profiles: {},
47
+ profiles_to_apply: [],
48
+ applying_profile: nil,
49
+ generated_templates: {},
50
+ services_to_reload: Set.new,
51
+ last_refresh_time: 0,
52
+ next_state: :running,
53
+ retry_count: 3,
54
+ retries_left: 3,
55
+ retry_wait: 2,
56
+ region: nil,
57
+ appconfig_client: nil,
58
+ systemd_interface: nil
59
+ )
60
+ super()
61
+
62
+ @argv = argv
63
+ @env = env
64
+ @early_exit = early_exit
65
+ @configuration_directory = configuration_directory
66
+ @runtime_directory = runtime_directory
67
+ @logs_directory = logs_directory
68
+ @run_count = run_count
69
+ @profile_defs = profile_defs
70
+ @template_defs = template_defs
71
+ @service_defs = service_defs
72
+ @dependencies = dependencies
73
+ @refresh_interval = refresh_interval
74
+ @client_id = client_id
75
+ @logger = logger
76
+ @compiled_templates = compiled_templates
77
+ @applied_profiles = applied_profiles
78
+ @profiles_to_apply = profiles_to_apply
79
+ @applying_profile = applying_profile
80
+ @generated_templates = generated_templates
81
+ @services_to_reload = services_to_reload
82
+ @last_refresh_time = last_refresh_time
83
+ @next_state = next_state
84
+ @retry_count = retry_count
85
+ @retries_left = retries_left
86
+ @retry_wait = retry_wait
87
+ @region = region
88
+ @appconfig_client = appconfig_client
89
+ @systemd_interface = systemd_interface
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,35 @@
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 ApplyAllProfiles < LifecycleVM::OpBase
22
+ reads :profiles_to_apply, :applied_profiles
23
+ writes :profiles_to_apply, :applied_profiles
24
+
25
+ def call
26
+ profiles_to_apply.each do |profile|
27
+ applied_profiles[profile.name] = profile
28
+ error profile.name, profile.errors if profile.errors?
29
+ end
30
+
31
+ self.profiles_to_apply = []
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,35 @@
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 CommitStagedProfile < LifecycleVM::OpBase
22
+ reads :applied_profiles, :applying_profile
23
+ writes :applied_profiles, :applying_profile
24
+
25
+ def call
26
+ # This happens in the first boot case, where we apply all profiles at once and so there's no
27
+ # individual applying_profile.
28
+ return if applying_profile.nil?
29
+
30
+ applied_profiles[applying_profile.name] = applying_profile
31
+ self.applying_profile = nil
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,41 @@
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 'erb'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class CompileTemplates < LifecycleVM::OpBase
24
+ reads :template_defs, :configuration_directory
25
+ writes :compiled_templates
26
+
27
+ def call
28
+ self.compiled_templates = template_defs.each_with_object({}) do |(key, templ_def), hash|
29
+ filename = File.join(configuration_directory, 'templates', templ_def.src)
30
+ begin
31
+ templ = ERB.new(File.read(filename))
32
+ templ.filename = filename
33
+ hash[key] = templ.def_class(Object, 'render(profiles)').new
34
+ rescue SyntaxError, StandardError => e
35
+ error filename, e
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
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 'aws-sdk-appconfig'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class ConnectToAppconfig < LifecycleVM::OpBase
24
+ reads :region
25
+ writes :appconfig_client
26
+
27
+ def call
28
+ client_opts = { logger: logger }
29
+ client_opts[:region] = region if region
30
+
31
+ self.appconfig_client = Aws::AppConfig::Client.new(client_opts)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,66 @@
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 GenerateAllTemplates < LifecycleVM::OpBase
22
+ reads :template_defs, :dependencies, :applied_profiles, :applying_profile, :generated_templates,
23
+ :compiled_templates, :runtime_directory
24
+
25
+ writes :generated_templates, :services_to_reload
26
+
27
+ def call
28
+ # By doing the error check here instead of in StageOneProfile we ensure that the applying_profile
29
+ # gets set in memory, even if errored, which simplifies the retry logic.
30
+ error applying_profile.name, applying_profile.errors if applying_profile&.errors?
31
+
32
+ return if errors?
33
+
34
+ profiles = applied_profiles
35
+ profiles[applying_profile.name] = applying_profile if applying_profile
36
+ self.services_to_reload = []
37
+
38
+ template_defs.each do |(key, templ_def)|
39
+ compiled_template = compiled_templates[key]
40
+
41
+ begin
42
+ rendered = compiled_template.render(profiles)
43
+ rescue StandardError => e
44
+ error key, e
45
+ next
46
+ end
47
+
48
+ generated = GeneratedTemplate.new(rendered)
49
+
50
+ if generated_templates[key] != generated
51
+ destination_file = File.join(runtime_directory, templ_def.dst)
52
+ logger&.notice(:template_update, template: key, file: destination_file, digest: generated.digest)
53
+
54
+ generated_templates[key] = generated
55
+ File.open(destination_file, 'w') { |f| f.write(rendered) }
56
+ dependencies[key]&.each { |service| services_to_reload << service }
57
+ end
58
+ end
59
+
60
+ services_to_reload.uniq!
61
+
62
+ logger&.notice(:scheduled_restarts, services: services_to_reload)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,48 @@
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 'sd_notify'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class NextTick < LifecycleVM::OpBase
24
+ PAUSE_INTERVAL = 1
25
+
26
+ reads :last_refresh_time, :refresh_interval, :run_count, :retry_count
27
+ writes :next_state, :run_count, :retries_left
28
+
29
+ def call
30
+ self.run_count += 1
31
+
32
+ SdNotify.watchdog
33
+
34
+ # If we got here then our retry process has succeeded.
35
+ self.retries_left = retry_count
36
+
37
+ # I'm calling Kernel.sleep directly so that tests can easily stub it out.
38
+ Kernel.sleep PAUSE_INTERVAL
39
+
40
+ if Time.now.to_i - last_refresh_time > refresh_interval
41
+ self.next_state = :refreshing_profiles
42
+ else
43
+ self.next_state = :running
44
+ end
45
+ end
46
+ end
47
+ end
48
+ 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/op_base'
18
+
19
+ require 'sd_notify'
20
+
21
+ module ConfigOMat
22
+ module Op
23
+ class NotifySystemdStart < LifecycleVM::OpBase
24
+ def call
25
+ SdNotify.ready
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,93 @@
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
+ require 'optparse'
19
+
20
+ module ConfigOMat
21
+ module Op
22
+ class ParseCli < LifecycleVM::OpBase
23
+ reads :argv, :env
24
+ writes :configuration_directory, :runtime_directory, :logs_directory, :early_exit
25
+
26
+ # Add expand_path to string because the safe accessor is nice to use.
27
+ module CoreExt
28
+ refine String do
29
+ def expand_path
30
+ File.expand_path(self)
31
+ end
32
+ end
33
+ end
34
+
35
+ using CoreExt
36
+
37
+ def call
38
+ self.early_exit = false
39
+
40
+ parser = OptionParser.new do |opts|
41
+ opts.on('-v', '--version', 'Display the version') do
42
+ self.early_exit = true
43
+ end
44
+
45
+ opts.on('-h', '--help', 'Prints this help') do
46
+ puts opts
47
+ self.early_exit = true
48
+ end
49
+
50
+ opts.on(
51
+ '-c', '--configuration-directory directory',
52
+ 'Read configuration from the given directory instead of from $CONFIGURATION_DIRECTORY'
53
+ ) do |dir|
54
+ self.configuration_directory = dir
55
+ end
56
+
57
+ opts.on(
58
+ '-r', '--runtime-directory directory',
59
+ 'Use the given directory for writing templates instead of $RUNTIME_DIRECTORY'
60
+ ) do |dir|
61
+ self.runtime_directory = dir
62
+ end
63
+
64
+ opts.on(
65
+ '-l', '--logs-directory directory',
66
+ 'Use the given directory for writing log files instead of $LOGS_DIRECTORY'
67
+ ) do |dir|
68
+ self.logs_directory = dir
69
+ end
70
+ end
71
+
72
+ parser.parse(argv)
73
+
74
+ self.configuration_directory ||= env['CONFIGURATION_DIRECTORY']
75
+ self.runtime_directory ||= env['RUNTIME_DIRECTORY']
76
+ self.logs_directory ||= env['LOGS_DIRECTORY']
77
+
78
+ self.configuration_directory = configuration_directory&.expand_path
79
+ self.runtime_directory = runtime_directory&.expand_path
80
+ end
81
+
82
+ def validate
83
+ return if early_exit
84
+
85
+ if configuration_directory.nil? || configuration_directory.empty?
86
+ error :configuration_directory, 'must be present'
87
+ end
88
+
89
+ error :runtime_directory, 'must be present' if runtime_directory.nil? || runtime_directory.empty?
90
+ end
91
+ end
92
+ end
93
+ end