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