mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-25 17:12:50 +00:00
feat: support pre_install & post_install scripts by global config (#2872)
This commit is contained in:
parent
bd780ee397
commit
86dbf89026
|
|
@ -20,8 +20,19 @@
|
|||
mode: 0755
|
||||
register: post_install_copy_result
|
||||
|
||||
- name: Post | Copy post-installation config scripts to remote hosts
|
||||
copy:
|
||||
src: >-
|
||||
{{ .scripts_dir }}/{{ .item.script }}
|
||||
dest: >-
|
||||
/etc/kubekey/scripts/post_install_{{ .item.script }}
|
||||
mode: 0755
|
||||
loop: "{{ .post_install | toJson }}"
|
||||
when: "{{ getStringSlice .groups .item.group | default list | has .inventory_hostname }}"
|
||||
register: post_install_config_copy_result
|
||||
|
||||
- name: Post | Execute post-installation scripts on remote hosts
|
||||
when: .post_install_copy_result.error | empty
|
||||
when: or (.post_install_copy_result.error | empty) (and .post_install_config_copy_result (.post_install_config_copy_result.error | empty))
|
||||
command: |
|
||||
for file in /etc/kubekey/scripts/post_install_*.sh; do
|
||||
if [ -f "$file" ]; then
|
||||
|
|
@ -29,4 +40,4 @@
|
|||
chmod +x "$file"
|
||||
"$file"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
|
|
|||
|
|
@ -13,8 +13,19 @@
|
|||
mode: 0755
|
||||
register: pre_install_copy_result
|
||||
|
||||
- name: Pre | Copy pre-installation config scripts to remote hosts
|
||||
copy:
|
||||
src: >-
|
||||
{{ .work_dir }}/scripts/{{ .item.script }}
|
||||
dest: >-
|
||||
/etc/kubekey/scripts/pre_install_{{ .item.script }}
|
||||
mode: 0755
|
||||
loop: "{{ .pre_install | toJson }}"
|
||||
when: "{{ getStringSlice .groups .item.group | default list | has .inventory_hostname }}"
|
||||
register: pre_install_config_copy_result
|
||||
|
||||
- name: Pre | Execute pre-installation scripts on remote hosts
|
||||
when: .pre_install_copy_result.error | empty
|
||||
when: or (.pre_install_copy_result.error | empty) (and .pre_install_config_copy_result (.pre_install_config_copy_result.error | empty))
|
||||
command: |
|
||||
for file in /etc/kubekey/scripts/pre_install_*.sh; do
|
||||
if [ -f "$file" ]; then
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ work_dir: /root/kubekey
|
|||
binary_dir: >-
|
||||
{{ .work_dir }}/kubekey
|
||||
scripts_dir: >-
|
||||
{{ .binary_dir }}/scripts
|
||||
{{ .work_dir }}/scripts
|
||||
tmp_dir: /tmp/kubekey
|
||||
|
||||
# Mapping of common machine architecture names to their standard forms
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ func funcMap() template.FuncMap {
|
|||
f["subtractList"] = subtractList
|
||||
f["fileExist"] = fileExist
|
||||
f["unquote"] = unquote
|
||||
f["getStringSlice"] = getStringSlice
|
||||
|
||||
return f
|
||||
}
|
||||
|
|
@ -131,3 +132,10 @@ func unquote(input any) string {
|
|||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func getStringSlice(d map[string][]string, key string) []string {
|
||||
if val, ok := d[key]; ok {
|
||||
return val
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -252,6 +252,16 @@ func TestParseValue(t *testing.T) {
|
|||
},
|
||||
excepted: []byte("bar"),
|
||||
},
|
||||
{
|
||||
name: "get string slice from dictionary",
|
||||
input: "{{ getStringSlice .foo \"foo\" }}",
|
||||
variable: map[string]any{
|
||||
"foo": map[string][]string{
|
||||
"foo": {"bar1", "bar2"},
|
||||
},
|
||||
},
|
||||
excepted: []byte("[bar1 bar2]"),
|
||||
},
|
||||
{
|
||||
name: "multi level 2",
|
||||
input: "{{ index .foo \"foo\" }}",
|
||||
|
|
|
|||
|
|
@ -166,21 +166,19 @@ func (e *taskExecutor) execTaskHost(i int, h string) func(ctx context.Context) {
|
|||
resErr = errors.Errorf("host: %s variable is not a map", h)
|
||||
return
|
||||
}
|
||||
// check when condition
|
||||
if skip, err := e.dealWhen(had); err != nil {
|
||||
resErr = err
|
||||
return
|
||||
} else if skip {
|
||||
stdout = modules.StdoutSkip
|
||||
return
|
||||
}
|
||||
// execute module in loop with loop item.
|
||||
// if loop is empty. execute once, and the item is null
|
||||
for _, item := range e.dealLoop(had) {
|
||||
resErr = e.executeModule(ctx, e.task, item, h, &stdout, &stderr)
|
||||
if resErr != nil {
|
||||
resSkip, exeErr := e.executeModule(ctx, e.task, item, h, &stdout, &stderr)
|
||||
if exeErr != nil {
|
||||
resErr = exeErr
|
||||
break
|
||||
}
|
||||
// loop execute once, skip task
|
||||
if item == nil && resSkip {
|
||||
stdout = modules.StdoutSkip
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -260,18 +258,18 @@ func (e *taskExecutor) execTaskHostLogs(ctx context.Context, h string, stdout, _
|
|||
}
|
||||
|
||||
// executeModule executes a single module task on a specific host.
|
||||
func (e *taskExecutor) executeModule(ctx context.Context, task *kkcorev1alpha1.Task, item any, host string, stdout, stderr *string) (resErr error) {
|
||||
func (e *taskExecutor) executeModule(ctx context.Context, task *kkcorev1alpha1.Task, item any, host string, stdout, stderr *string) (resSkip bool, resErr error) {
|
||||
// Set loop item variable if one was provided
|
||||
if item != nil {
|
||||
// Convert item to runtime variable
|
||||
node, err := converter.ConvertMap2Node(map[string]any{_const.VariableItem: item})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to convert loop item")
|
||||
return false, errors.Wrap(err, "failed to convert loop item")
|
||||
}
|
||||
|
||||
// Merge item into host's runtime variables
|
||||
if err := e.variable.Merge(variable.MergeRuntimeVariable([]yaml.Node{node}, host)); err != nil {
|
||||
return errors.Wrap(err, "failed to set loop item to variable")
|
||||
return false, errors.Wrap(err, "failed to set loop item to variable")
|
||||
}
|
||||
|
||||
// Clean up loop item variable after execution
|
||||
|
|
@ -295,13 +293,20 @@ func (e *taskExecutor) executeModule(ctx context.Context, task *kkcorev1alpha1.T
|
|||
// Get all variables for this host, including any loop item
|
||||
ha, err := e.variable.Get(variable.GetAllVariable(host))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get host %s variable", host)
|
||||
return false, errors.Wrapf(err, "failed to get host %s variable", host)
|
||||
}
|
||||
|
||||
// Convert host variables to map type
|
||||
had, ok := ha.(map[string]any)
|
||||
if !ok {
|
||||
return errors.Wrapf(err, "host %s variable is not a map", host)
|
||||
return false, errors.Wrapf(err, "host %s variable is not a map", host)
|
||||
}
|
||||
|
||||
// check when condition
|
||||
if skip, err := e.dealWhen(had); err != nil {
|
||||
return false, err
|
||||
} else if skip {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Execute the actual module with the prepared context
|
||||
|
|
@ -313,7 +318,7 @@ func (e *taskExecutor) executeModule(ctx context.Context, task *kkcorev1alpha1.T
|
|||
Playbook: *e.playbook,
|
||||
LogOutput: e.logOutput,
|
||||
})
|
||||
return e.dealFailedWhen(had, resErr)
|
||||
return false, e.dealFailedWhen(had, resErr)
|
||||
}
|
||||
|
||||
// dealLoop parses the loop specification into a slice of items to iterate over.
|
||||
|
|
|
|||
Loading…
Reference in New Issue