Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic targets and cross-task vars #207

Open
umputun opened this issue May 26, 2024 Discussed in #206 · 0 comments
Open

Dynamic targets and cross-task vars #207

umputun opened this issue May 26, 2024 Discussed in #206 · 0 comments

Comments

@umputun
Copy link
Owner

umputun commented May 26, 2024

Discussed in #206

Originally posted by odyfey May 25, 2024
Hi!

I'm having a few issues while trying to run this playbook:

targets:
  default:
    hosts: [{host: "pghost1"}, {host: "pghost2"}, {host: "pghost3"}]

tasks:
  - name: check-recovery
    targets: ["default"]
    commands:
      - name: check recovery mode and set leader
        script: |
          is_recovery=$(psql -U ${pguser} -p ${pgport} -A -t -c "select pg_is_in_recovery();")
          if [ "$is_recovery" = "f" ]; then
            leader=$(hostname -I)
          fi
        register: [leader]

  - name: run on host
    targets: ["$leader"]
    commands: 
      - name: do something on leader
        script: |
          echo "doing something on $leader"

The playbook performs a check-recovery task on each host to discover the leader. Then, in the next task, some queries are executed on the leader host.

  1. Is it correct to use a variable from the previous task as a dynamic target?
  2. The playbook is successful only if the last element in the default targets (pghost3) is the leader, and as a result, the res.Vars variable has a value of map[leader:pghost3]. If you change the order in default targets, the last assigned value in the res.Vars map will be [leader:] and spot will error out on the last task:
[]  ! failed to dial: dial tcp :22: connect: connection refused
2024/05/24 17:36:29.424 [ERROR] can't run task "run on host" for target "": 1 error(s) occurred: [0] {failed to dial: dial tcp :22: connect: connection refused}
  1. Based on this comment, I suggest that the scope of res.Vars should be limited to one task, but when using register, this variable is used to set targets in another task. Is this correct?
  2. If the previous statements are correct, is it possible to change the behavior of spot so that once a non-empty value is written to map, it is not overwritten by the next empty value? I'm talking about code like this:
// changes in this line: https://github.com/umputun/spot/blob/master/pkg/runner/runner.go#L113
if rv, ok := allVars[k]; ok && rv != "" {
	continue
}

allVars[k] = v
```</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant