module

Krikri::SynchronizeRsync

The rsync-invocation core of ansible.posix.synchronize, shared by both entry points that need it:

  • SynchronizeActionPlugin (controller-side action plugin - the normal task-execution path; see its own file for why synchronize is controller-side here, same as real Ansible)
  • plugins/synchronize.cr (the standalone/fat plugin binary, kept for --async/manual invocation on whatever host the "local" rsync end is - same split as debug/pause)

Ported from real ansible.posix's plugins/modules/synchronize.py (the module half; the action-plugin half only munges src/dest into remote user@host:path form and resolves the private key/port before handing over). Argument order, flag spelling, and the itemize-changes protocol all follow that source verbatim:

  • every flag rsync gets is the real module's own (including the non-obvious ones: --delete-after for delete:, --delay-updates -F by default, --archive plus explicit --no-X for each toggle that was EXPLICITLY turned off under a default-on archive:)
  • changed detection is rsync's own: the command always runs with --out-format=<<CHANGED>>%i %n%L, so every item rsync actually created/updated/attribute-changed/deleted gets a <<CHANGED>>- prefixed itemize line and an untouched tree prints nothing at all - "any marker line => changed" is exactly real Ansible's own changed = changed_marker in out test (with the documented link_dest exception, where a leading . itemize char means "hard-linked, no change")

Constants

CHANGED_MARKER = "<<CHANGED>>"

Class methods

bool(value : String | Nil, default : Bool = false) : Bool
Source
bool_opt(value : String | Nil) : Bool | Nil

Tri-state form: nil when the param is absent (the caller decides what "absent" follows - for the archive toggles that's archive's own value, per the real module's type: bool-without-default spec).

Source
build_argv(src : String, dest : String, params : Hash(String, String), private_key : String | Nil = nil, dest_port : Int32 | Nil = nil) : Array(String)

Builds the full rsync argv for one synchronize invocation. src and dest must already be FINAL (the caller munged remote ends into user@host:path form first); everything else is read from params with the real module's own defaults. private_key/dest_port are the caller-resolved connection values (param override, then inventory vars) that feed the --rsh= ssh command when either path is remote (contains ':').

Source
clean_output(output : String) : String

Strips the markers back off, keeping one itemize line (marker removed) per real change - the real module's msg/stdout_lines/diff payload.

Source
format_rsh_target(host_addr : String, path : String, user : String | Nil) : String

_format_rsync_rsh_target - builds user@host:path for the remote end, preserving an already-qualified path (user@host:path as written in the task, or an rsync:// URL) untouched. IPv6 hosts get the [user@addr]:path bracket form rsync's ssh transport requires.

Source
needs_rsh?(src : String, dest : String) : Bool

True when either final path is an rsync remote spec (host:path, user@host:path, or rsync:// URL) - the real module's is_rsh_needed. Two plain local paths (the delegate_to: localhost idiom) need no remote shell.

Source
parse_list(value : String | Nil) : Array(String)

List-shaped params arrive as strings (the wire format every plugin gets) - either a JSON array or comma-separated. Same defensive re-parse find.cr/apt.cr document (a YAML one-element list otherwise becomes ONE string containing literal brackets/quotes).

Source
run(argv : Array(String)) : RsyncResult
Source

Nested types