Munki 使用 pkginfo 文件中的信息,并查找软件项以确定是否必须安装给定项。要创建功能性 pkginfo 项,请了解 Munki 检查软件项列表时所使用的方法。

重要说明: 本节的大部分内容来自 Munki 网站。

方法

按照优先级顺序,Munki 使用以下方法来确定是否需要安装或移除给定项:

  1. 使用检查脚本安装 macOS 应用程序
  2. 使用安装项目安装 macOS 应用程序
  3. 使用回执安装 macOS 应用程序

在组合这些方法时,仅使用优先级最高的方法。例如,如果给定的 pkginfo 项同时具有“安装”列表和“回执”列表,则在确定安装状态时将忽略回执。即使在这种情况下,移除某个项时也可以使用回执,因为它们有助于 Munki 准确确定安装了哪些文件。

使用检查脚本安装 macOS 应用程序

pkginfo 项目可以选择性地包含 installcheck_script。安装检查脚本提供了一种方法来确定是否需要安装软件项(当提供安装/回执并不足够或不实用时)。

通常通过端口 (MacPorts) 安装的命令行工具或者使用 easy_install 或 pip 安装的 Python 模块是主要示例,因为它们没有提供简单方法来确定安装的版本。

应编写一个 install check_script,如果退出代码为 0,则表明当前未安装该项目,因此应进行安装。所有非零退出代码则表明已安装该项目。

下面的 installcheck_script 示例说明了如何执行检查来确定是否已安装 argparse Python 模块的最新版本。

#!/bin/sh# Grab current version of installed python moduleversion="$(python -c 'import argparse;print argparse.__version__' 2>/dev/null)"# Compare with the version we want to installif [ ${version:-0} < 1.2.1 ]; thenexit 0elseexit 1fi

(可选)可以提供显式 uninstallcheck_script 来确定是否应移除某个软件项。在这种情况下,退出代码为 0 的脚本表明当前已安装该项目,应将其移除。所有非零退出代码则表明未安装该项目。

使用安装项目安装 macOS 应用程序

安装项列表由 VMware AirWatch Admin Assistant 为某些类型的安装项 (.dmg) 生成,但不适用于 Apple 软件包(.pkg 或 .mpkg)。您可以生成(或修改)此列表,这是确定安装状态的最灵活机制。

安装列表可以包含任意数量的项目,例如应用程序、首选项窗格、框架或其他包样式项、info.plist、简单目录或文件。您可以使用任何项目组合来帮助 Munki 确定项目是否已安装。

为 Firefox 6.0 自动生成的“安装”列表示例

<key>installs</key><array><dict><key>CFBundleIdentifier</key><string>org.mozilla.firefox</string><key>CFBundleName</key><string>Firefox</string><key>CFBundleShortVersionString</key><string>6.0</string><key>minosversion</key><string>10.5</string><key>path</key><string>Applications/Firefox.app</string><key>type</key><string>application</string></dict></array>

要确定 Firefox 6 是否已安装,Munki 会检查是否存在 CFBundleIdentifier 为 org.mozilla.firefox 的应用程序,如果找到,则验证其版本 (CFBundleShortVersionString) 是否至少为 6.0。如果 Munki 找不到应用程序或其版本低于 6.0,它会将 Firefox-6.0 视为未安装。安装列表可以包含多个项目。如果有任何项目缺失或版本较旧,则该项目将被视为未安装。您可以使用以下 pkginfo 手动生成要添加到安装列表的项目。

        /Library/Application\ Support/AirWatch/Data/Munki/bin/makepkginfo -f /Library/Interne
        t\ Plug-Ins/Flash\ Player.plugin
      
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/Prope
        rtyList-1.0.dtd">
        <plist version="1.0">
        <dict>
        
          <key>installs</key>
          <array>
           <dict>  <key>CFBundleShortVersionString</key> <string>10.3.183.5</string> <key>path</key> <string>/Library/Internet Plug-Ins/Flash Player.plugin</string> <key>type</key> <string>bundle</string>  </dict> 
          </array>
        
        </dict>
        </plist>
      

