Esempio n. 1
0
    def UploadMunkiPackage(self,
                           filename,
                           description,
                           display_name,
                           catalogs,
                           manifests,
                           install_types,
                           unattended_install=False,
                           unattended_uninstall=False,
                           pkginfo_hooks=None,
                           pkginfo_name=None):
        """Uploads a Munki PackageInfo plist along with a Package.

    Args:
      filename: str file name to upload.
      description: str description.
      display_name: str human readable display name.
      catalogs: list of str catalog names.
      manifests: list of str manifest names.
      install_types: list of str install types.
      unattended_install: bool, if True inject "unattended_install" bool into
              plist XML.
      unattended_uninstall: bool, if True inject "unattended_uninstall" bool
              into plist XML.
      pkginfo_hooks: optional, function to call with package info after
              generated
      pkginfo_name: optional, str name to override the pkginfo name.
    Returns:
      Tuple. (Str response body from upload, filename, name of the package,
              list of manifests, file size in kilobytes, SHA-256 hash of file)
    Raises:
      client.SimianClientError: if a client generated error occurs.
    """
        if not self._IsDiskImageReadOnly(filename):
            raise client.SimianClientError('%s is not a read-only disk image' %
                                           filename)

        pkginfo = self._LoadPackageInfo(filename, description, display_name,
                                        catalogs)

        if unattended_install:
            pkginfo['unattended_install'] = True
            # TODO(user): remove backwards compatibility after a while...
            pkginfo['forced_install'] = True
        if unattended_uninstall:
            pkginfo['unattended_uninstall'] = True
            # TODO(user): remove backwards compatibility after a while...
            pkginfo['forced_uninstall'] = True
        if pkginfo_name:
            pkginfo['name'] = unicode(pkginfo_name)

        try:
            pkginfo.Validate()
        except plist.Error, e:
            raise client.SimianClientError(
                ('Internal sanity check, plist error: %s' % str(e)))
Esempio n. 2
0
    def _LoadPackageInfo(self, filename, description, display_name, catalogs):
        """Load package info from a file and return its package info.

    Args:
      filename: str, like /tmp/foo.dmg
      description: str, like "Security update for Foo Software"
      display_name: str, like "Munki Client"
      catalogs: list of str catalogs.
    Returns:
      plist.MunkiPackageInfoPlist object.
    Raises:
      client.SimianClientError: there was an error creating the pkginfo plist.
    """
        p = pkgs.MunkiPackageInfo()
        try:
            p.CreateFromPackage(filename, description, display_name, catalogs)
        except pkgs.Error, e:
            raise client.SimianClientError(str(e))
Esempio n. 3
0
    def _IsDiskImageReadOnly(self, filename):
        """Returns True if the disk image will mount read-only.

    Args:
      filename: str, disk image filename
    Returns:
      True, if the disk image will mount read-only.
      False, if the disk image will mount read-write.
    Raises:
      client.SimianClientError: the package is malformed.
    """
        try:
            argv = ['/usr/bin/hdiutil', 'imageinfo', filename]
            p = subprocess.Popen(argv,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            (stdout, stderr) = p.communicate()
            rc = p.wait()
        except OSError, e:
            raise client.SimianClientError(
                'Could not hdiutil imageinfo %s: %s' % (filename, str(e)))
Esempio n. 4
0
    Raises:
      client.SimianClientError: the package is malformed.
    """
        try:
            argv = ['/usr/bin/hdiutil', 'imageinfo', filename]
            p = subprocess.Popen(argv,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.PIPE)
            (stdout, stderr) = p.communicate()
            rc = p.wait()
        except OSError, e:
            raise client.SimianClientError(
                'Could not hdiutil imageinfo %s: %s' % (filename, str(e)))

        if rc != 0:
            raise client.SimianClientError('%s: %s: %s' %
                                           (filename, str(rc), stderr))

        if stdout:
            if re.search('Format Description:.*read\-only', stdout):
                return True

        return False

    def _IsPackageUploadNecessary(self, filename, upload_pkginfo):
        """Returns True if the package file should be uploaded.

    This method helps the client decide whether to upload the entire package
    and package info, or just new package info.  It compares the sha256 hash
    of the existing package on the server with the one of the package file
    which would potentially be uploaded.  If the existing package info is
    not obtainable or not parseable the hash value cannot be compared, so