1# This policy is designed to be run with an independent agent. 2 3# WARNING: Including this policy into the inputs of another policy may result in 4# duplicate definition of bundles. 5 6# TODO remove windows_unattended_upgrade.cf when ENT-6823 allows us to use msiexec packages module 7bundle common standalone_self_upgrade_file_control 8{ 9 vars: 10 "inputs" slist => { "$(this.promise_dirname)$(const.dirsep)cfe_internal$(const.dirsep)update$(const.dirsep)windows_unattended_upgrade.cf" }; 11} 12 13body file control 14{ 15 inputs => { @(standalone_self_upgrade_file_control.inputs) }; 16} 17bundle agent main 18# @brief This bundle drives the self upgrade. It actuates the appropriate 19# bundles to download binaries to the hub for serving to clients, caching the 20# software to remote clients, and managing the version of cfengine installed on 21# non hubs. 22{ 23 classes: 24 25 "policy_server_dat_unstable" 26 expression => isnewerthan( "$(sys.workdir)/policy_server.dat", "$(sys.workdir)/outputs" ), 27 comment => "If $(sys.workdir)/policy_server.dat is newer than the 28 outputs directory, it can indicate that the current agent 29 execution is a result of bootstrap. For stability we want to 30 skip upgrades during bootstrap. The outputs directory should 31 be newer than the policy_server.dat on the next agent run 32 and allow upgrade then."; 33 34 reports: 35 "Running $(this.promise_filename)"; 36 37 methods: 38 39 "cfengine_software"; 40 41 (am_policy_hub|policy_server).!mpf_disable_hub_masterfiles_software_update_seed:: 42 43 "Master Software Repository Data" 44 usebundle => cfengine_master_software_content; 45 46 !(am_policy_hub|policy_server|policy_server_dat_unstable):: 47 48 "Local Software Cache" 49 usebundle => cfengine_software_cached_locally; 50 51 "CFEngine Version" 52 usebundle => cfengine_software_version; 53 54} 55 56bundle common package_module_knowledge 57# @brief common package_module_knowledge bundle 58# 59# This common bundle defines which package modules are the defaults on different 60# platforms. 61{ 62 vars: 63 debian|ubuntu:: 64 "platform_default" string => "apt_get"; 65 66 redhat|centos|amazon_linux:: 67 "platform_default" string => "yum"; 68} 69bundle common u_common_knowledge 70# @brief standalone common packages knowledge bundle 71# 72# This common bundle defines general things about platforms. 73# @see common_knowledge 74{ 75 vars: 76 "list_update_ifelapsed_now" string => "10080"; 77} 78bundle agent cfengine_software 79# @brief Variables to control the specifics in desired package selection 80{ 81 vars: 82 83 # Default desired CFEngine software 84 "pkg_name" string => ifelse( isvariable( "def.cfengine_software_pkg_name" ), $(def.cfengine_software_pkg_name), "cfengine-nova"); 85 "pkg_version" string => ifelse( isvariable( "def.cfengine_software_pkg_version" ), $(def.cfengine_software_pkg_version), "3.19.0"); 86 "pkg_release" string => ifelse( isvariable( "def.cfengine_software_pkg_release" ), $(def.cfengine_software_pkg_release), "1"); 87 "pkg_arch" string => ifelse( isvariable( "def.cfengine_software_pkg_arch" ), $(def.cfengine_software_pkg_arch), "x86_64"); 88 "package_dir" string => ifelse( isvariable( "def.cfengine_software_pkg_dir" ), $(def.cfengine_software_pkg_dir), "$(sys.flavour)_$(sys.arch)"); 89 "pkg_edition_path" string => ifelse( isvariable( "def.cfengine_software_pkg_edition_path" ), $(def.cfengine_software_pkg_edition_path), "enterprise/Enterprise-$(pkg_version)/agent"); 90 91 community_edition:: 92 "pkg_name" string => "cfengine-community"; 93 "pkg_edition_path" string => "community_binaries/Community-$(pkg_version)"; 94 95 aix:: 96 "pkg_name" string => "cfengine.cfengine-nova"; 97 "pkg_arch" string => "default"; 98 99 # TODO ENT-3187 100 solaris|solarisx86:: 101 "pkg_name" string => "CFE.cfengine-nova"; 102 103 (debian|ubuntu).64_bit:: 104 105 "pkg_arch" 106 string => "amd64", 107 comment => "On debian hosts it's the standard to use 'amd64' instead of 108 'x86_64' in package architectures."; 109 110 (redhat|centos|suse|sles).32_bit:: 111 "pkg_arch" 112 string => "i386", 113 comment => "i686 is the detected architecture, but the package is 114 compatible from i386 up."; 115 116 hpux:: 117 118 "package_dir" 119 string => "$(sys.class)_$(sys.arch)", 120 comment => "The directory within software updates to look for packages. 121 On HPUX sys.flavor includes versions, so we use sys.class 122 instead."; 123 any:: 124 125 "local_software_dir" 126 string => translatepath( "$(sys.workdir)/software_updates/$(package_dir)" ), 127 comment => "So that we converge on the first pass we set this last as 128 package_dir may vary across platforms."; 129 130 reports: 131 DEBUG|DEBUG_cfengine_software:: 132 "$(this.bundle) pkg_name = $(pkg_name)"; 133 "$(this.bundle) pkg_version = $(pkg_version)"; 134 "$(this.bundle) pkg_release = $(pkg_release)"; 135 "$(this.bundle) pkg_arch = $(pkg_arch)"; 136 "$(this.bundle) package_dir = $(package_dir)"; 137 138 139 files: 140 "$(sys.statedir)/MPF/." 141 create => "true"; 142 143 "$(sys.statedir)/MPF/desired-cfengine-package-version.json" 144 create => "true"; 145 146 "$(sys.statedir)/MPF/desired-cfengine-package-version.json" -> { "ENT-3592", "ENT-3937" } 147 edit_line => cfengine_software_version_data; 148 149 windows:: 150 "$(sys.bindir)$(const.dirsep)vercmp.ps1" 151 create => "true", 152 template_method => "mustache", 153 edit_template => "$(this.promise_dirname)$(const.dirsep)/templates/vercmp.ps1", 154 template_data => mergedata( '{}' ), 155 comment => "We need to use specialized version comparison logic for unattended self upgrades."; 156 157} 158 159bundle edit_line cfengine_software_version_data 160# @brief Populate data file with the package information 161# The data this bundle writes is used by the update policy to determine if the 162# standalone self upgrade policy should be run or not. 163# TODO Consider replacing with inline_mustache after 3.10.x is EOL 164{ 165 delete_lines: ".*"; 166 insert_lines: '{ 167"name": "$(cfengine_software.pkg_name)", 168"version": "$(cfengine_software.pkg_version)", 169"release": "$(cfengine_software.pkg_release)", 170"arch": "$(cfengine_software.pkg_arch)" 171}'; 172} 173 174bundle agent cfengine_software_cached_locally 175# @brief Ensure that the internal local software mirror is up to date 176{ 177 reports: 178 inform_mode:: 179 "Ensuring local software cache in $(local_software_dir) is up to date"; 180 181 vars: 182 "local_software_dir" 183 string => "$(cfengine_software.local_software_dir)"; 184 185 "package_dir" 186 string => "$(cfengine_software.package_dir)"; 187 188 "master_software_location" -> { "ENT-4953" } 189 string => "master_software_updates", 190 comment => "The Cfengine binary updates directory on the policy server", 191 handle => "cfe_internal_update_bins_vars_master_software_location"; 192 193 files: 194 "$(local_software_dir)/." 195 create => "true", 196 comment => "Ensure the local software directory exists for new binaries 197 to be downloaded to"; 198 199 # NOTE This is pegged to the single upstream policy hub, it won't fail 200 # over to a secondary for copying the binarys to update. 201 202 "$(local_software_dir)" 203 comment => "Copy binary updates from master source on policy server", 204 handle => "cfe_internal_update_bins_files_pkg_copy", 205 copy_from => u_dsync( "$(master_software_location)/$(package_dir)", $(sys.policy_hub) ), 206 file_select => plain, 207 depth_search => u_recurse_basedir(inf), 208 action => u_immediate, 209 classes => u_if_repaired("bin_newpkg"); 210 211} 212 213 214bundle agent cfengine_software_version 215# @brief Ensure the version of CFEngine installed is correct for supported 216# platforms. Different platforms leverage different implementations for self 217# upgrading. 218{ 219 classes: 220 "__supported_platform" -> { "ENT-5045", "ENT-5152", "ENT-4094" } 221 or => { 222 "redhat.!redhat_4", 223 "centos.!centos_4", 224 "debian", 225 "suse|opensuse", 226 "ubuntu", 227 "hpux", 228 "aix", 229 "windows", # ENT-4094 230 }; 231 232 # Add "windows" to __new_implementation classes with ENT-6823 233 "__new_implementation" 234 or => { "redhat", "centos", "ubuntu", "debian", "suse", "opensuse" }; 235 236 vars: 237 "pkg_name" string => "$(cfengine_software.pkg_name)"; 238 "pkg_version" string => "$(cfengine_software.pkg_version)"; 239 "pkg_release" string => "$(cfengine_software.pkg_release)"; 240 "_cf_version_release" string => ifelse( isvariable( "sys.cf_version_release" ), "$(sys.cf_version_release)", "1" ); 241 "pkg_arch" string => "$(cfengine_software.pkg_arch)"; 242 "package_dir" string => "$(cfengine_software.package_dir)"; 243 "local_software_dir" string => "$(cfengine_software.local_software_dir)"; 244 245 methods: 246 __supported_platform.__new_implementation:: 247 "Manage CFEngine Version" 248 usebundle => cfengine_software_version_packages2; 249 250 __supported_platform.!__new_implementation:: 251 "Manage CFEngine Version" 252 usebundle => cfengine_software_version_packages1; 253 254 # TODO, remove this and cfe_internal/enterprise/windows_unattended_upgrade.cf 255 # when ENT-6823 allows us to use msiexec.bat packages module. 256 "Windows Unattended Upgrade Workaround" 257 usebundle => windows_unattended_upgrade, 258 if => and( 259 "windows", 260 or( 261 not(strcmp("$(cfengine_software.pkg_version)", "$(sys.cf_version)")), 262 not(strcmp("$(cfengine_software.pkg_release)", "$(_cf_version_release)")) 263 ) 264 ); 265 266 reports: 267 !__supported_platform.inform_mode:: 268 "$(this.bundle) $(package_dir) is not supported"; 269} 270 271bundle agent cfengine_software_version_packages2 272# @brief Ensure the correct version of software is installed using the new packages promise implementation 273{ 274 vars: 275 "pkg_name" string => "$(cfengine_software.pkg_name)"; 276 "pkg_version" string => "$(cfengine_software.pkg_version)"; 277 "pkg_release" string => "$(cfengine_software.pkg_release)"; 278 "pkg_arch" string => "$(cfengine_software.pkg_arch)"; 279 "package_dir" string => "$(cfengine_software.package_dir)"; 280 "local_software_dir" string => "$(cfengine_software.local_software_dir)"; 281 282 packages: 283 284 (redhat|centos):: 285 "$(local_software_dir)/$(cfengine_package_names.my_pkg)" 286 policy => "present", 287 package_module => yum, 288 comment => "Ensure the latest package is installed"; 289 290 (debian|ubuntu):: 291 "$(local_software_dir)/$(cfengine_package_names.my_pkg)" 292 policy => "present", 293 package_module => apt_get, 294 comment => "Ensure the latest package is installed"; 295 296 (opensuse|suse):: 297 "$(local_software_dir)/$(cfengine_package_names.my_pkg)" 298 policy => "present", 299 package_module => zypper, 300 comment => "Ensure the latest package is installed"; 301 302 # TODO, uncomment the following to enable msiexec packages module (ENT-6823) 303# windows:: 304# "$(local_software_dir)$(const.dirsep)$(cfengine_package_names.my_pkg)" 305# policy => "present", 306# package_module => msiexec, 307# comment => "Ensure the latest package is installed"; 308 reports: 309 310 "DEBUG|DEBUG_$(this.bundle)":: 311 "Running $(this.bundle)"; 312} 313 314bundle agent cfengine_software_version_packages1 315# @brief Ensure the correct version of software is installed using the legacy self update mechanism 316#@ **Supported Platforms:** 317#@ - RedHat|Centos|Suse (rpm) 318#@ - Debian|Ubuntu (dpkg) 319#@ - solarisx86|solaris (pkgadd) 320#@ - windows (msiexec) 321#@ - aix (installp) 322#@ **Unsupported Platforms:** (but stubbed) 323#@ - freebsd|netbsd (pkg_add) 324{ 325 classes: 326 327 "cf_upgrade" expression => "(redhat|suse|sles|debian|solaris|solarisx86).!(am_policy_hub|policy_server)"; 328 329 vars: 330 331 # NOTE These logs are not actively used or cleaned up by anything. Their 332 # use will be phased as platforms migrate to the new packages 333 # implementation for self upgrades. 334 335 "local_update_log_dir" 336 string => translatepath("$(sys.workdir)/software_updates/update_log"), 337 comment => "Local directory to store update log for this host.", 338 handle => "cfe_internal_update_bins_vars_local_update_log_dir"; 339 340 "local_software_dir" string => "$(cfengine_software.local_software_dir)"; 341 342 "desired_version" -> { "ENT-4094" } 343 string => ifelse("linux", "$(cfengine_software.pkg_version)-$(cfengine_software.pkg_release)", 344 "windows", "$(cfengine_software.pkg_version).$(cfengine_software.pkg_release)", # ENT-4094 345 "aix", "$(cfengine_software.pkg_version).0", 346 $(cfengine_software.pkg_version) ), 347 comment => "The version attribute sometimes contains package release 348 information and sometimes does not. Here we construct the 349 version used in the package promise for the given 350 platform."; 351 352 cf_upgrade:: 353 354 # We only use cf-upgrade for some platforms, the need for it has been 355 # deprecated by the new packages promise implementation. 356 357 # backup script for cf-upgrade 358 # the script should have 2 conditions, BACKUP and RESTORE 359 # BACKUP and RESTORE status is $(const.dollar)1 variable in the script 360 # see more details at bundle edit_line u_backup_script 361 362 # NOTE cf-upgrade wants to execute from /tmp by default. This is 363 # problematic for systems where /tmp is mounted with no-exec. 364 365 "backup_script" string => "/tmp/cf-upgrade_backup.sh"; 366 367 # a single compressed backup file for cf-upgrade 368 # this backup_file is passed to backup_script as $(const.dollar)2 variable 369 # cf-upgrade will extract this file if return signal of upgrade command is not 0 370 371 "backup_file" string => "/tmp/cfengine-nova-$(sys.cf_version).tar.gz"; 372 373 # install script for cf-upgrade 374 # each distribution has its own way to upgrade a package 375 # see more details at bundle edit_line u_install_script 376 377 "install_script" string => "/tmp/cf-upgrade_install.sh"; 378 379 (solarisx86|solaris).enterprise:: 380 381 # to automatically remove or install packages on Solaris 382 # admin_file is a must to have to avoid pop-up interaction 383 # see more details at bundle edit_line u_admin_file 384 385 "admin_file" string => "/tmp/cf-upgrade_admin_file"; 386 387 files: 388 389 # Remote enterprise agents (non policy hubs) that have `trigger_upgrade` defined 390 391 cf_upgrade.enterprise.trigger_upgrade:: 392 393 "$(backup_script)" 394 comment => "Create a backup script for cf-upgrade", 395 handle => "cfe_internal_update_bins_files_backup_script", 396 create => "true", 397 if => "!windows", 398 edit_defaults => u_empty_no_backup, 399 edit_line => u_backup_script, 400 perms => u_m("0755"); 401 402 "$(install_script)" 403 comment => "Create an install script for cf-upgrade", 404 handle => "cfe_internal_update_bins_files_install_script", 405 create => "true", 406 if => "!windows", 407 edit_defaults => u_empty_no_backup, 408 edit_line => u_install_script, 409 perms => u_m("0755"); 410 411 "$(admin_file)" 412 comment => "Create solaris admin_file to automate remove and install packages", 413 handle => "cfe_internal_update_bins_files_solaris_admin_file", 414 create => "true", 415 edit_defaults => u_empty_no_backup, 416 edit_line => u_admin_file, 417 perms => u_m("0644"), 418 if => "solarisx86|solaris"; 419 420 packages: 421 # Only non policy hubs running are allowed to self upgrade 422 # We don't upgrade during bootstrap 423 424 !(am_policy_hub|policy_server|bootstrap_mode).enterprise_edition:: 425 426 "$(cfengine_software.pkg_name)" 427 comment => "Update Nova package to a newer version", 428 handle => "cfe_internal_update_bins_packages_nova_update", 429 package_policy => "update", 430 package_select => "==", 431 package_architectures => { "$(cfengine_software.pkg_arch)" }, 432 package_version => "$(desired_version)", 433 package_method => u_generic( $(cfengine_software.local_software_dir) ), 434 classes => u_if_else("bin_update_success", "bin_update_fail"); 435 436 reports: 437 438 "DEBUG|DEBUG_$(this.bundle)":: 439 "Running $(this.bundle)"; 440} 441 442bundle common cfengine_package_names 443# @brief Maps platforms to the package naming convention used by the self upgrade policy 444{ 445 vars: 446 "pkg_name" string => "$(cfengine_software.pkg_name)"; 447 "pkg_version" string => "$(cfengine_software.pkg_version)"; 448 "pkg_release" string => "$(cfengine_software.pkg_release)"; 449 "pkg_arch" string => "$(cfengine_software.pkg_arch)"; 450 451 # Redhat/Centos/Oracle 5, SLES 11 use the same package 452 453 "pkg[redhat_5_x86_64]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release).el5.centos.x86_64.rpm"; 454 "pkg[centos_5_x86_64]" string => "$(pkg[redhat_5_x86_64])"; 455 "pkg[oracle_5_x86_64]" string => "$(pkg[redhat_5_x86_64])"; 456 "pkg[SuSE_11_x86_64]" string => "$(pkg[redhat_5_x86_64])"; 457 458 # 32bit RPMs 459 "pkg[$(cfengine_master_software_content._rpm_dists)_$(cfengine_master_software_content._32bit_arches)]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release).el5.centos.i386.rpm"; 460 461 # Redhat/Centos/Oracle 6, SLES 12-15 use the same package 462 463 "pkg[redhat_6_x86_64]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release).el6.x86_64.rpm"; 464 "pkg[centos_6_x86_64]" string => "$(pkg[redhat_6_x86_64])"; 465 "pkg[oracle_6_x86_64]" string => "$(pkg[redhat_6_x86_64])"; 466 "pkg[SuSE_12_x86_64]" string => "$(pkg[redhat_6_x86_64])"; 467 "pkg[SuSE_15_x86_64]" string => "$(pkg[redhat_6_x86_64])"; 468 469 # Redhat/Centos/Oracle 7 use the same package 470 "pkg[redhat_7_x86_64]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release).el7.x86_64.rpm"; 471 "pkg[centos_7_x86_64]" string => "$(pkg[redhat_7_x86_64])"; 472 "pkg[oracle_7_x86_64]" string => "$(pkg[redhat_7_x86_64])"; 473 474 # Redhat/Centos/Oracle 8 use the same package 475 "pkg[redhat_8_x86_64]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release).el8.x86_64.rpm"; 476 "pkg[centos_8_x86_64]" string => "$(pkg[redhat_8_x86_64])"; 477 "pkg[oracle_8_x86_64]" string => "$(pkg[redhat_8_x86_64])"; 478 479 # 64bit Debian 480 481 "pkg[debian_7_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).debian7_amd64.deb"; 482 "pkg[debian_8_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).debian8_amd64.deb"; 483 "pkg[debian_9_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).debian9_amd64.deb"; 484 "pkg[debian_10_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).debian10_amd64.deb"; 485 486 # 64bit Ubuntu 487 "pkg[ubuntu_14_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).ubuntu14_amd64.deb"; 488 "pkg[ubuntu_16_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).ubuntu16_amd64.deb"; 489 "pkg[ubuntu_18_x86_64]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).ubuntu18_amd64.deb"; 490 491 # 32bit DEBs 492 493 "pkg[$(cfengine_master_software_content._deb_dists)_$(cfengine_master_software_content._32bit_arches)]" string => "$(pkg_name)_$(pkg_version)-$(pkg_release).debian7_i386.deb"; 494 495 # Windows 496 "pkg[windows_x86_64]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release)-x86_64.msi"; 497 "pkg[windows_i686]" string => "$(pkg_name)-$(pkg_version)-$(pkg_release)-i686.msi"; 498 "my_pkg" 499 string => "$(pkg[$(sys.flavor)_$(sys.arch)])", 500 comment => "The package name for the currently executing platform."; 501 502 reports: 503 504 "DEBUG|DEBUG_$(this.bundle)":: 505 506 "My Package: $(my_pkg)"; 507} 508 509bundle agent cfengine_master_software_content 510# @brief When cfengine_master_software_content_state_present is defined the software 511# will try be be automatically downloaded. 512{ 513 vars: 514 "pkg_name" string => "$(cfengine_software.pkg_name)"; 515 "pkg_version" string => "$(cfengine_software.pkg_version)"; 516 "pkg_release" string => "$(cfengine_software.pkg_release)"; 517 "pkg_arch" string => "$(cfengine_software.pkg_arch)"; 518 "package_dir" string => "$(cfengine_software.package_dir)"; 519 "pkg_edition" string => "$(cfengine_software.pkg_edition_path)"; 520 "base_url" string => "https://cfengine-package-repos.s3.amazonaws.com/$(pkg_edition)"; 521 522 # Map platform/directory identifier to upstream package URLs 523 # Better to read in an external explicit data structure? 524 525 "_32bit_arches" slist => { "i386", "i586", "i686" }; 526 527 # Redhat/Centos/Oracle 5 and SuSE 11 all use the same package 528 "dir[redhat_5_x86_64]" string => "agent_rpm_x86_64"; 529 "dir[centos_5_x86_64]" string => "$(dir[redhat_5_x86_64])"; 530 "dir[oracle_5_x86_64]" string => "$(dir[redhat_5_x86_64])"; 531 "dir[SuSE_11_x86_64]" string => "$(dir[redhat_5_x86_64])"; 532 533 # All 32bit rpms use the same package 534 "_rpm_dists" slist => { "redhat_5", "redhat_6", "redhat_7", 535 "centos_5", "centos_6", "centos_7", 536 "SuSE_11", "SuSE_10" }; 537 538 "dir[$(_rpm_dists)_$(_32bit_arches)]" string => "agent_rpm_i386"; 539 540 # Redhat/Centos/Oracle 6 use the same package 541 "dir[redhat_6_x86_64]" string => "agent_rhel6_x86_64"; 542 "dir[centos_6_x86_64]" string => "$(dir[redhat_6_x86_64])"; 543 "dir[oracle_6_x86_64]" string => "$(dir[redhat_6_x86_64])"; 544 545 # Redhat/Centos/Oracle 7 use the same package 546 "dir[redhat_7_x86_64]" string => "agent_rhel7_x86_64"; 547 "dir[centos_7_x86_64]" string => "$(dir[redhat_7_x86_64])"; 548 "dir[oracle_7_x86_64]" string => "$(dir[redhat_7_x86_64])"; 549 550 # Redhat/Centos/Oracle 8 use the same package 551 "dir[redhat_8_x86_64]" string => "agent_rhel8_x86_64"; 552 "dir[centos_8_x86_64]" string => "$(dir[redhat_8_x86_64])"; 553 "dir[oracle_8_x86_64]" string => "$(dir[redhat_8_x86_64])"; 554 555 # Debian 556 "dir[debian_7_x86_64]" string => "agent_deb_x86_64"; 557 "dir[debian_8_x86_64]" string => "agent_debian8_x86_64"; 558 "dir[debian_9_x86_64]" string => "agent_debian9_x86_64"; 559 "dir[debian_10_x86_64]" string => "agent_debian10_x86_64"; 560 561 # Ubuntu 562 "dir[ubuntu_14_x86_64]" string => "agent_ubuntu14_x86_64"; 563 "dir[ubuntu_16_x86_64]" string => "agent_ubuntu16_x86_64"; 564 "dir[ubuntu_18_x86_64]" string => "agent_ubuntu18_x86_64"; 565 566 # All 32bit debs use the same package 567 "_deb_dists" slist => { "debian_4", "debian_5", "debian_6", 568 "debian_7", "debian_8", "debian_9", 569 "debian_10", "ubuntu_14", "ubuntu_16", 570 "ubuntu_18" }; 571 572 "dir[$(_deb_dists)_$(_32bit_arches)]" string => "agent_deb_i386"; 573 574 "platform_dir" slist => getindices( dir ); 575 "download_dir" string => "$(sys.workdir)/master_software_updates"; 576 577 files: 578 "$(download_dir)/$(platform_dir)/." 579 create => "true", 580 comment => "We need a place to download each packge we build"; 581 582 commands: 583 # Fetch each package that we don't already have 584 "/usr/bin/curl" 585 args => "-s $(base_url)/$(dir[$(platform_dir)])/$(cfengine_package_names.pkg[$(platform_dir)]) --output /var/cfengine/master_software_updates/$(platform_dir)/$(cfengine_package_names.pkg[$(platform_dir)])", 586 if => not( fileexists( "$(download_dir)/$(platform_dir)/$(cfengine_package_names.pkg[$(platform_dir)])" ) ); 587 588 reports: 589 DEBUG|DEBUG_cfengine_master_software_content:: 590 "curl -s $(base_url)/$(dir[$(platform_dir)])/$(cfengine_package_names.pkg[$(platform_dir)]) --output $(download_dir)/$(platform_dir)/$(cfengine_package_names.pkg[$(platform_dir)])"; 591} 592 593bundle edit_line u_backup_script 594# @brief Backup script used by cf-upgrade 595{ 596 insert_lines: 597 598 linux:: 599 600 "#!/bin/sh 601 602if [ $(const.dollar)1 = \"BACKUP\" ]; then 603 tar cfzS $(const.dollar)2 $(sys.workdir) > /dev/null 604fi 605if [ $(const.dollar)1 = \"RESTORE\" ]; then 606 tar xfz $(const.dollar)2 607fi"; 608 609 solarisx86|solaris:: 610 611 "#!/bin/sh 612 613if [ $(const.dollar)1 = \"BACKUP\" ]; then 614 tar cf $(const.dollar)2 $(sys.workdir); gzip $(const.dollar)2 615fi 616if [ $(const.dollar)1 = \"RESTORE\" ]; then 617 gunzip $(const.dollar)2.gz; tar xf $(const.dollar)2 618fi"; 619 620} 621bundle edit_line u_install_script 622# @brief Install script used by cf-upgrade 623{ 624 insert_lines: 625 626 redhat|suse|sles:: 627 628 "#!/bin/sh 629 630/bin/rpm -U $(const.dollar)1"; 631 632 debian:: 633 634 "#!/bin/sh 635 636/usr/bin/dpkg --force-confdef --force-confnew --install $(const.dollar)1 > /dev/null"; 637 638 solarisx86|solaris:: 639 640 "#!/bin/sh 641 642pkgname=`pkginfo -d $(const.dollar)1 | awk '{print $(const.dollar)2}'` 643/usr/sbin/pkgrm -n -a $(cfengine_software_version_packages1.admin_file) $pkgname 644/usr/sbin/pkgadd -n -a $(cfengine_software_version_packages1.admin_file) -d $(const.dollar)1 all 645$(sys.workdir)/bin/cf-execd || true 646exit 0"; 647 648} 649 650 651bundle edit_line u_admin_file 652# @brief Admin file specification to enable unattended installation 653{ 654 insert_lines: 655 656 sunos_5_8:: 657 658 "mail= 659instance=unique 660partial=nocheck 661runlevel=nocheck 662idepend=nocheck 663rdepend=nocheck 664space=nocheck 665setuid=nocheck 666conflict=nocheck 667action=nocheck 668basedir=default"; 669 670 solaris.!sunos_5_8:: 671 672 "mail= 673instance=overwrite 674partial=nocheck 675runlevel=nocheck 676idepend=nocheck 677rdepend=nocheck 678space=nocheck 679setuid=nocheck 680conflict=nocheck 681action=nocheck 682networktimeout=60 683networkretries=3 684authentication=quit 685keystore=/var/sadm/security 686proxy= 687basedir=default"; 688 689} 690 691body action u_immediate 692# @brief Ignore promise locks, actuate the promise immediately 693{ 694 ifelapsed => "0"; 695} 696 697body copy_from u_dsync(from,server) 698# @brief Synchronize promiser with `from` on `server` using digest comparison. If host is a policy hub, then it skips the remote copy, preferring the local file path. For this reason, this body is not compatible with shortcuts defined by cf-serverd. 699# @param from File path to copy from on remote server 700# @param server Remote server to copy file from if executing host is not a policy server 701{ 702 # NOTE policy servers cheat and copy directly from the local file system. 703 # This works even if cf-serverd is down and it makes sense if your serving 704 # yourself. 705 706 source => "$(from)"; 707 compare => "digest"; 708 trustkey => "false"; 709 purge => "true"; 710 711 !am_policy_hub:: 712 713 servers => { "$(server)" }; 714 715 cfengine_internal_encrypt_transfers:: 716 717 encrypt => "true"; 718} 719 720body classes u_if_repaired(x) 721# @brief Define `x` if promise results in a repair 722# @param x Name of the class to be defined if promise results in repair 723{ 724 promise_repaired => { "$(x)" }; 725} 726body classes u_if_else(yes,no) 727# @brief Define `yes` if promise results in a repair, `no` if promise is not kept (failed, denied, timeout) 728# @param yes class to define if promise results in repair 729# @param no class to define if promise is not kept (failed, denied, timeout) 730{ 731 # promise_kept => { "$(yes)" }; 732 promise_repaired => { "$(yes)" }; 733 repair_failed => { "$(no)" }; 734 repair_denied => { "$(no)" }; 735 repair_timeout => { "$(no)" }; 736} 737 738body common control 739# @brief Common control for standalone self upgrade 740{ 741 version => "CFEngine Standalone Self Upgrade 3.19.0"; 742 743 (debian|ubuntu):: 744 package_inventory => { $(package_module_knowledge.platform_default) }; 745 746 # We only define pacakge_inventory on redhat like systems that have a 747 # python version that works with the package module. 748 749 (redhat|centos):: 750 package_inventory => { $(package_module_knowledge.platform_default) }; 751 752 (debian|redhat):: 753 package_module => $(package_module_knowledge.platform_default); 754} 755 756body depth_search u_recurse_basedir(d) 757# @brief Search recursively from (and including) the referenced directory directory to depth `d` excluding common version control paths 758# @param d maximum depth to descend 759{ 760 include_basedir => "true"; 761 depth => "$(d)"; 762 exclude_dirs => { "\.svn", "\.git", "git-core" }; 763} 764 765body edit_defaults u_empty_no_backup 766# @brief Do not create backups and ensure we are promising the entire content of 767# the file. 768{ 769 empty_file_before_editing => "true"; 770 edit_backup => "false"; 771} 772 773body file_select plain 774# @brief Select plain, regular files 775{ 776 file_types => { "plain" }; 777 file_result => "file_types"; 778} 779 780body package_method u_generic(repo) 781# @brief Generic package_method capable of managing packages on multiple platforms. 782# @param repo Local directory to look for packages in 783{ 784 785 debian:: 786 787 package_changes => "individual"; 788 package_list_command => "/usr/bin/dpkg -l"; 789 790 # package_list_update_command => "/usr/bin/apt-get update"; 791 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 792 793 package_list_name_regex => "ii\s+([^\s:]+).*"; 794 # package_list_version_regex => "ii\s+[^\s]+\s+([^\s]+).*"; 795 package_list_version_regex => "ii\s+[^\s]+\s+(\d+\.\d+((\.|-)\d+)+).*"; 796 797 package_installed_regex => ".*"; # all reported are installed 798 799 package_file_repositories => { "$(repo)" }; 800 package_version_equal_command => "/usr/bin/dpkg --compare-versions '$(v1)' eq '$(v2)'"; 801 package_version_less_command => "/usr/bin/dpkg --compare-versions '$(v1)' lt '$(v2)'"; 802 803 804 debian.x86_64:: 805 package_name_convention => "$(name)_$(version)_amd64.deb"; 806 807 debian.i686:: 808 package_name_convention => "$(name)_$(version)_i386.deb"; 809 810 debian:: 811 package_add_command => "/usr/bin/dpkg --force-confdef --force-confnew --install"; 812 package_delete_command => "/usr/bin/dpkg --purge"; 813 814 redhat|SuSE|suse|sles:: 815 816 package_changes => "individual"; 817 818 package_list_command => "/bin/rpm -qa --queryformat \"i | repos | %{name} | %{version}-%{release} | %{arch}\n\""; 819 820 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 821 822 package_list_name_regex => "[^|]+\|[^|]+\|\s+([^\s|]+).*"; 823 package_list_version_regex => "[^|]+\|[^|]+\|[^|]+\|\s+([^\s|]+).*"; 824 package_list_arch_regex => "[^|]+\|[^|]+\|[^|]+\|[^|]+\|\s+([^\s]+).*"; 825 826 package_installed_regex => "i.*"; 827 828 package_file_repositories => { "$(repo)" }; 829 830 package_name_convention => "$(name)-$(version).$(arch).rpm"; 831 832 package_add_command => "/bin/rpm -ivh "; 833 package_delete_command => "/bin/rpm -e --nodeps"; 834 package_verify_command => "/bin/rpm -V"; 835 package_noverify_regex => ".*[^\s].*"; 836 837 package_version_less_command => "$(sys.bindir)/rpmvercmp '$(v1)' lt '$(v2)'"; 838 package_version_equal_command => "$(sys.bindir)/rpmvercmp '$(v1)' eq '$(v2)'"; 839 840 (redhat|SuSE|suse|sles|debian|solarisx86|solaris):: 841 package_update_command => "$(sys.workdir)/bin/cf-upgrade -b $(cfengine_software_version_packages1.backup_script) -s $(cfengine_software_version_packages1.backup_file) -i $(cfengine_software_version_packages1.install_script)"; 842 843 redhat.!redhat_4:: 844 package_list_update_command => "/usr/bin/yum --quiet check-update"; 845 redhat_4:: 846 package_list_update_command => "/usr/bin/yum check-update"; 847 SuSE|suse|sles:: 848 package_list_update_command => "/usr/bin/zypper list-updates"; 849 850 windows:: 851 852 package_changes => "individual"; 853 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 854 package_file_repositories => { "$(repo)" }; 855 856 package_installed_regex => ".*"; 857 858 package_name_convention => "$(name)-$(version)-$(arch).msi"; 859 860 package_add_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; 861 package_update_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /i"; 862 package_delete_command => "\"$(sys.winsysdir)\msiexec.exe\" /qn /x"; 863 package_version_less_command => '$(sys.winsysdir)$(const.dirsep)WindowsPowerShell$(const.dirsep)v1.0$(const.dirsep)powershell.exe "$(sys.bindir)$(const.dirsep)vercmp.ps1" "$(v1)" "lt" "$(v2)"'; 864 package_version_equal_command => '$(sys.winsysdir)$(const.dirsep)WindowsPowerShell$(const.dirsep)v1.0$(const.dirsep)powershell.exe "$(sys.bindir)$(const.dirsep)vercmp.ps1" "$(v1)" "eq" "$(v2)"'; 865 866 freebsd:: 867 868 package_changes => "individual"; 869 870 package_list_command => "/usr/sbin/pkg_info"; 871 872 package_list_update_command => "/usr/bin/true"; 873 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 874 875 package_list_name_regex => "^(\S+)-(\d+\.?)+"; 876 package_list_version_regex => "^\S+-((\d+\.?)+\_\d)"; 877 878 package_file_repositories => { "$(repo)" }; 879 880 package_installed_regex => ".*"; 881 882 package_name_convention => "$(name)-$(version).tbz"; 883 package_delete_convention => "$(name)-$(version)"; 884 885 package_add_command => "/usr/sbin/pkg_add"; 886 package_delete_command => "/usr/sbin/pkg_delete"; 887 888 netbsd:: 889 890 package_changes => "individual"; 891 892 package_list_command => "/usr/sbin/pkg_info"; 893 894 package_list_update_command => "/usr/bin/true"; 895 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 896 897 package_list_name_regex => "^(\S+)-(\d+\.?)+"; 898 package_list_version_regex => "^\S+-((\d+\.?)+\nb\d)"; 899 900 package_file_repositories => { "$(repo)" }; 901 902 package_installed_regex => ".*"; 903 904 package_name_convention => "$(name)-$(version).tgz"; 905 package_delete_convention => "$(name)-$(version)"; 906 907 package_add_command => "/usr/sbin/pkg_add"; 908 package_delete_command => "/usr/sbin/pkg_delete"; 909 910 solarisx86|solaris:: 911 912 package_changes => "individual"; 913 package_list_command => "/usr/bin/pkginfo -l"; 914 package_list_update_command => "/usr/bin/true"; 915 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 916 917 package_multiline_start => "\s*PKGINST:\s+[^\s]+"; 918 package_list_name_regex => "\s*PKGINST:\s+([^\s]+)"; 919 package_list_version_regex => "\s*VERSION:\s+([^\s]+)"; 920 package_list_arch_regex => "\s*ARCH:\s+([^\s]+)"; 921 922 package_file_repositories => { "$(repo)" }; 923 924 package_installed_regex => "\s*STATUS:\s*(completely|partially)\s+installed.*"; 925 package_name_convention => "$(name)-$(version)-$(arch).pkg"; 926 package_delete_convention => "$(name)"; 927 928 # Cfengine appends path to package and package name below, respectively 929 package_add_command => "/bin/sh $(repo)/add_scr $(repo)/admin_file"; 930 package_delete_command => "/usr/sbin/pkgrm -n -a $(repo)/admin_file"; 931 932 aix:: 933 934 package_changes => "individual"; 935 936 package_list_update_command => "/usr/bin/true"; 937 package_list_update_ifelapsed => "$(u_common_knowledge.list_update_ifelapsed_now)"; 938 939 package_list_command => "/usr/bin/lslpp -lc"; 940 package_list_name_regex => "[^:]+:([^:]+):[^:]+:.*"; 941 package_list_version_regex => "[^:]+:[^:]+:([^:]+):.*"; 942 943 package_file_repositories => { "$(repo)" }; 944 945 package_installed_regex => "[^:]+:[^:]+:[^:]+:[^:]*:(COMMITTED|APPLIED):.*"; 946 947 package_name_convention => "$(name)-$(version).bff"; 948 package_delete_convention => "$(name)"; 949 950 # Redirecting the output to '/dev/null' below makes sure 'geninstall' has 951 # its stdout open even if the 'cf-agent' process that started it 952 # terminates (e.g. gets killed). 953 package_add_command => "/usr/bin/rm -f $(repo)/.toc && /usr/sbin/geninstall -IacgXNY -d $(repo) cfengine.cfengine-nova > /dev/null$"; 954 package_update_command => "/usr/bin/rm -f $(repo)/.toc && /usr/sbin/geninstall -IacgXNY -d $(repo) cfengine.cfengine-nova > /dev/null$"; 955 package_delete_command => "/usr/sbin/installp -ug cfengine.cfengine-nova$"; 956 957 # Internal version comparison model doesn't work for W.X.Y.Z 958 package_version_less_command => "$(sys.bindir)/rpmvercmp '$(v1)' lt '$(v2)'"; 959 package_version_equal_command => "$(sys.bindir)/rpmvercmp '$(v1)' eq '$(v2)'"; 960} 961 962body package_module yum 963# @brief Yum package module default settings 964{ 965 query_installed_ifelapsed => "10"; 966 query_updates_ifelapsed => "30"; 967@if minimum_version(3.12.2) 968 interpreter => "$(sys.bindir)/cfengine-selected-python"; 969@endif 970} 971 972body package_module apt_get 973# @brief apt_get package module default settings 974{ 975 query_installed_ifelapsed => "10"; 976 query_updates_ifelapsed => "30"; 977@if minimum_version(3.12.2) 978 interpreter => "$(sys.bindir)/cfengine-selected-python"; 979@endif 980} 981 982body package_module zypper 983{ 984 query_installed_ifelapsed => "0"; 985 query_updates_ifelapsed => "30"; 986 #default_options => {}; 987@if minimum_version(3.12.2) 988 interpreter => "$(sys.bindir)/cfengine-selected-python"; 989@endif 990} 991 992body package_module msiexec 993# @brief msiexec package module default settings 994{ 995 query_installed_ifelapsed => "10"; 996 query_updates_ifelapsed => "30"; 997@if minimum_version(3.12.2) 998 interpreter => "$(sys.winsysdir)$(const.dirsep)cmd.exe /c "; 999@endif 1000 module_path => "$(sys.workdir)$(const.dirsep)modules$(const.dirsep)packages$(const.dirsep)msiexec.bat"; 1001} 1002body perms u_m(p) 1003# @brief Ensure mode is `p` 1004# @param p permissions 1005{ 1006 mode => "$(p)"; 1007} 1008 1009body copy_from local_dcp(from) 1010# @brief Copy a local file if the hash on the source file differs. 1011# @param from The path to the source file. 1012# 1013# **Example:** 1014# 1015# ```cf3 1016# bundle agent example 1017# { 1018# files: 1019# "/tmp/file.bak" 1020# copy_from => local_dcp("/tmp/file"); 1021# } 1022# ``` 1023# 1024# **See Also:** `local_cp()`, `remote_dcp()` 1025{ 1026 source => "$(from)"; 1027 compare => "digest"; 1028} 1029