|
| 1 | +# AppStreams Promise Type Enhancements - Before/After Examples |
| 2 | + |
| 3 | +This document illustrates the improvements made to the appstreams promise type in commit f1a12a0. |
| 4 | + |
| 5 | +## Enhancement 1: Generic DNF Options Support |
| 6 | + |
| 7 | +### Before |
| 8 | +The appstreams promise type had no way to pass DNF configuration options. Users could not control behavior like weak dependency installation. |
| 9 | + |
| 10 | +**Policy (not possible before):** |
| 11 | +```cfengine3 |
| 12 | +appstreams: |
| 13 | + "php" |
| 14 | + state => "installed", |
| 15 | + stream => "8.2", |
| 16 | + profile => "minimal"; |
| 17 | + # No way to prevent weak dependencies from being installed |
| 18 | +``` |
| 19 | + |
| 20 | +**Result:** |
| 21 | +``` |
| 22 | +$ rpm -q httpd |
| 23 | +httpd-2.4.57-11.el9_4.1.x86_64 # Weak dependency was installed |
| 24 | +$ rpm -q php-cli |
| 25 | +php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 |
| 26 | +``` |
| 27 | + |
| 28 | +### After |
| 29 | +New `options` attribute accepts any DNF configuration option. |
| 30 | + |
| 31 | +**Policy:** |
| 32 | +```cfengine3 |
| 33 | +appstreams: |
| 34 | + "php" |
| 35 | + state => "installed", |
| 36 | + stream => "8.2", |
| 37 | + profile => "minimal", |
| 38 | + options => { "install_weak_deps=false" }; # NEW |
| 39 | +``` |
| 40 | + |
| 41 | +**Result:** |
| 42 | +``` |
| 43 | +$ rpm -q httpd |
| 44 | +package httpd is not installed # Weak dependency excluded! |
| 45 | +$ rpm -q php-cli |
| 46 | +php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 |
| 47 | +``` |
| 48 | + |
| 49 | +**DNF History:** |
| 50 | +``` |
| 51 | +Command Line : module install -y php:8.2/minimal --setopt=install_weak_deps=false |
| 52 | +Comment : CFEngine appstreams promise: php state=installed |
| 53 | +``` |
| 54 | + |
| 55 | +**Multiple options example:** |
| 56 | +```cfengine3 |
| 57 | +appstreams: |
| 58 | + "nodejs" |
| 59 | + state => "installed", |
| 60 | + stream => "20", |
| 61 | + profile => "minimal", |
| 62 | + options => { |
| 63 | + "install_weak_deps=false", |
| 64 | + "best=true", |
| 65 | + "skip_broken=false" |
| 66 | + }; |
| 67 | +``` |
| 68 | + |
| 69 | +--- |
| 70 | + |
| 71 | +## Enhancement 2: Automatic Stream Switching |
| 72 | + |
| 73 | +### Before |
| 74 | +If a module was already enabled at one stream and you requested a different stream, the promise would report KEPT without making changes or would fail. |
| 75 | + |
| 76 | +**Starting state:** |
| 77 | +``` |
| 78 | +$ dnf module list php |
| 79 | +Name Stream Profiles Summary |
| 80 | +php 8.1 [e] common [d], devel, minimal [i] PHP scripting language |
| 81 | +php 8.2 common [d], devel, minimal PHP scripting language |
| 82 | +
|
| 83 | +$ rpm -q php-cli |
| 84 | +php-cli-8.1.32-1.module+el9.7.0+40003+454ed3c4.x86_64 |
| 85 | +``` |
| 86 | + |
| 87 | +**Policy:** |
| 88 | +```cfengine3 |
| 89 | +appstreams: |
| 90 | + "php" |
| 91 | + state => "installed", |
| 92 | + stream => "8.2", # Want to upgrade to 8.2 |
| 93 | + profile => "minimal"; |
| 94 | +``` |
| 95 | + |
| 96 | +**Result (before fix):** |
| 97 | +``` |
| 98 | +$ rpm -q php-cli |
| 99 | +php-cli-8.1.32-1.module+el9.7.0+40003+454ed3c4.x86_64 # Still on 8.1! |
| 100 | +``` |
| 101 | +Promise would report KEPT because it detected the module was "installed", but didn't check if the stream matched. |
| 102 | + |
| 103 | +### After |
| 104 | +Automatic detection and handling of stream changes (both upgrades and downgrades). |
| 105 | + |
| 106 | +**Same policy, same starting state:** |
| 107 | +```cfengine3 |
| 108 | +appstreams: |
| 109 | + "php" |
| 110 | + state => "installed", |
| 111 | + stream => "8.2", |
| 112 | + profile => "minimal", |
| 113 | + options => { "install_weak_deps=false" }; |
| 114 | +``` |
| 115 | + |
| 116 | +**CF-Agent output:** |
| 117 | +``` |
| 118 | +info: Switching module php from stream 8.1 to 8.2 |
| 119 | +info: Module php:8.2/minimal switched successfully |
| 120 | +``` |
| 121 | + |
| 122 | +**Result:** |
| 123 | +``` |
| 124 | +$ rpm -q php-cli |
| 125 | +php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 # Upgraded! |
| 126 | +
|
| 127 | +$ dnf module list php |
| 128 | +Name Stream Profiles Summary |
| 129 | +php 8.1 common [d], devel, minimal PHP scripting language |
| 130 | +php 8.2 [e] common [d], devel, minimal [i] PHP scripting language |
| 131 | +``` |
| 132 | + |
| 133 | +**DNF History:** |
| 134 | +``` |
| 135 | +Command Line : module switch-to -y php:8.2/minimal --setopt=install_weak_deps=false |
| 136 | +Comment : CFEngine appstreams promise: php state=installed |
| 137 | +Packages Altered: |
| 138 | + Upgrade php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 |
| 139 | + Upgraded php-cli-8.1.32-1.module+el9.7.0+40003+454ed3c4.x86_64 |
| 140 | +``` |
| 141 | + |
| 142 | +**Downgrade example:** |
| 143 | +```cfengine3 |
| 144 | +appstreams: |
| 145 | + "php" |
| 146 | + state => "installed", |
| 147 | + stream => "8.1", # Downgrade from 8.2 to 8.1 |
| 148 | + profile => "minimal"; |
| 149 | +``` |
| 150 | + |
| 151 | +**Result:** |
| 152 | +``` |
| 153 | +$ dnf history info last |
| 154 | +Command Line : module switch-to -y php:8.1/minimal |
| 155 | +Packages Altered: |
| 156 | + Downgrade php-cli-8.1.32-1.module+el9.7.0+40003+454ed3c4.x86_64 |
| 157 | + Downgraded php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 |
| 158 | +``` |
| 159 | + |
| 160 | +--- |
| 161 | + |
| 162 | +## Enhancement 3: DNF History Command Line Tracking |
| 163 | + |
| 164 | +### Before |
| 165 | +DNF history showed blank command lines for CFEngine-initiated changes, making it impossible to see what options were used or reconstruct what happened. |
| 166 | + |
| 167 | +**DNF History (before):** |
| 168 | +``` |
| 169 | +ID | Command line | Date and time | Action(s) |
| 170 | +------------------------------------------------------------------------ |
| 171 | + 33 | | 2026-04-21 21:00 | Downgrade |
| 172 | + 32 | | 2026-04-21 20:58 | Upgrade |
| 173 | + 31 | | 2026-04-21 20:57 | Downgrade |
| 174 | +``` |
| 175 | + |
| 176 | +**Detail view:** |
| 177 | +``` |
| 178 | +$ dnf history info 33 |
| 179 | +Transaction ID : 33 |
| 180 | +Command Line : # BLANK - no audit trail! |
| 181 | +Comment : CFEngine appstreams promise: php state=installed |
| 182 | +``` |
| 183 | + |
| 184 | +### After |
| 185 | +Full command line with all options visible in DNF history. |
| 186 | + |
| 187 | +**DNF History (after):** |
| 188 | +``` |
| 189 | +ID | Command line | Date and time | Action(s) |
| 190 | +------------------------------------------------------------------------------------ |
| 191 | + 41 | module switch-to -y php:8.3/minimal | 2026-04-21 21:35 | Upgrade |
| 192 | + 40 | module install -y php:8.2/minimal | 2026-04-21 21:33 | Install |
| 193 | +``` |
| 194 | + |
| 195 | +**Detail view:** |
| 196 | +``` |
| 197 | +$ dnf history info 41 |
| 198 | +Transaction ID : 41 |
| 199 | +Command Line : module switch-to -y php:8.3/minimal --setopt=install_weak_deps=false |
| 200 | +Comment : CFEngine appstreams promise: php state=installed |
| 201 | +Releasever : 9 |
| 202 | +User : <vagrant> |
| 203 | +Return-Code : Success |
| 204 | +``` |
| 205 | + |
| 206 | +Now auditors can see exactly what DNF command was used, including all options. |
| 207 | + |
| 208 | +--- |
| 209 | + |
| 210 | +## Enhancement 4: Correct Package Versions Using ModuleBase API |
| 211 | + |
| 212 | +### Before |
| 213 | +When using the old module package container (mpc) API, packages might be installed from the wrong stream or default stream instead of the requested module stream. |
| 214 | + |
| 215 | +**Policy:** |
| 216 | +```cfengine3 |
| 217 | +appstreams: |
| 218 | + "php" |
| 219 | + state => "installed", |
| 220 | + stream => "8.2", # Request 8.2 specifically |
| 221 | + profile => "minimal"; |
| 222 | +``` |
| 223 | + |
| 224 | +**Result (with old mpc.enable/install API):** |
| 225 | +``` |
| 226 | +$ rpm -q php-cli |
| 227 | +php-cli-8.0.30-5.el9_7.x86_64 # Got 8.0 (default stream) instead of 8.2! |
| 228 | +``` |
| 229 | + |
| 230 | +**DNF History showed the intent but wrong execution:** |
| 231 | +``` |
| 232 | +Command Line : module install -y php:8.2/minimal |
| 233 | +Packages Altered: |
| 234 | + Install php-cli-8.0.30-5.el9_7.x86_64 # Wrong version! |
| 235 | +``` |
| 236 | + |
| 237 | +### After |
| 238 | +Using `ModuleBase` API ensures packages come from the correct module stream context. |
| 239 | + |
| 240 | +**Same policy:** |
| 241 | +```cfengine3 |
| 242 | +appstreams: |
| 243 | + "php" |
| 244 | + state => "installed", |
| 245 | + stream => "8.2", |
| 246 | + profile => "minimal"; |
| 247 | +``` |
| 248 | + |
| 249 | +**Result:** |
| 250 | +``` |
| 251 | +$ rpm -q php-cli |
| 252 | +php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 # Correct 8.2 version! |
| 253 | +``` |
| 254 | + |
| 255 | +**DNF History shows correct execution:** |
| 256 | +``` |
| 257 | +Command Line : module install -y php:8.2/minimal |
| 258 | +Packages Altered: |
| 259 | + Install php-cli-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 # Correct! |
| 260 | + Install php-common-8.2.30-1.module+el9.7.0+40073+569087df.x86_64 |
| 261 | +``` |
| 262 | + |
| 263 | +--- |
| 264 | + |
| 265 | +## Combined Real-World Example |
| 266 | + |
| 267 | +**Use Case:** Install PHP 8.2 minimal profile without documentation and weak dependencies, then upgrade to 8.3 when needed. |
| 268 | + |
| 269 | +### Initial Installation |
| 270 | +```cfengine3 |
| 271 | +bundle agent webserver |
| 272 | +{ |
| 273 | + appstreams: |
| 274 | + "php" |
| 275 | + state => "installed", |
| 276 | + stream => "8.2", |
| 277 | + profile => "minimal", |
| 278 | + options => { |
| 279 | + "install_weak_deps=false" |
| 280 | + }; |
| 281 | +} |
| 282 | +``` |
| 283 | + |
| 284 | +**Result:** |
| 285 | +- ✅ PHP 8.2.30 installed (correct version) |
| 286 | +- ✅ httpd NOT installed (weak dependency excluded) |
| 287 | +- ✅ Only minimal profile packages installed |
| 288 | +- ✅ Full audit trail in DNF history |
| 289 | + |
| 290 | +### Later Upgrade to PHP 8.3 |
| 291 | +Just change the stream in policy: |
| 292 | +```cfengine3 |
| 293 | +bundle agent webserver |
| 294 | +{ |
| 295 | + appstreams: |
| 296 | + "php" |
| 297 | + state => "installed", |
| 298 | + stream => "8.3", # Changed from 8.2 |
| 299 | + profile => "minimal", |
| 300 | + options => { |
| 301 | + "install_weak_deps=false" |
| 302 | + }; |
| 303 | +} |
| 304 | +``` |
| 305 | + |
| 306 | +**Result:** |
| 307 | +- ✅ Automatic detection of stream change |
| 308 | +- ✅ Clean upgrade from 8.2 → 8.3 |
| 309 | +- ✅ Weak dependencies still excluded |
| 310 | +- ✅ DNF history shows: `module switch-to -y php:8.3/minimal --setopt=install_weak_deps=false` |
| 311 | + |
| 312 | +**No manual intervention needed!** |
| 313 | + |
| 314 | +--- |
| 315 | + |
| 316 | +## Summary of Improvements |
| 317 | + |
| 318 | +| Feature | Before | After | |
| 319 | +|---------|--------|-------| |
| 320 | +| **DNF Options** | Not supported | Any option via `options` attribute | |
| 321 | +| **Stream Switching** | Manual intervention required | Automatic detection and switching | |
| 322 | +| **Package Versions** | Sometimes wrong stream | Always correct via ModuleBase API | |
| 323 | +| **DNF History Command** | Blank | Full command with all options | |
| 324 | +| **DNF History Comment** | Not supported | CFEngine context included | |
| 325 | +| **Weak Deps Control** | Always installed | Can exclude with `install_weak_deps=false` | |
| 326 | +| **Audit Trail** | Incomplete | Complete reconstruction possible | |
| 327 | + |
| 328 | +## Technical Implementation |
| 329 | + |
| 330 | +The enhancements use: |
| 331 | +1. **`base.conf.set_or_append_opt_value()`** for generic option handling |
| 332 | +2. **`ModuleBase.install()`** for correct module package context |
| 333 | +3. **`ModuleBase.switch_to()`** for stream changes |
| 334 | +4. **`base.args`** for DNF history command line tracking |
| 335 | +5. **`base.conf.comment`** for CFEngine context in audit trail (from upstream) |
| 336 | + |
| 337 | +All changes maintain backward compatibility - existing policies without `options` continue to work as before. |
0 commit comments