请复制并粘贴整个安装键和值,或者复制 dict 值并将其添加到 pkginfo 文件中的现有安装列表。Munki 将检查是否存在 /Library/Internet Plug-Ins/Flash Player.plugin,如果找到,则检查其版本。如果版本低于 10.3.183.5,则该项目将被视为未安装。您可以为任何文件系统项生成安装项,但 Munki 仅知道如何确定包含 Info.plist 或具有版本信息的 version.plist 的包样式项的版本。

对于其他文件系统项,Munki 只能确定非包目录是否存在,也可以计算校验和(对于文件)。对于带有校验和的文件,如果磁盘上文件的校验和与 pkginfo 中的校验和不匹配,则测试将失败(因此,该项目将被视为未安装)。

        <key>installs</key>
        <array>
        
          <dict>
           <key>md5checksum</key> <string>087fe4805b63412ec3ed559b0cd9be71</string> <key>path</key> <string>/private/var/db/dslocal/nodes/MCX/computergroups/loginwindow.plist</s tring> <key>type</key> <string>file</string> 
          </dict>
        
        </array>
      

如果您希望 Munki 仅检查文件是否存在而并不关注其内容,请在安装项信息中移除生成的 md5checksum 信息。请确保提供的路径完好无损。

        <key>installs</key>
        <array>
        
          <dict>
          <key>path</key>
          <string>/private/var/db/dslocal/nodes/MCX/computergroups/loginwindow.plist
          </string>
          <key>type</key>
           <string>file</string> 
          </dict>
        
        </array>
      

使用回执安装 macOS 应用程序

在安装 Apple 样式的软件包时,您可以在计算机上生成一个回执。元包将生成多个回执。VMware AirWatch Admin Assistant 会将这些回执的名称和版本添加到软件包的 pkginfo 中的一个回执数组中。

以下是 Avid LE QuickTime 编解码器版本 2.3.4 的回执数组。

        <key>receipts</key>
        <array>
        
          <dict>
           <key>filename</key> <string>AvidCodecsLE.pkg</string> <key>installed_size</key> <integer>1188</integer> <key>name</key> <string>AvidCodecsLE</string> <key>packageid</key> <string>com.avid.avidcodecsle</string> <key>version</key> <string>2.3.4</string> 
          </dict>
        
        </array>
      

如果 Munki 使用回执数组来确定安装状态,它将验证数组中的每个回执是否存在并验证其版本。如果任何回执缺失或版本号低于在回执数组中为该回执指定的版本,则该项目将被视为未安装。只有当每个回执存在,并且所有版本与 pkginfo 中的版本相同(或更高)时,项目才会被视为已安装。要解决问题,请使用 pkgutil 工具检查安装的回执。

        # pkgutil --pkg-info com.avid.avidcodecsle
        No receipt for 'com.avid.avidcodecsle' found at '/'.
      

在本例中,在此计算机上找不到 Avid LE QuickTime 编解码器的回执。回执的一个常见情况是,使用多个元包时,安装逻辑导致仅安装子包的一部分。通常,回执列表对元包中的每个子包包含一个回执(如果要求 Munki 基于包回执移除软件项,则需要此信息)。但是,如果情况正常并且预期不会安装每个子包,则 Munki 会将项目标记为当前未安装,并且一次又一次地提供它以便安装。此问题的一个解决方案是将可选键及其值 true 添加到选择性地安装的回执中。在确定安装状态时,Munki 不会考虑这些回执。

        <key>receipts</key>
        <array>
        
          <dict>
           <key>filename</key> <string>mandatory.pkg</string> <key>installed_size</key> <integer>1188</integer> <key>name</key> <string>Mandatory</string> <key>packageid</key> <string>com.foo.mandatory</string> <key>version</key> <string>1.0</string> 
          </dict>
          <dict>
           <key>filename</key> <string>optional.pkg</string> <key>installed_size</key> <integer>1188</integer> <key>name</key> <string>Optional</string> <key>optional</key> <true/> <key>packageid</key> <string>com.foo.optional</string> <key>version</key> <string>1.0</string> 
          </dict>
        
        </array>
      

此情况的另一个解决方案是提供一个安装数组,列出包安装的项目。Munki 可以使用安装数组信息(而非回执)来确定安装状态。