├── .gitignore ├── hiera.yaml ├── files └── auto_run.sh ├── Rakefile ├── lib ├── facter │ ├── munki_dir_exists.rb │ ├── munki_version_short.rb │ ├── munki_last_run_unix.rb │ ├── munki_running.rb │ ├── munki_last_run.rb │ ├── munki_version.rb │ ├── munki_self_serve_manifest.rb │ └── munki_managed_installs.rb └── puppet │ └── functions │ └── munki_item_installed.rb ├── .fixtures.yml ├── Gemfile ├── .github └── workflows │ └── tests.yml ├── LICENSE ├── manifests ├── install.pp ├── local_only_manifest.pp ├── auto_run.pp ├── init.pp ├── install_aio.pp ├── service.pp ├── config.pp └── install_components.pp ├── data └── common.yaml ├── Gemfile.lock └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .kitchen/ 2 | .kitchen.local.yml 3 | .bundle 4 | vendor/* -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | # munki/hiera.yaml 2 | --- 3 | version: 5 4 | defaults: 5 | datadir: data 6 | data_hash: yaml_data 7 | hierarchy: 8 | - name: "common" 9 | path: "common.yaml" 10 | -------------------------------------------------------------------------------- /files/auto_run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Ugh, bash. What can I say, I need a bit of pain occasionally? 4 | 5 | /usr/local/munki/managedsoftwareupdate --auto 6 | /bin/rm /Library/LaunchDaemons/org.munki.auto_run.plist 7 | /bin/rm /usr/local/munki/auto_run.sh 8 | 9 | exit 0 -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "puppetlabs_spec_helper/rake_tasks" 2 | require "rubocop/rake_task" 3 | 4 | RuboCop::RakeTask.new 5 | PuppetLint.configuration.send("disable_variable_scope") 6 | task :all do 7 | Rake::Task["lint"].invoke 8 | Rake::Task["syntax"].invoke 9 | end 10 | 11 | task default: [:all] 12 | -------------------------------------------------------------------------------- /lib/facter/munki_dir_exists.rb: -------------------------------------------------------------------------------- 1 | # munki_dir_exists.rb 2 | Facter.add(:munki_dir_exists) do 3 | confine kernel: "Darwin" 4 | setcode do 5 | if File.exist?("/usr/local/munki") && 6 | File.exist?("/Applications/Managed Software Center.app") 7 | true 8 | else 9 | false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/facter/munki_version_short.rb: -------------------------------------------------------------------------------- 1 | # munki_version_short.rb 2 | Facter.add(:munki_version_short) do 3 | confine kernel: "Darwin" 4 | setcode do 5 | munki_version = Facter.value(:munki_version) 6 | if munki_version == "Munki not installed" 7 | 0 8 | else 9 | munki_version[/^\d+\W\d+\W\d+/] 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /.fixtures.yml: -------------------------------------------------------------------------------- 1 | fixtures: 2 | symlinks: 3 | munki: "#{source_dir}" 4 | repositories: 5 | stdlib: "git://github.com/puppetlabs/puppetlabs-stdlib.git" 6 | mac_profiles_handler: "git://github.com/keeleysam/puppet-mac_profiles_handler.git" 7 | apple_package: 'git://github.com/macadmins/puppet-apple_package.git' 8 | mac_stdlib: 'git://github.com/macadmins/puppet-mac_stdlib.git' 9 | -------------------------------------------------------------------------------- /lib/facter/munki_last_run_unix.rb: -------------------------------------------------------------------------------- 1 | # munki_last_run_unix.rb 2 | 3 | require "time" 4 | 5 | Facter.add(:munki_last_run_unix) do 6 | confine kernel: "Darwin" 7 | setcode do 8 | last_run = 0 9 | munki_last_run = Facter.value(:munki_last_run) 10 | if munki_last_run == "never" 11 | last_run = 0 12 | else 13 | last_run = Time.parse(munki_last_run).to_i 14 | end 15 | last_run || 0 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/facter/munki_running.rb: -------------------------------------------------------------------------------- 1 | # munki_running.rb 2 | 3 | Facter.add(:munki_running) do 4 | confine kernel: "Darwin" 5 | setcode do 6 | running = false 7 | output = Facter::Util::Resolution.exec("/bin/ps -eo pid=,command=") 8 | output.each_line do |line| 9 | if line.include? "/usr/bin/python /usr/local/munki/managedsoftwareupdate" 10 | running = true 11 | break 12 | end 13 | end 14 | running 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | source "https://rubygems.org" 4 | 5 | gem "facter" 6 | gem "librarian-puppet" 7 | gem "puppet" 8 | gem "puppet-lint" 9 | gem "puppet-lint-absolute_template_path" 10 | gem "puppet-lint-legacy_facts-check" 11 | gem "puppet-lint-strict_indent-check" 12 | gem "puppet-lint-top_scope_facts-check" 13 | gem "puppet-lint-unquoted_string-check" 14 | gem "puppet-lint-variable_contains_upcase" 15 | gem "puppetlabs_spec_helper" 16 | gem "rspec-puppet" 17 | gem "rubocop" 18 | gem "rufo" 19 | -------------------------------------------------------------------------------- /lib/facter/munki_last_run.rb: -------------------------------------------------------------------------------- 1 | # munki_last_run.rb 2 | 3 | # Get the plist dynamically eventually 4 | report_plist = "/Library/Managed Installs/ManagedInstallReport.plist" 5 | 6 | Facter.add(:munki_last_run) do 7 | confine kernel: "Darwin" 8 | setcode do 9 | last_run = "never" 10 | if File.exist?(report_plist) 11 | require "puppet/util/plist" if Puppet.features.cfpropertylist? 12 | plist = Puppet::Util::Plist.read_plist_file(report_plist) 13 | last_run = plist["StartTime"] 14 | end 15 | last_run || "never" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/facter/munki_version.rb: -------------------------------------------------------------------------------- 1 | # munki_version.rb 2 | Facter.add(:munki_version) do 3 | confine kernel: "Darwin" 4 | setcode do 5 | if File.exist?("/usr/local/munki/managedsoftwareupdate") 6 | # rubocop:disable LineLength 7 | output = Facter::Util::Resolution.exec("/usr/local/munki/managedsoftwareupdate --version") 8 | # rubocop:enable LineLength 9 | if output =~ /^\d+\W\d+\W\d+\W\d+$/ 10 | output 11 | else 12 | "Munki not installed" 13 | end 14 | else 15 | "Munki not installed" 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push] 4 | 5 | jobs: 6 | test: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Set up Ruby 12 | uses: ruby/setup-ruby@v1 13 | with: 14 | ruby-version: 2.6 15 | - name: Install dependencies 16 | run: bundle install 17 | - name: Run Rufo 18 | run: bundle exec rufo --check . 19 | - name: puppet-lint 20 | uses: scottbrenner/puppet-lint-action@master 21 | with: 22 | args: --no-autoloader_layout-check . 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2017 Airbnb 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /lib/facter/munki_self_serve_manifest.rb: -------------------------------------------------------------------------------- 1 | # munki_self_serve_manifest.rb 2 | 3 | # Get the plist dynamically eventually 4 | self_serve_manifest = "/Library/Managed Installs/manifests/SelfServeManifest" 5 | 6 | Facter.add(:munki_self_serve_manifest) do 7 | confine kernel: "Darwin" 8 | setcode do 9 | if File.exist?(self_serve_manifest) 10 | require "puppet/util/plist" if Puppet.features.cfpropertylist? 11 | plist = Puppet::Util::Plist.read_plist_file(self_serve_manifest) 12 | managed_installs = plist["managed_installs"] 13 | managed_installs 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /lib/puppet/functions/munki_item_installed.rb: -------------------------------------------------------------------------------- 1 | Puppet::Functions.create_function(:munki_item_installed) do 2 | dispatch :munki_item_installed do 3 | required_param "String", :munki_item 4 | end 5 | 6 | def munki_item_installed(munki_item) 7 | munki_managed_installs = Facter.value("munki_managed_installs") 8 | # Nothing in here, return false 9 | return false if munki_managed_installs.nil? || munki_managed_installs.size.zero? 10 | 11 | if munki_managed_installs.include? munki_item 12 | # If a version has been specified, make sure it's that version installed 13 | return munki_managed_installs[munki_item]["installed"] 14 | end 15 | 16 | # If we're here, it's not installed, return false 17 | return false 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /manifests/install.pp: -------------------------------------------------------------------------------- 1 | # Install munki 2 | class munki::install { 3 | 4 | $munkitools_version = $munki::munkitools_version 5 | $days_before_broken = $munki::days_before_broken 6 | $package_source = $munki::package_source 7 | 8 | if $munki::use_aio { 9 | include munki::install_aio 10 | } 11 | else{ 12 | include munki::install_components 13 | } 14 | 15 | if $facts['munki_dir_exists'] == false { 16 | # Kick of a run if needed 17 | class { '::munki::auto_run': } 18 | } 19 | 20 | # Make sure everything is owned by root 21 | if $facts['munki_dir_exists'] == true { 22 | file {'/usr/local/munki': 23 | owner => 'root', 24 | group => 'wheel', 25 | recurse => true, 26 | max_files => -1, 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /manifests/local_only_manifest.pp: -------------------------------------------------------------------------------- 1 | # == Class: munki::local_only_manifest 2 | # 3 | class munki::local_only_manifest ( 4 | Array $managed_installs, 5 | Array $managed_uninstalls, 6 | String $manifest_name, 7 | ){ 8 | if !defined(File['/Library/Managed Installs']) { 9 | file { '/Library/Managed Installs': 10 | ensure => directory, 11 | } 12 | } 13 | 14 | if !defined(File['/Library/Managed Installs/manifests']) { 15 | file { '/Library/Managed Installs/manifests': 16 | ensure => directory, 17 | } 18 | } 19 | 20 | if $managed_installs == [] and $managed_uninstalls == [] { 21 | $ensure = 'absent' 22 | } else { 23 | $ensure = 'present' 24 | } 25 | 26 | $file_content = { 27 | 'managed_installs' => $managed_installs, 28 | 'managed_uninstalls' => $managed_uninstalls 29 | } 30 | 31 | file {"/Library/Managed Installs/manifests/${manifest_name}": 32 | ensure => $ensure, 33 | mode => '0644', 34 | owner => 0, 35 | group => 0, 36 | content => plist($file_content) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /manifests/auto_run.pp: -------------------------------------------------------------------------------- 1 | # Runs Munki after it has been installed 2 | 3 | class munki::auto_run { 4 | $auto_run_after_install = $munki::auto_run_after_install 5 | $munkitools_version = $munki::munkitools_version 6 | 7 | File { 8 | ensure => 'present', 9 | owner => 0, 10 | group => 0, 11 | } 12 | 13 | if $auto_run_after_install == true { 14 | $launchd = { 15 | 'Disabled' => false, 16 | 'Label' => 'org.munki.auto_run', 17 | 'ProgramArguments' => [ 18 | '/usr/local/munki/auto_run.sh' 19 | ], 20 | 'RunAtLoad' => true 21 | } 22 | 23 | if !defined(File['/usr/local/munki']){ 24 | file {'/usr/local/munki': 25 | ensure => directory 26 | } 27 | } 28 | 29 | file {'/usr/local/munki/auto_run.sh': 30 | mode => '0755', 31 | source => 'puppet:///modules/munki/auto_run.sh' 32 | } 33 | 34 | -> file {'/Library/LaunchDaemons/org.munki.auto_run.plist': 35 | mode => '0755', 36 | content => plist($launchd) 37 | } 38 | 39 | -> service {'org.munki.auto_run': 40 | ensure => 'running', 41 | enable => true, 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/facter/munki_managed_installs.rb: -------------------------------------------------------------------------------- 1 | # munki_managed_installs.rb 2 | 3 | report_plist = "/Library/Managed Installs/ManagedInstallReport.plist" 4 | 5 | Facter.add(:munki_managed_installs) do 6 | confine kernel: "Darwin" 7 | setcode do 8 | require "puppet/util/plist" if Puppet.features.cfpropertylist? 9 | output = {} 10 | if File.exist?(report_plist) 11 | plist = Puppet::Util::Plist.read_plist_file(report_plist) 12 | if plist.include? "ManagedInstalls" 13 | plist["ManagedInstalls"].each do |install| 14 | # This was added in Munki 2.8, handle that 15 | installed_version = if install.include? "installed_version" 16 | install["installed_version"] 17 | else 18 | "unknown" 19 | end 20 | # rubocop:disable AlignHash 21 | output[install["name"]] = { 22 | "display_name" => install["display_name"], 23 | "name" => install["name"], 24 | "installed" => install["installed"], 25 | "installed_size" => install["installed_size"], 26 | "installed_version" => installed_version, 27 | } 28 | # rubocop:enable AlignHash 29 | end 30 | end 31 | end 32 | 33 | output 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | munki::munkitools_version: '3.3.0.3515' 3 | munki::apple_software_updates_only: false 4 | munki::client_cert_path: "%{facts.ssldir}/certs/%{facts.certname}.pem" 5 | munki::client_identifier: '' 6 | munki::client_key_path: "%{facts.ssldir}/private_keys/%{facts.certname}.pem" 7 | munki::days_between_notifications: 1 8 | munki::install_apple_software_updates: true 9 | munki::unattended_apple_updates: false 10 | munki::logging_level: 1 11 | munki::log_to_syslog: false 12 | munki::msu_log_enabled: false 13 | munki::software_repo_ca_cert: "%{facts.ssldir}/certs/ca.pem" 14 | munki::software_repo_url: '' 15 | munki::software_update_server_url: '' 16 | munki::suppress_loginwindow_install: false 17 | munki::suppress_user_notification: false 18 | munki::use_client_cert: false 19 | munki::show_removal_detail: false 20 | munki::days_before_broken: 60 21 | munki::additional_http_headers: [] 22 | munki::payload_organization: '' 23 | munki::package_source: '' 24 | munki::auto_run_after_install: true 25 | munki::perform_auth_restarts: false 26 | munki::recovery_key_file: '' 27 | munki::use_notification_center_days: 3 28 | munki::managed_installs: [] 29 | munki::managed_uninstalls: [] 30 | munki::show_optional_installs_for_higher_os_versions: false 31 | munki::local_only_manifest_name: 'extra_packages' 32 | munki::use_aio: false 33 | munki::munkitools_admin_checksum: '' 34 | munki::munkitools_admin_receipt: '' 35 | munki::munkitools_admin_source: '' 36 | munki::munkitools_admin_version: '' 37 | munki::munkitools_app_usage_checksum: '' 38 | munki::munkitools_app_usage_receipt: '' 39 | munki::munkitools_app_usage_source: '' 40 | munki::munkitools_app_usage_version: '' 41 | munki::munkitools_checksum: '' 42 | munki::munkitools_core_checksum: '' 43 | munki::munkitools_core_receipt: '' 44 | munki::munkitools_core_source: '' 45 | munki::munkitools_core_version: '' 46 | munki::munkitools_receipt: '' 47 | munki::munkitools_source: '' 48 | munki::munkitools_launchd_checksum: '' 49 | munki::munkitools_launchd_receipt: '' 50 | munki::munkitools_launchd_source: '' 51 | munki::munkitools_launchd_version: '' 52 | munki::munkitools_python_checksum: '' 53 | munki::munkitools_python_receipt: '' 54 | munki::munkitools_python_source: '' 55 | munki::munkitools_python_version: '' 56 | munki::http_user: '' 57 | munki::http_password: '' 58 | munki::munki_python: true 59 | munki::manage_profile: true 60 | munki::aggressive_update_notification_days: 14 -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # Class: munki 2 | # 3 | # Installs and configures munki 4 | # you must specify your own munki repo URL; please don't use http://munki and instead use a https URL. 5 | 6 | class munki ( 7 | Boolean $apple_software_updates_only, 8 | String $client_cert_path, 9 | String $client_identifier, 10 | String $client_key_path, 11 | Integer $days_between_notifications, 12 | Boolean $install_apple_software_updates, 13 | Boolean $unattended_apple_updates, 14 | Integer $logging_level, 15 | Boolean $log_to_syslog, 16 | Boolean $msu_log_enabled, 17 | String $software_repo_ca_cert, 18 | String $software_repo_url, 19 | String $software_update_server_url, 20 | Boolean $suppress_user_notification, 21 | Boolean $suppress_loginwindow_install, 22 | Boolean $use_client_cert, 23 | Boolean $show_removal_detail, 24 | Integer $days_before_broken, 25 | Array $additional_http_headers, 26 | String $payload_organization, 27 | String $package_source, 28 | String $munkitools_source, 29 | String $munkitools_core_source, 30 | String $munkitools_admin_source, 31 | String $munkitools_app_usage_source, 32 | String $munkitools_launchd_source, 33 | String $munkitools_python_source, 34 | String $munkitools_receipt, 35 | String $munkitools_core_receipt, 36 | String $munkitools_admin_receipt, 37 | String $munkitools_app_usage_receipt, 38 | String $munkitools_launchd_receipt, 39 | String $munkitools_python_receipt, 40 | String $munkitools_checksum, 41 | String $munkitools_core_checksum, 42 | String $munkitools_admin_checksum, 43 | String $munkitools_app_usage_checksum, 44 | String $munkitools_launchd_checksum, 45 | String $munkitools_python_checksum, 46 | String $munkitools_version, 47 | String $munkitools_core_version, 48 | String $munkitools_admin_version, 49 | String $munkitools_app_usage_version, 50 | String $munkitools_launchd_version, 51 | String $munkitools_python_version, 52 | Boolean $auto_run_after_install, 53 | Boolean $perform_auth_restarts, 54 | String $recovery_key_file, 55 | Integer $use_notification_center_days, 56 | Array $managed_installs, 57 | Array $managed_uninstalls, 58 | Boolean $show_optional_installs_for_higher_os_versions, 59 | String $local_only_manifest_name, 60 | Boolean $use_aio, 61 | String $http_user, 62 | String $http_password, 63 | Boolean $munki_python, 64 | Boolean $manage_profile, 65 | Integer $aggressive_update_notification_days, 66 | ) 67 | { 68 | class { '::munki::config': } 69 | -> class { '::munki::install': } 70 | -> class { '::munki::service': } 71 | -> Class['munki'] 72 | 73 | } 74 | -------------------------------------------------------------------------------- /manifests/install_aio.pp: -------------------------------------------------------------------------------- 1 | class munki::install_aio { 2 | $days_before_broken = $munki::days_before_broken 3 | $package_source = $munki::package_source 4 | $munkitools_source = $munki::munkitools_source 5 | $munkitools_version = $munki::munkitools_version 6 | 7 | if $package_source != '' { 8 | $actual_package_source = $package_source 9 | } elsif $munkitools_source != '' { 10 | $actual_package_source = $munkitools_source 11 | } else { 12 | $actual_package_source = "puppet:///modules/bigfiles/munki/munkitools-${munkitools_version}.pkg" 13 | } 14 | 15 | 16 | # $today = strftime('%s') 17 | $now = time() 18 | # $today - (86400 seconds in a day * $days_before_broken) 19 | $broken_days_ago = $now - (86400 * $days_before_broken) 20 | if $facts['munki_last_run_unix'] > 0 and 21 | $facts['munki_last_run_unix'] < $broken_days_ago and 22 | $facts['munki_running'] == false { 23 | $force_install = true 24 | } 25 | elsif ($facts['munki_dir_exists'] == false or 26 | $facts['munki_version'] == 0 or 27 | versioncmp($facts['munki_version'], $munkitools_version) < 0) and 28 | $facts['munki_running'] == false { 29 | $force_install = true 30 | exec {'forget_munki_pkgs': 31 | command => '/bin/rm -rf /usr/local/munki/munkilib 32 | /usr/sbin/pkgutil --forget com.googlecode.munki.admin 33 | /usr/sbin/pkgutil --forget com.googlecode.munki.app 34 | /usr/sbin/pkgutil --forget com.googlecode.munki.core 35 | /usr/sbin/pkgutil --forget com.googlecode.munki.launchd 36 | /usr/sbin/pkgutil --forget com.googlecode.munki.app_usage 37 | /usr/sbin/pkgutil --forget com.googlecode.munki.python 38 | exit 0', 39 | before => Apple_package['munkitools'] 40 | } 41 | } else { 42 | $force_install = false 43 | } 44 | 45 | apple_package { 'munkitools': 46 | source => $actual_package_source, 47 | version => $munkitools_version, 48 | receipt => 'com.googlecode.munki.core', 49 | installs => ['/Applications/Managed Software Center.app/Contents/MacOS/Managed Software Center', '/usr/local/munki/managedsoftwareupdate'], # lint:ignore:140chars 50 | force_install => $force_install, 51 | notify => [ 52 | Exec['munki_reload_launchagents'], 53 | Service['com.googlecode.munki.managedsoftwareupdate-check'], 54 | Service['com.googlecode.munki.managedsoftwareupdate-install'], 55 | Service['com.googlecode.munki.managedsoftwareupdate-manualcheck'] 56 | ], 57 | http_checksum => $munki::munkitools_checksum, 58 | http_username => $munki::http_user, 59 | http_password => $munki::http_password 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | ast (2.4.2) 5 | concurrent-ruby (1.1.9) 6 | deep_merge (1.2.1) 7 | diff-lcs (1.4.4) 8 | facter (4.2.0) 9 | hocon (~> 1.3) 10 | thor (>= 1.0.1, < 2.0) 11 | faraday (0.17.4) 12 | multipart-post (>= 1.2, < 3) 13 | faraday_middleware (0.14.0) 14 | faraday (>= 0.7.4, < 1.0) 15 | fast_gettext (1.1.2) 16 | gettext (3.2.9) 17 | locale (>= 2.0.5) 18 | text (>= 1.3.0) 19 | gettext-setup (0.34) 20 | fast_gettext (~> 1.1.0) 21 | gettext (>= 3.0.2, < 3.3.0) 22 | locale 23 | hiera (3.7.0) 24 | hocon (1.3.1) 25 | librarian-puppet (3.0.1) 26 | librarianp (>= 0.6.3) 27 | puppet_forge (~> 2.1) 28 | rsync 29 | librarianp (1.0.0) 30 | thor (~> 1.0) 31 | locale (2.1.3) 32 | minitar (0.9) 33 | mocha (1.12.0) 34 | multi_json (1.15.0) 35 | multipart-post (2.1.1) 36 | parallel (1.20.1) 37 | parser (3.0.1.1) 38 | ast (~> 2.4.1) 39 | pathspec (1.0.0) 40 | puppet (7.12.1) 41 | concurrent-ruby (~> 1.0) 42 | deep_merge (~> 1.0) 43 | facter (> 2.0.1, < 5) 44 | fast_gettext (~> 1.1) 45 | hiera (>= 3.2.1, < 4) 46 | locale (~> 2.1) 47 | multi_json (~> 1.10) 48 | puppet-resource_api (~> 1.5) 49 | scanf (~> 1.0) 50 | semantic_puppet (~> 1.0) 51 | puppet-lint (2.4.2) 52 | puppet-lint-absolute_template_path (1.0.1) 53 | puppet-lint (>= 1.1, < 3.0) 54 | puppet-lint-legacy_facts-check (1.0.4) 55 | puppet-lint (~> 2.4) 56 | puppet-lint-strict_indent-check (2.0.7) 57 | puppet-lint (> 1.0) 58 | puppet-lint-top_scope_facts-check (1.0.1) 59 | puppet-lint (~> 2.0) 60 | puppet-lint-unquoted_string-check (2.0.0) 61 | puppet-lint (>= 2.1, < 3.0) 62 | puppet-lint-variable_contains_upcase (1.2.0) 63 | puppet-lint (>= 1.0, < 3.0) 64 | puppet-resource_api (1.8.14) 65 | hocon (>= 1.0) 66 | puppet-syntax (3.1.0) 67 | puppet (>= 5) 68 | rake 69 | puppet_forge (2.3.4) 70 | faraday (>= 0.9.0, < 0.18.0, != 0.13.1) 71 | faraday_middleware (>= 0.9.0, < 0.15.0) 72 | gettext-setup (~> 0.11) 73 | minitar 74 | semantic_puppet (~> 1.0) 75 | puppetlabs_spec_helper (3.0.0) 76 | mocha (~> 1.0) 77 | pathspec (>= 0.2.1, < 1.1.0) 78 | puppet-lint (~> 2.0) 79 | puppet-syntax (>= 2.0, < 4) 80 | rspec-puppet (~> 2.0) 81 | rainbow (3.0.0) 82 | rake (13.0.3) 83 | regexp_parser (2.1.1) 84 | rexml (3.2.5) 85 | rspec (3.10.0) 86 | rspec-core (~> 3.10.0) 87 | rspec-expectations (~> 3.10.0) 88 | rspec-mocks (~> 3.10.0) 89 | rspec-core (3.10.1) 90 | rspec-support (~> 3.10.0) 91 | rspec-expectations (3.10.1) 92 | diff-lcs (>= 1.2.0, < 2.0) 93 | rspec-support (~> 3.10.0) 94 | rspec-mocks (3.10.2) 95 | diff-lcs (>= 1.2.0, < 2.0) 96 | rspec-support (~> 3.10.0) 97 | rspec-puppet (2.9.0) 98 | rspec 99 | rspec-support (3.10.2) 100 | rsync (1.0.9) 101 | rubocop (1.16.0) 102 | parallel (~> 1.10) 103 | parser (>= 3.0.0.0) 104 | rainbow (>= 2.2.2, < 4.0) 105 | regexp_parser (>= 1.8, < 3.0) 106 | rexml 107 | rubocop-ast (>= 1.7.0, < 2.0) 108 | ruby-progressbar (~> 1.7) 109 | unicode-display_width (>= 1.4.0, < 3.0) 110 | rubocop-ast (1.7.0) 111 | parser (>= 3.0.1.1) 112 | ruby-progressbar (1.11.0) 113 | rufo (0.13.0) 114 | scanf (1.0.0) 115 | semantic_puppet (1.0.4) 116 | text (1.3.1) 117 | thor (1.1.0) 118 | unicode-display_width (2.0.0) 119 | 120 | PLATFORMS 121 | ruby 122 | 123 | DEPENDENCIES 124 | facter 125 | librarian-puppet 126 | puppet 127 | puppet-lint 128 | puppet-lint-absolute_template_path 129 | puppet-lint-legacy_facts-check 130 | puppet-lint-strict_indent-check 131 | puppet-lint-top_scope_facts-check 132 | puppet-lint-unquoted_string-check 133 | puppet-lint-variable_contains_upcase 134 | puppetlabs_spec_helper 135 | rspec-puppet 136 | rubocop 137 | rufo 138 | 139 | BUNDLED WITH 140 | 1.17.3 141 | -------------------------------------------------------------------------------- /manifests/service.pp: -------------------------------------------------------------------------------- 1 | # Ensure munki's services are running 2 | class munki::service { 3 | 4 | $post_v3_agents_cmd = '# get console UID 5 | consoleuser=`/usr/bin/stat -f "%u" /dev/console` 6 | 7 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.ManagedSoftwareCenter.plist 8 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.MunkiStatus.plist 9 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.managedsoftwareupdate-loginwindow.plist 10 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.munki-notifier.plist 11 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.ManagedSoftwareCenter.plist 12 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.MunkiStatus.plist 13 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.managedsoftwareupdate-loginwindow.plist 14 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.munki-notifier.plist 15 | 16 | exit 0' 17 | 18 | service { 'com.googlecode.munki.managedsoftwareupdate-check': 19 | ensure => 'running', 20 | enable => true, 21 | } 22 | 23 | service { 'com.googlecode.munki.managedsoftwareupdate-install': 24 | ensure => 'running', 25 | enable => true, 26 | } 27 | 28 | -> service { 'com.googlecode.munki.managedsoftwareupdate-manualcheck': 29 | ensure => 'running', 30 | enable => true, 31 | } 32 | 33 | if versioncmp($facts['munki_version'], '3.3.0') >= 0 { 34 | service { 'com.googlecode.munki.appusaged': 35 | ensure => 'running', 36 | enable => true, 37 | require => Service['com.googlecode.munki.managedsoftwareupdate-manualcheck'] 38 | } 39 | 40 | -> exec { 'munki_reload_launchagents': 41 | command => $post_v3_agents_cmd, 42 | path => '/bin:/sbin:/usr/bin:/usr/sbin', 43 | provider => 'shell', 44 | refreshonly => true, 45 | notify => Exec['munki_app_usage_agent'] 46 | } 47 | 48 | -> exec {'munki_app_usage_agent': 49 | command => '# get console UID 50 | consoleuser=`/usr/bin/stat -f "%u" /dev/console` 51 | 52 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.app_usage_monitor.plist 53 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.app_usage_monitor.plist 54 | 55 | exit 0', 56 | path => '/bin:/sbin:/usr/bin:/usr/sbin', 57 | provider => 'shell', 58 | refreshonly => true, 59 | } 60 | 61 | exec {'munki unload old app usgae': 62 | command => '/bin/launchctl unload /Library/LaunchDaemons/com.googlecode.munki.app_usage_monitor.plist 63 | exit 0', 64 | provider => 'shell', 65 | refreshonly => true, 66 | before => File['/Library/LaunchDaemons/com.googlecode.munki.app_usage_monitor.plist'] 67 | } 68 | 69 | -> file {'/Library/LaunchDaemons/com.googlecode.munki.app_usage_monitor.plist': 70 | ensure => absent 71 | } 72 | 73 | } 74 | 75 | elsif versioncmp($facts['munki_version'], '3.0.0') >= 0 { 76 | service { 'com.googlecode.munki.app_usage_monitor': 77 | ensure => 'running', 78 | enable => true, 79 | require => Service['com.googlecode.munki.managedsoftwareupdate-manualcheck'] 80 | } 81 | 82 | -> exec { 'munki_reload_launchagents': 83 | command => $post_v3_agents_cmd, 84 | path => '/bin:/sbin:/usr/bin:/usr/sbin', 85 | provider => 'shell', 86 | refreshonly => true, 87 | } 88 | } else { 89 | exec { 'munki_reload_launchagents': 90 | command => '# get console UID 91 | consoleuser=`/usr/bin/stat -f "%u" /dev/console` 92 | 93 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.ManagedSoftwareCenter.plist 94 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.MunkiStatus.plist 95 | /bin/launchctl bootout gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.managedsoftwareupdate-loginwindow.plist 96 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.ManagedSoftwareCenter.plist 97 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.MunkiStatus.plist 98 | /bin/launchctl bootstrap gui/$consoleuser /Library/LaunchAgents/com.googlecode.munki.managedsoftwareupdate-loginwindow.plist 99 | 100 | exit 0', 101 | path => '/bin:/sbin:/usr/bin:/usr/sbin', 102 | provider => 'shell', 103 | refreshonly => true, 104 | require => Service['com.googlecode.munki.managedsoftwareupdate-manualcheck'] 105 | } 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # puppet-munki 2 | 3 | This module installs and configures a [Munki client](https://github.com/munki/munki). 4 | 5 | ## Changes in version 2 of this module 6 | 7 | ### Support for remote files 8 | 9 | If you use Autopkg to download Munki, it may be more convenient to host the files on your Munki repo. This module now can make use of [remote_file](https://forge.puppet.com/lwf/remote_file) so you do not need to host your packages on your Puppet server. The module will determine whether to use the Puppet fileserver or remote_package depending on whether `puppet:///` is in your source or not. 10 | 11 | ### Use of component packages 12 | 13 | The module can use the individual packages that autopkg generates. If you wish to continue using the all in one package, you should set `munki::use_aio` to `true`. 14 | 15 | ## Configuring with Hiera 16 | 17 | ```yaml 18 | --- 19 | classes: 20 | - munki 21 | 22 | munki::use_client_cert: false 23 | munki::software_repo_url: "https://munki.example.com" 24 | munki::additional_http_headers: ["Authorization: Basic abc12345=="] 25 | munki::package_source: "puppet:///modules/a_module_with_munkis_pkg/munkitools.pkg" 26 | munki::days_before_broken: 14 27 | ``` 28 | 29 | ## Configuring directly in Puppet 30 | 31 | ```puppet 32 | class {'munki': 33 | use_client_cert => false, 34 | software_repo_url => "https://munki.example.com", 35 | additional_http_headers => ['Authorization: Basic abc12345=='], 36 | package_source => "puppet:///modules/a_module_with_munkis_pkg/munkitools.pkg", 37 | days_before_broken => 14, 38 | } 39 | ``` 40 | 41 | For all of the configuration options, see `data/common.yaml`. Most options correlate directly with their equivalent Munki preference. 42 | 43 | ## Options that aren't Munki options 44 | 45 | ### auto_run_after_install 46 | 47 | This will deploy a LaunchDaemon that will run `managedsoftwareupdate --auto` once before cleaning up after itself. This will allow Munki to begin it's run during your Puppet run without blocking the rest of your Puppet config. 48 | 49 | ### payload_organization 50 | 51 | The organization that is displayed in the configuration profile. 52 | 53 | ### days_before_broken 54 | 55 | The number of days since the last successful run after which Munki is considered 'broken' and will be reinstalled. 56 | 57 | ### munkitools_version 58 | 59 | The version of Munki you wish to install. This is the output of `managedsoftwareupdate --version`. 60 | 61 | ### package_source 62 | 63 | The path to the install package on your Puppet server. Defaults to `puppet:///modules/bigfiles/munki/munkitools-${munkitools_version}.pkg`, which means that the install package should be in the `bigfiles` module, in `files/munki`, named to match the version. 64 | 65 | ### local_only_manifest_name 66 | 67 | This is the file name of the local manifest. This defaults to `extra_packages`, so if you have a manifest called this on your server, you should change it to something unique. 68 | 69 | ## Local managed_installs and managed_uninstalls 70 | 71 | This module is able to make use of local only manifests, which allows you to use Hiera to assign software to your nodes. As this composites the configuration from all levels of your hierarchy via the `lookup` function, you _must_ use Hiera (rather than Puppet code directly) to configure this. 72 | 73 | ## munki_python 74 | 75 | Set this to false if you do not wish Munki to install it's own Python. 76 | 77 | ```yaml 78 | # data/serial_number/YOURSERIALNUMBER.yaml 79 | munki::managed_installs: 80 | - 'windows10_vm' 81 | 82 | munki::managed_uninstalls: 83 | - 'AdobeFlashPlayer' 84 | ``` 85 | 86 | Using the `lookup` function allows you to specify managed installs and uninstalls at different places in your hierarchy, so for example, you can specify installs for all of your machines using something like the below: 87 | 88 | ```yaml 89 | # data/osfamily/Darwin.yaml 90 | munki::managed_installs: 91 | - "GoogleChrome" 92 | ``` 93 | 94 | And then configuring a one off install for a particular machine: 95 | 96 | ```yaml 97 | # data/serial_number/ABC123.yaml 98 | munki::managed_installs: 99 | - "Firefox" 100 | ``` 101 | 102 | Which would produce a local client manifest (at `/Library/Managed Installs/manifests/extra_packages`) for the machine with the serial number ABC123 of: 103 | 104 | ```xml 105 | 106 | 107 | 108 | 109 | managed_installs 110 | 111 | windows10_vm 112 | 113 | managed_uninstalls 114 | 115 | 116 | 117 | ``` 118 | 119 | ## Requirements 120 | 121 | - [apple_package](https://github.com/macadmins/puppet-apple_package) 122 | - [client_stdlib](https://github.com/macadmins/puppet-client_stdlib) 123 | - [stdlib](https://forge.puppetlabs.com/puppetlabs/stdlib) 124 | - [mac_profiles_handler](https://github.com/macadmins/puppet-mac_profiles_handler) 125 | -------------------------------------------------------------------------------- /manifests/config.pp: -------------------------------------------------------------------------------- 1 | # Configure munki via dynamic profile 2 | class munki::config { 3 | $aggressive_update_notification_days = $munki::aggressive_update_notification_days 4 | $apple_software_updates_only = $munki::apple_software_updates_only 5 | $client_cert_path = $munki::client_cert_path 6 | $client_identifier = $munki::client_identifier 7 | $client_key_path = $munki::client_key_path 8 | $days_between_notifications = $munki::days_between_notifications 9 | $install_apple_software_updates = $munki::install_apple_software_updates 10 | $unattended_apple_updates = $munki::unattended_apple_updates 11 | $logging_level = $munki::logging_level 12 | $log_to_syslog = $munki::log_to_syslog 13 | $msu_log_enabled = $munki::msu_log_enabled 14 | $software_repo_ca_cert = $munki::software_repo_ca_cert 15 | $software_repo_url = $munki::software_repo_url 16 | $software_update_server_url = $munki::software_update_server_url 17 | $suppress_user_notification = $munki::suppress_user_notification 18 | $suppress_loginwindow_install = $munki::suppress_loginwindow_install 19 | $use_client_cert = $munki::use_client_cert 20 | $additional_http_headers = $munki::additional_http_headers 21 | $payload_organization = $munki::payload_organization 22 | $show_removal_detail = $munki::show_removal_detail 23 | $recovery_key_file = $munki::recovery_key_file 24 | $perform_auth_restarts = $munki::perform_auth_restarts 25 | $use_notification_center_days = $munki::use_notification_center_days 26 | $show_optional_installs_for_higher_os_versions = $munki::show_optional_installs_for_higher_os_versions 27 | $local_only_manifest_name = $munki::local_only_manifest_name 28 | $manage_profile = $munki::manage_profile 29 | 30 | $mcx_settings = { 31 | 'AdditionalHttpHeaders' => $additional_http_headers, 32 | 'AggressiveUpdateNotificationDays' => $aggressive_update_notification_days, 33 | 'AppleSoftwareUpdatesOnly' => $apple_software_updates_only, 34 | 'ClientIdentifier' => $client_identifier, 35 | 'DaysBetweenNotifications' => $days_between_notifications, 36 | 'InstallAppleSoftwareUpdates' => $install_apple_software_updates, 37 | 'UnattendedAppleUpdates' => $unattended_apple_updates, 38 | 'LoggingLevel' => $logging_level, 39 | 'LogToSyslog' => $log_to_syslog, 40 | 'MSULogEnabled' => $msu_log_enabled, 41 | 'SoftwareRepoURL' => $software_repo_url, 42 | 'SuppressLoginwindowInstall' => $suppress_loginwindow_install, 43 | 'SuppressUserNotification' => $suppress_user_notification, 44 | 'UseClientCertificate' => $use_client_cert, 45 | 'ShowRemovalDetail' => $show_removal_detail, 46 | 'PerformAuthRestarts' => $perform_auth_restarts, 47 | 'RecoveryKeyFile' => $recovery_key_file, 48 | 'UseNotificationCenterDays' => $use_notification_center_days, 49 | 'ShowOptionalInstallsForHigherOSVersions' => $show_optional_installs_for_higher_os_versions 50 | } 51 | $managed_installs = lookup('munki::managed_installs', Array, 'unique', []) 52 | $managed_uninstalls = lookup('munki::managed_uninstalls', Array, 'unique', []) 53 | 54 | if $use_client_cert == true { 55 | $cert_settings = {'ClientCertificatePath' => $client_cert_path, 'ClientKeyPath' => $client_key_path, 'SoftwareRepoCACertificate' => $software_repo_ca_cert} 56 | $settings_with_cert = merge($mcx_settings, $cert_settings) 57 | } else { 58 | $settings_with_cert = $mcx_settings 59 | } 60 | 61 | if $software_update_server_url != '' { 62 | $sus_settings = {'software_update_server_url' => $software_update_server_url} 63 | $settings_with_sus_url = merge($settings_with_cert, $sus_settings) 64 | } else { 65 | $settings_with_sus_url = $settings_with_cert 66 | } 67 | 68 | if $managed_installs != [] or $managed_uninstalls != [] { 69 | # merge existing settings with 'LocalOnlyManifest' pref string 70 | $local_only_manifest = {'LocalOnlyManifest' => $local_only_manifest_name} 71 | $settings_to_write = merge($settings_with_sus_url, $local_only_manifest) 72 | } else { 73 | # just copy the existing to $settings_to_write 74 | $settings_to_write = $settings_with_sus_url 75 | } 76 | 77 | class {'munki::local_only_manifest' : 78 | managed_installs => $managed_installs, 79 | managed_uninstalls => $managed_uninstalls, 80 | manifest_name => $local_only_manifest_name 81 | } 82 | 83 | $profile = { 84 | 'PayloadContent' => [ 85 | { 86 | 'PayloadContent' => { 87 | 'ManagedInstalls' => { 88 | 'Forced' => [ 89 | { 90 | 'mcx_preference_settings' => $settings_to_write 91 | } 92 | ] 93 | } 94 | }, 95 | 'PayloadEnabled' => true, 96 | 'PayloadIdentifier' => 'MCXToProfile.1dc15df4-d4c4-4b3a-b507-dd8f3b44f093.alacarte.customsettings.2beb4aeb-861b-4000-8c3a-d05117bf5ba7', # lint:ignore:140chars 97 | 'PayloadType' => 'com.apple.ManagedClient.preferences', 98 | 'PayloadUUID' => '2beb4aeb-861b-4000-8c3a-d05117bf5ba7', 99 | 'PayloadVersion' => 1 100 | } 101 | ], 102 | 'PayloadDescription' => "Included custom settings:\nManagedInstalls", 103 | 'PayloadDisplayName' => 'Settings for Munki', 104 | 'PayloadIdentifier' => 'ManagedInstalls', 105 | 'PayloadOrganization' => $payload_organization, 106 | 'PayloadRemovalDisallowed' => true, 107 | 'PayloadScope' => 'System', 108 | 'PayloadType' => 'Configuration', 109 | 'PayloadUUID' => '1dc15df4-d4c4-4b3a-b507-dd8f3b44f093', 110 | 'PayloadVersion' => 1 111 | } 112 | 113 | if $manage_profile { 114 | mac_profiles_handler::manage { 'ManagedInstalls': 115 | ensure => present, 116 | file_source => plist($profile), 117 | type => 'template', 118 | } 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /manifests/install_components.pp: -------------------------------------------------------------------------------- 1 | class munki::install_components { 2 | $munkitools_source = $munki::munkitools_source 3 | $munkitools_version = $munki::munkitools_version 4 | $days_before_broken = $munki::days_before_broken 5 | 6 | if $munkitools_source != '' { 7 | $actual_munkitools_source = $munkitools_source 8 | } else { 9 | $actual_munkitools_source = "puppet:///modules/bigfiles/munki/munkitools-${munkitools_version}.pkg" 10 | } 11 | 12 | $munkitools_core_source = $munki::munkitools_core_source 13 | $munkitools_core_version = $munki::munkitools_core_version 14 | 15 | if $munkitools_core_source != '' { 16 | $actual_munkitools_core_source = $munkitools_core_source 17 | } else { 18 | $actual_munkitools_core_source = "puppet:///modules/bigfiles/munki/munkitools_core-${munkitools_core_version}.pkg" 19 | } 20 | 21 | $munkitools_python_source = $munki::munkitools_python_source 22 | $munkitools_python_version = $munki::munkitools_python_version 23 | 24 | if $munkitools_python_source != '' { 25 | $actual_munkitools_python_source = $munkitools_python_source 26 | } else { 27 | $actual_munkitools_python_source = "puppet:///modules/bigfiles/munki/munkitools_python-${munkitools_python_version}.pkg" 28 | } 29 | 30 | 31 | $munkitools_admin_source = $munki::munkitools_admin_source 32 | $munkitools_admin_version = $munki::munkitools_admin_version 33 | 34 | if $munkitools_admin_source != '' { 35 | $actual_munkitools_admin_source = $munkitools_admin_source 36 | } else { 37 | $actual_munkitools_admin_source = "puppet:///modules/bigfiles/munki/munkitools_admin-${munkitools_admin_version}.pkg" 38 | } 39 | 40 | $munkitools_app_usage_source = $munki::munkitools_app_usage_source 41 | $munkitools_app_usage_version = $munki::munkitools_app_usage_version 42 | 43 | if $munkitools_app_usage_source != '' { 44 | $actual_munkitools_app_usage_source = $munkitools_app_usage_source 45 | } else { 46 | $actual_munkitools_app_usage_source = "puppet:///modules/bigfiles/munki/munkitools_app_usage-${munkitools_app_usage_version}.pkg" 47 | } 48 | 49 | $munkitools_launchd_source = $munki::munkitools_launchd_source 50 | $munkitools_launchd_version = $munki::munkitools_launchd_version 51 | 52 | if $munkitools_launchd_source != '' { 53 | $actual_munkitools_launchd_source = $munkitools_launchd_source 54 | } else { 55 | $actual_munkitools_launchd_source = "puppet:///modules/bigfiles/munki/munkitools_launchd-${munkitools_launchd_version}.pkg" 56 | } 57 | 58 | 59 | # $today = strftime('%s') 60 | $now = time() 61 | # $today - (86400 seconds in a day * $days_before_broken) 62 | $broken_days_ago = $now - (86400 * $days_before_broken) 63 | if $facts['munki_last_run_unix'] > 0 and 64 | $facts['munki_last_run_unix'] < $broken_days_ago and 65 | $facts['munki_running'] == false { 66 | $force_install = true 67 | } 68 | elsif ($facts['munki_dir_exists'] == false or 69 | $facts['munki_version'] == 0 or 70 | versioncmp($facts['munki_version'], $munkitools_core_version) < 0) and 71 | $facts['munki_running'] == false { 72 | $force_install = true 73 | exec {'forget_munki_pkgs': 74 | command => '/bin/rm -rf /usr/local/munki/munkilib 75 | /usr/sbin/pkgutil --forget com.googlecode.munki.admin 76 | /usr/sbin/pkgutil --forget com.googlecode.munki.app 77 | /usr/sbin/pkgutil --forget com.googlecode.munki.core 78 | /usr/sbin/pkgutil --forget com.googlecode.munki.launchd 79 | /usr/sbin/pkgutil --forget com.googlecode.munki.app_usage 80 | exit 0', 81 | before => [ 82 | Apple_package['munkitools'], 83 | Apple_package['munkitools_core'], 84 | Apple_package['munkitools_admin'], 85 | Apple_package['munkitools_app_usage'], 86 | Apple_package['munkitools_launchd'] 87 | ] 88 | } 89 | } else { 90 | $force_install = false 91 | } 92 | 93 | apple_package { 'munkitools': 94 | source => $actual_munkitools_source, 95 | version => $munkitools_version, 96 | receipt => $munki::munkitools_receipt, 97 | installs => ['/Applications/Managed Software Center.app/Contents/MacOS/Managed Software Center'], # lint:ignore:140chars 98 | force_install => $force_install, 99 | http_checksum => $munki::munkitools_checksum, 100 | http_username => $munki::http_user, 101 | http_password => $munki::http_password 102 | } 103 | 104 | if versioncmp($munkitools_python_version, '3.8.0') > 0 { 105 | $python_installs = ['/usr/local/munki/Python.framework', '/usr/local/munki/munki-python'] 106 | } else { 107 | $python_installs = ['/usr/local/munki/Python.framework', '/usr/local/munki/python'] 108 | } 109 | if $munki::munki_python { 110 | apple_package { 'munkitools_python': 111 | source => $actual_munkitools_python_source, 112 | version => $munkitools_python_version, 113 | receipt => $munki::munkitools_python_receipt, 114 | installs => $python_installs, 115 | force_install => $force_install, 116 | http_checksum => $munki::munkitools_python_checksum, 117 | http_username => $munki::http_user, 118 | http_password => $munki::http_password 119 | } 120 | } 121 | 122 | apple_package { 'munkitools_core': 123 | source => $actual_munkitools_core_source, 124 | version => $munkitools_core_version, 125 | receipt => $munki::munkitools_core_receipt, 126 | installs => [ 127 | '/usr/local/munki/managedsoftwareupdate', 128 | '/usr/local/munki/authrestartd', 129 | '/usr/local/munki/launchapp', 130 | '/usr/local/munki/ptyexec', 131 | '/usr/local/munki/removepackages', 132 | '/usr/local/munki/supervisor', 133 | ], 134 | force_install => $force_install, 135 | http_checksum => $munki::munkitools_core_checksum, 136 | http_username => $munki::http_user, 137 | http_password => $munki::http_password 138 | } 139 | 140 | apple_package { 'munkitools_admin': 141 | source => $actual_munkitools_admin_source, 142 | version => $munkitools_admin_version, 143 | receipt => $munki::munkitools_admin_receipt, 144 | installs => [ 145 | '/usr/local/munki/iconimporter', 146 | '/usr/local/munki/makecatalogs', 147 | '/usr/local/munki/makepkginfo', 148 | '/usr/local/munki/manifestutil', 149 | '/usr/local/munki/munkiimport', 150 | ], 151 | force_install => $force_install, 152 | http_checksum => $munki::munkitools_admin_checksum, 153 | http_username => $munki::http_user, 154 | http_password => $munki::http_password 155 | } 156 | 157 | apple_package { 'munkitools_app_usage': 158 | source => $actual_munkitools_app_usage_source, 159 | version => $munkitools_app_usage_version, 160 | receipt => $munki::munkitools_app_usage_receipt, 161 | installs => [ 162 | '/Library/LaunchDaemons/com.googlecode.munki.appusaged.plist', 163 | '/Library/LaunchAgents/com.googlecode.munki.app_usage_monitor.plist', 164 | '/usr/local/munki/appusaged', 165 | '/usr/local/munki/app_usage_monitor' 166 | ], 167 | force_install => $force_install, 168 | http_checksum => $munki::munkitools_app_usage_checksum, 169 | http_username => $munki::http_user, 170 | http_password => $munki::http_password 171 | } 172 | 173 | apple_package { 'munkitools_launchd': 174 | source => $actual_munkitools_launchd_source, 175 | version => $munkitools_launchd_version, 176 | receipt => $munki::munkitools_launchd_receipt, 177 | installs => [ 178 | '/Library/LaunchDaemons/com.googlecode.munki.managedsoftwareupdate-check.plist', 179 | '/Library/LaunchDaemons/com.googlecode.munki.managedsoftwareupdate-install.plist', 180 | '/Library/LaunchDaemons/com.googlecode.munki.managedsoftwareupdate-manualcheck.plist', 181 | '/Library/LaunchDaemons/com.googlecode.munki.logouthelper.plist', 182 | ], 183 | force_install => $force_install, 184 | notify => [ 185 | Exec['munki_reload_launchagents'], 186 | Service['com.googlecode.munki.managedsoftwareupdate-check'], 187 | Service['com.googlecode.munki.managedsoftwareupdate-install'], 188 | Service['com.googlecode.munki.managedsoftwareupdate-manualcheck'] 189 | ], 190 | http_checksum => $munki::munkitools_launchd_checksum, 191 | http_username => $munki::http_user, 192 | http_password => $munki::http_password 193 | } 194 | 195 | 196 | } 197 | --------------------------------------------------------------------------------