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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +26 -0
- data/Gemfile.lock +56 -0
- data/LICENSE +202 -0
- data/NOTICE +2 -0
- data/README.md +15 -0
- data/Rakefile +35 -0
- data/bin/config_o_mat-configurator +49 -0
- data/bin/config_o_mat-meta_configurator +49 -0
- data/config_o_mat.gemspec +49 -0
- data/design/configurator_lifecycle_test.dot +91 -0
- data/design/original_design.md +45 -0
- data/lib/config_o_mat/configurator/cond/first_run.rb +29 -0
- data/lib/config_o_mat/configurator/cond/next_state.rb +29 -0
- data/lib/config_o_mat/configurator/cond/profiles_to_apply.rb +29 -0
- data/lib/config_o_mat/configurator/cond/retries_left.rb +37 -0
- data/lib/config_o_mat/configurator/cond/services_to_reload.rb +29 -0
- data/lib/config_o_mat/configurator/cond.rb +17 -0
- data/lib/config_o_mat/configurator/memory.rb +93 -0
- data/lib/config_o_mat/configurator/op/apply_all_profiles.rb +35 -0
- data/lib/config_o_mat/configurator/op/commit_staged_profile.rb +35 -0
- data/lib/config_o_mat/configurator/op/compile_templates.rb +41 -0
- data/lib/config_o_mat/configurator/op/connect_to_appconfig.rb +35 -0
- data/lib/config_o_mat/configurator/op/generate_all_templates.rb +66 -0
- data/lib/config_o_mat/configurator/op/next_tick.rb +48 -0
- data/lib/config_o_mat/configurator/op/notify_systemd_start.rb +29 -0
- data/lib/config_o_mat/configurator/op/parse_cli.rb +93 -0
- data/lib/config_o_mat/configurator/op/refresh_all_profiles.rb +63 -0
- data/lib/config_o_mat/configurator/op/refresh_profile.rb +65 -0
- data/lib/config_o_mat/configurator/op/reload_one_service.rb +73 -0
- data/lib/config_o_mat/configurator/op/stage_one_profile.rb +33 -0
- data/lib/config_o_mat/configurator/op/wait_retry.rb +41 -0
- data/lib/config_o_mat/configurator/op.rb +17 -0
- data/lib/config_o_mat/configurator.rb +122 -0
- data/lib/config_o_mat/flip_flopper/cond/service_status.rb +29 -0
- data/lib/config_o_mat/flip_flopper/cond.rb +17 -0
- data/lib/config_o_mat/flip_flopper/memory.rb +51 -0
- data/lib/config_o_mat/flip_flopper/op/check_service_status.rb +72 -0
- data/lib/config_o_mat/flip_flopper/op/determine_running_instance.rb +56 -0
- data/lib/config_o_mat/flip_flopper/op/report_failure.rb +36 -0
- data/lib/config_o_mat/flip_flopper/op/start_activating_instance.rb +34 -0
- data/lib/config_o_mat/flip_flopper/op/stop_activating_instance.rb +34 -0
- data/lib/config_o_mat/flip_flopper/op/stop_initial_instance.rb +34 -0
- data/lib/config_o_mat/flip_flopper/op.rb +17 -0
- data/lib/config_o_mat/flip_flopper.rb +46 -0
- data/lib/config_o_mat/meta_configurator/memory.rb +73 -0
- data/lib/config_o_mat/meta_configurator/op/generate_systemd_config.rb +80 -0
- data/lib/config_o_mat/meta_configurator/op/parse_meta_cli.rb +103 -0
- data/lib/config_o_mat/meta_configurator/op.rb +17 -0
- data/lib/config_o_mat/meta_configurator.rb +44 -0
- data/lib/config_o_mat/shared/cond/early_exit.rb +29 -0
- data/lib/config_o_mat/shared/cond.rb +17 -0
- data/lib/config_o_mat/shared/op/load_meta_config.rb +188 -0
- data/lib/config_o_mat/shared/op.rb +17 -0
- data/lib/config_o_mat/shared/systemd_interface.rb +93 -0
- data/lib/config_o_mat/shared/types.rb +248 -0
- data/lib/config_o_mat/version.rb +19 -0
- data/lib/version.rb +19 -0
- data/systemd/teak-configurator-restart-service@.path +27 -0
- data/systemd/teak-configurator-restart-service@.service +21 -0
- data/systemd/teak-configurator-start-service@.path +27 -0
- data/systemd/teak-configurator-start-service@.service +21 -0
- data/systemd/teak-configurator-stop-service@.path +27 -0
- data/systemd/teak-configurator-stop-service@.service +21 -0
- data/systemd/teak-configurator.service +68 -0
- data/systemd/teak-metaconfigurator.service +57 -0
- 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
|