βββββββββββββββββββββββββββββββββββββββββββ
β Get current state via Status() β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Is ensure = "latest"? β
βββββββββββββββββββ¬ββββββββββββββββββββββββ
Yes β No
βΌ β
βββββββββββββββββββββββ β
β Is package absent? β β
βββββββββββββββ¬ββββββββ β
Yes β No β
βΌ βΌ β
ββββββββββ ββββββββββ
βInstall β βUpgrade β
βlatest β βlatest β
ββββββββββ ββββββββββ
β
βΌ
βββββββββββββββββββββββββββ
β Is desired state met? β
βββββββββββββββ¬ββββββββββββ
Yes β No
βΌ β
βββββββββββββ β
β No change β βΌ
βββββββββββββ (Phase 2)
Phase 2: Handle Ensure Values
βββββββββββββββββββββββββββ
β What is desired ensure? β
βββββββββββββββ¬ββββββββββββ
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
β absent β present β <version>
βΌ βΌ βΌ
ββββββββββββββ βββββββββββββββββ βββββββββββββββββ
β Uninstall β β Is absent? β β Is absent? β
ββββββββββββββ βββββββββ¬ββββββββ βββββββββ¬ββββββββ
Yes β No Yes β No
βΌ βΌ βΌ βΌ
ββββββββββ ββββββββββ ββββββββββ ββββββββββββββ
βInstall β βNo β βInstall β βCompare β
β β βchange β βversion β βversions β
ββββββββββ ββββββββββ ββββββββββ βββββββ¬βββββββ
β
ββββββββββββββββββΌβββββββββββββββββ
β current < β current = β current >
βΌ βΌ βΌ
βββββββββββββ βββββββββββββ βββββββββββββ
β Upgrade β β No change β β Downgrade β
βββββββββββββ βββββββββββββ βββββββββββββ
Version Comparison
The VersionCmp method compares two version strings:
Return Value
Meaning
-1
versionA < versionB (upgrade needed)
0
versionA == versionB (no change)
1
versionA > versionB (downgrade needed)
Version comparison is delegated to the provider, allowing platform-specific version parsing (e.g., RPM epoch handling, Debian revision suffixes).
Idempotency
The package resource is idempotent through state comparison:
Decision Table
Desired
Current State
Action
ensure: present
installed (any version)
None
ensure: present
absent
Install
ensure: absent
absent
None
ensure: absent
installed
Uninstall
ensure: latest
absent
Install latest
ensure: latest
installed
Upgrade (always runs)
ensure: <version>
same version
None
ensure: <version>
older version
Upgrade
ensure: <version>
newer version
Downgrade
ensure: <version>
absent
Install
Special Case: ensure: latest
When ensure: latest is used:
The package manager determines what “latest” means
Upgrade is always called when the package exists (package manager is idempotent)
The type cannot verify if “latest” was achieved (package managers may report stale data)
Desired state validation only checks that the package is not absent
Package Name Validation
Package names are validated to prevent injection attacks:
Allowed Characters:
Alphanumeric (a-z, A-Z, 0-9)
Period (.), underscore (_), plus (+)
Colon (:), tilde (~), hyphen (-)
Rejected:
Shell metacharacters (;, |, &, $, etc.)
Whitespace
Quotes and backticks
Path separators
Version strings (when ensure is a version) are also validated for dangerous characters.
Noop Mode
In noop mode, the package type:
Queries current state normally
Computes version comparison
Logs what actions would be taken
Sets appropriate NoopMessage:
“Would have installed latest”
“Would have upgraded to latest”
“Would have installed version X”
“Would have upgraded to X”
“Would have downgraded to X”
“Would have uninstalled”
Reports Changed: true if changes would occur
Does not call provider Install/Upgrade/Downgrade/Uninstall methods
Desired State Validation
After applying changes (in non-noop mode), the type verifies the package reached the desired state:
func (t*Type) isDesiredState(properties, state) bool {
switchproperties.Ensure {
case"present":
// Any installed version is acceptablereturnstate.Ensure!="absent"case"absent":
returnstate.Ensure=="absent"case"latest":
// Cannot verify "latest", just check not absentreturnstate.Ensure!="absent"default:
// Specific version must matchreturnVersionCmp(state.Ensure, properties.Ensure, false) ==0 }
}
If the desired state is not reached, an ErrDesiredStateFailed error is returned.