Class: Jamf::JPackage
- Inherits:
-
OAPISchemas::Package
- Object
- OAPIObject
- OAPISchemas::Package
- Jamf::JPackage
- Extended by:
- Filterable
- Includes:
- ChangeLog, CollectionResource
- Defined in:
- lib/jamf/api/jamf_pro/api_objects/j_package.rb
Overview
A Package in the Jamf Pro API
Constant Summary collapse
- SEARCH_RESULT_OBJECT =
The OAPI object class we get back from a ‘list’ query to get the whole collection, or a subset of it. It contains a :results key which is an array of data for objects of the parent class.
Jamf::OAPISchemas::PackagesSearchResults
- POST_OBJECT =
The OAPI object class we send with a POST request to make a new member of the collection in Jamf. This is usually the same as the parent class.
Jamf::OAPISchemas::Package
- PUT_OBJECT =
The OAPI object class we send with a PUT request to change an object in Jamf by specifying all its values. Most updates happen this way, and this is usually the same as the parent class
Jamf::OAPISchemas::Package
- LIST_PATH =
The path for GETting the list of all objects in the collection, possibly filtered, sorted, and/or paged REQUIRED for all collection resources
GET_PATH, POST_PATH, PUT_PATH, PATCH_PATH, and DELETE_PATH are automatically assumed from the LIST_PATH if they follow the standards:
-
GET_PATH = “#LIST_PATH/id”
-
fetch an object from the collection
-
-
POST_PATH = LIST_PATH
-
create a new object in the collection
-
-
PUT_PATH = “#LIST_PATH/id”
-
update an object passing all its values back. Most objects use this or PATCH but not both
-
-
PATCH_PATH = “#LIST_PATH/id”
-
update an object passing some of its values back Most objects use this or PUT but not both
-
-
DELETE_PATH = “#LIST_PATH/id”
-
delete an object from the collection
-
If those paths differ from the standards, the constants must be defined here
-
'v1/packages'
- ALT_IDENTIFIERS =
Identifiers not marked in the superclass’s OAPI_PROPERTIES constant which usually only identifies ‘:id’
%i[packageName fileName].freeze
- OBJECT_NAME_ATTR =
If the object does not have a ‘name’ attribute, this is the attribute that holds its name. Used to allow referencing objects by ‘name’, creates a alias of the attribute called “name” and “name=”, and allows the use of “name:” as an identifier in the .fetch, .valid_id and similar methods.
:packageName
- FILTER_KEYS =
Must define this when extending Filterable
%i[ id fileName packageName categoryId info notes manifestFileName cloudTransferStatus ].freeze
- UPLOAD_ENDPOINT =
the suffix for the REST resource for uploading a package
'upload'
- DEFAULT_CATEGORY_ID =
Defaults for some required values
'-1'
- DEFAULT_PRIORITY =
10
- DEFAULT_FUT =
false
- DEFAULT_REBOOT_REQUIRED =
false
- DEFAULT_OS_INSTALL =
false
- DEFAULT_SUPPRESS_UPDATES =
false
- DEFAULT_SUPPRESS_FROM_DOCK =
false
- DEFAULT_SUPPRESS_EULA =
false
- DEFAULT_SUPPRESS_REGISTRATION =
false
- CHECKSUM_HASH_TYPE_MD5 =
The hashType value in the API or manifests for md5
'MD5'
- CHECKSUM_HASH_TYPE_SHA256 =
The hashType value in the API for sha256 - IF it exists?
'SHA_256'
- CHECKSUM_HASH_TYPE_SHA256_MDM_DEPLOY =
The hashType value in MDM deploy manifests for sha256
'SHA256'
- CHECKSUM_HASH_TYPE_SHA512 =
The hashType value in the API for sha512
'SHA_512'
- CHECKSUM_HASH_TYPES =
Mapping of the hash types to the maching Digest modules See calculate_checksum
{ CHECKSUM_HASH_TYPE_MD5 => Digest::MD5, CHECKSUM_HASH_TYPE_SHA256 => Digest::SHA256, CHECKSUM_HASH_TYPE_SHA512 => Digest::SHA512 }.freeze
- DEFAULT_CHECKSUM_HASH_TYPE =
CHECKSUM_HASH_TYPE_SHA512
- MANIFEST_FILENAME_DEFAULT_SUFFIX =
if no manifest filename is provided, this suffix will be appended to the fileName, with spaces converted to dashes.
'-manifest.plist'
- MANIFEST_BUNDLE_ID_PREFIX =
If no manifest bundle identifier is provided, this will be used before the packageName.
'com.pixar.ruby-jss.'
- MANIFEST_BUNDLE_VERSION_DEFAULT =
if no manifest bundle version is provided, this will be used.
'0'
- MANIFEST_CHUNK_SIZE =
Not doing chunking by default in generated manifests, but if we do, we’ll use this
1024 * 1024 * 10
- MANIFEST_PLIST_TEMPLATE =
10MB
{ items: [ { assets: [ { 'kind' => 'software-package', 'sha256s' => [], 'url' => 'url-goes-here' } # end hash ], # end assets array, metadata: { 'kind' => 'software', 'bundle-identifier' => "#{MANIFEST_BUNDLE_ID_PREFIX}example", 'bundle-version' => MANIFEST_BUNDLE_VERSION_DEFAULT, 'title' => 'title', 'sizeInBytes' => 1, 'sha256-whole' => 'sha256-goes-here' } # end metadata } # end hash ] # end items array }.freeze
- DEPLOYMENT_ENDPOINT =
The endpoint for deploying a package via MDM see developer.jamf.com/jamf-pro/reference/post_v1-deploy-package
'/v1/deploy-package?verbose=true'
Instance Attribute Summary collapse
-
#checksum ⇒ String
readonly
Checksums.
-
#cnx ⇒ Jamf::Connection
included
from JPAPIResource
readonly
The API connection thru which we deal with this resource.
-
#delete_path ⇒ String
included
from CollectionResource
readonly
The path for deleting a this item from the collection in the JPAPI.
-
#deploy_response ⇒ Hash
readonly
The response body of the last mdm-deploy of this package.
-
#get_path ⇒ String
included
from JPAPIResource
readonly
The path for fetching this thing from the JPAPI.
-
#post_path ⇒ String
included
from CollectionResource
readonly
The path for creating a new item in the collection in the JPAPI.
-
#update_path ⇒ String
included
from JPAPIResource
readonly
The path for updating this thing from the JPAPI.
-
#upload_response ⇒ Hash
readonly
The response body of the last upload of this package, with a timestamp added.
Class Method Summary collapse
-
.calculate_checksum(filepath, type = DEFAULT_CHECKSUM_HASH_TYPE) ⇒ String
Given a file path, and hash type, generate the checksum for an arbitrary file.
-
.default_manifest_base_url ⇒ String
Getter for the default base URL for package manifests.
-
.default_manifest_base_url=(url) ⇒ void
Setter for a default base URL for package manifests.
- .filter_keys ⇒ Object extended from Filterable
Instance Method Summary collapse
-
#add_change_log_note(note) ⇒ Object
included
from ChangeLog
Instance Methods.
- #change_log(sort: nil, filter: nil) ⇒ Object included from ChangeLog
- #change_log_count ⇒ Object included from ChangeLog
- #change_log_pager(page_size: Jamf::Pager::DEFAULT_PAGE_SIZE, sort: nil, filter: nil) ⇒ Object included from ChangeLog
-
#checksum_valid?(filepath) ⇒ Boolean
Does the checksum of the file match the checksum in the object? nil if there is no checksum in the object.
-
#default_manifestFileName ⇒ String
A default if none is set explicitly.
- #delete ⇒ Object included from CollectionResource
-
#deploy_via_mdm(computer_ids: nil, group_id: nil, managed: false) ⇒ Hash
Deploy this package to computers or a group via MDM.
- #exist? ⇒ Boolean included from CollectionResource
-
#generate_manifest(filepath, **opts) ⇒ void
Generate a manifest plist (xml) for this package from a local .pkg file, and update the #manifest and #manifestFileName attributes.
- #history_path ⇒ Object included from ChangeLog
-
#initialize(**data) ⇒ JPackage
constructor
Make an instance.
-
#manifest=(new_manifest) ⇒ void
Set the manifest from a local file or a String containing an XML plist.
-
#manifest_hash ⇒ Hash
return the manifest as a ruby hash converted from the plist IMPORTANT: all hash keys are strings, not symbols.
-
#osRequirements=(new_val) ⇒ void
Change the os_requirements field in the JSS E.g.
-
#pretty_print_instance_variables ⇒ Array
included
from JPAPIResource
Remove large cached items from the instance_variables used to create pretty-print (pp) output.
-
#recalculate_checksum(filepath) ⇒ String
Recalculate the checksum of the package file from a given filepath, and update the object’s checksum and hashValue attributes.
-
#receipt ⇒ Pathname
The local receipt when this pkg is installed by a policy.
-
#save ⇒ Object
included
from JPAPIResource
TODO: error handling.
-
#to_s ⇒ String
included
from CollectionResource
A meaningful string representation of this object.
-
#upload(filepath, **opts) ⇒ void
Upload a package file to Jamf Pro.
Constructor Details
#initialize(**data) ⇒ JPackage
Make an instance. Data comes from the API
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 325 def initialize(**data) super # set defaults for some required values # # check for explicit nils, since if these are boolean false # we don't want to change them. self.categoryId = DEFAULT_CATEGORY_ID if categoryId.nil? self.priority = DEFAULT_PRIORITY if priority.nil? self.fillUserTemplate = DEFAULT_FUT if fillUserTemplate.nil? self.rebootRequired = DEFAULT_REBOOT_REQUIRED if rebootRequired.nil? self.osInstall = DEFAULT_OS_INSTALL if osInstall.nil? self.suppressUpdates = DEFAULT_SUPPRESS_UPDATES if suppressUpdates.nil? self.suppressFromDock = DEFAULT_SUPPRESS_FROM_DOCK if suppressFromDock.nil? self.suppressEula = DEFAULT_SUPPRESS_EULA if suppressEula.nil? self.suppressRegistration = DEFAULT_SUPPRESS_REGISTRATION if suppressRegistration.nil? @checksum = case hashType when CHECKSUM_HASH_TYPE_MD5 md5 || hashValue when CHECKSUM_HASH_TYPE_SHA256 sha256 || hashValue when CHECKSUM_HASH_TYPE_SHA512 hashValue end end |
Instance Attribute Details
#checksum ⇒ String (readonly)
Checksums
Packages in Jamf Pro can have a checksum in either MD5 or SHA512, or possibly SHA256 - none of our 1500 pkgs have 256, but given the existence of the sha256 attribute in the API data, I’m assuming it existed at some point, and behaves like md5 (read on)
In all cases, the hashType attribute indicates the type of checksum, as a string, one of ‘MD5’, ‘SHA_256’, or ‘SHA_512’.
In the case of md5 and sha256, the actual digest value (the checksum) is in the ‘md5’ or ‘sha256’ attribute. In the case of sha512, the digest is in the ‘hashValue’ attribute. In anycase, the digest value will also be stored in the checksum attribute
NOTE: This is the checksum used when installing via a Policy. The checksum(s) used when deploying via MDM is stored in the manifest.
284 285 286 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 284 def checksum @checksum end |
#cnx ⇒ Jamf::Connection (readonly) Originally defined in module JPAPIResource
Returns the API connection thru which we deal with this resource.
#delete_path ⇒ String (readonly) Originally defined in module CollectionResource
Returns The path for deleting a this item from the collection in the JPAPI.
#deploy_response ⇒ Hash (readonly)
The response body of the last mdm-deploy of this package. see #deploy_via_mdm
{
"queuedCommands": [
{
"device": 1,
"commandUuid": "aaaaaaaa-3f1e-4b3a-a5b3-ca0cd7430937"
}
],
"errors": [
{
"device": 2,
"group": 3,
"reason": "Device does not support the InstallEnterpriseApplication command"
}
]
}
316 317 318 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 316 def deploy_response @deploy_response end |
#get_path ⇒ String (readonly) Originally defined in module JPAPIResource
Returns The path for fetching this thing from the JPAPI
this gets set in the constructor in the CollectionResource or SingletonResource mixins.
#post_path ⇒ String (readonly) Originally defined in module CollectionResource
Returns The path for creating a new item in the collection in the JPAPI.
#update_path ⇒ String (readonly) Originally defined in module JPAPIResource
Returns The path for updating this thing from the JPAPI
this gets set in the constructor in the CollectionResource or SingletonResource mixins
We use ‘update_path’ because some items are updated via a PUT_PATH and others via a PATCH_PATH. When this gets set, it will contain the appropriate one.
#upload_response ⇒ Hash (readonly)
The response body of the last upload of this package, with a timestamp added. Looks like:
{
:id=>"10392",
:href=>"https://casper-int.pixar.com:8443/api/v1/packages/10392/upload/10392"
:time=>2025-09-01 12:00:00 -0700
}
see #upload
295 296 297 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 295 def upload_response @upload_response end |
Class Method Details
.calculate_checksum(filepath, type = DEFAULT_CHECKSUM_HASH_TYPE) ⇒ String
Given a file path, and hash type, generate the checksum for an arbitrary file.
211 212 213 214 215 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 211 def self.calculate_checksum(filepath, type = DEFAULT_CHECKSUM_HASH_TYPE) raise ArgumentError, 'Unknown checksum hash type' unless CHECKSUM_HASH_TYPES.key? type CHECKSUM_HASH_TYPES[type].file(filepath).hexdigest end |
.default_manifest_base_url ⇒ String
Getter for the default base URL for package manifests. This will be the one set for the class for this ruby session, or the one set in the Jamf.config.package_manifest_base_url seealso default_manifest_base_url=
257 258 259 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 257 def self.default_manifest_base_url @default_manifest_url || Jamf.config.package_manifest_base_url end |
.default_manifest_base_url=(url) ⇒ void
This method returns an undefined value.
Setter for a default base URL for package manifests. Manifests are required for packages deployed via enrollment prestages or via the InstallEnterpriseApplication MDM command.
When generating a manifest for a package, you must provide a URL from which the package can be downloaded. This is usually from your Cloud Distribution Point, but can be some other https web server.
If Jamf.config.package_manifest_base_url is defined (see Configuration) then that will be used as the default. Otherwise, or if you wish to override the config, the value set here will be used as the default for generating manifests for all Jamf::JPackage objects in this ruby session.
Setting this in the config or here means you don’t have to provide a base URL each time when calling #generate_manifest or #upload, however you can still provide one at that time to override any default.
Normally, the package’s fileName is appended to this URL to generate the full download URL. E.g. for a package with a fileName ‘my-app.pkg’, with the base URL of ‘my-cdp.myorg.com’, the download URL in the manifest would be ‘my-cdp.myorg.com/my-app.pkg’
See #generate_manifest for more info.
246 247 248 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 246 def self.default_manifest_base_url=(url) @default_manifest_url = url.to_s end |
.filter_keys ⇒ Object Originally defined in module Filterable
Instance Method Details
#add_change_log_note(note) ⇒ Object Originally defined in module ChangeLog
Instance Methods
wrappers for the class methods, which pass the id and cnx should work on Singleton Resources since @id will be nil but @cnx will be set.
#change_log_pager(page_size: Jamf::Pager::DEFAULT_PAGE_SIZE, sort: nil, filter: nil) ⇒ Object Originally defined in module ChangeLog
#checksum_valid?(filepath) ⇒ Boolean
Returns Does the checksum of the file match the checksum in the object? nil if there is no checksum in the object.
415 416 417 418 419 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 415 def checksum_valid?(filepath) return unless checksum self.class.calculate_checksum(filepath, hashType) == checksum end |
#default_manifestFileName ⇒ String
Returns A default if none is set explicitly.
423 424 425 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 423 def default_manifestFileName "#{fileName.gsub(' ', '-')}#{MANIFEST_FILENAME_DEFAULT_SUFFIX}" end |
#delete ⇒ Object Originally defined in module CollectionResource
#deploy_via_mdm(computer_ids: nil, group_id: nil, managed: false) ⇒ Hash
Deploy this package to computers or a group via MDM.
REQUIREMENTS:
-
The package must have a manifest with specific data. See #manifest= and #generate_manifest for details.
-
The .pkg file must be a product archive (.pkg) built with Xcode or productbuild. (it must contain a ‘Distribution’ file, usually generated by those tools) Simple ‘component’ packages built with pkgbuild are not supported.
-
The .pkg file must be signed with a trusted signing certificate
This will send an MDM InstallEnterpriseApplication command to install the package to one or more computers, and/or the members of a single computer group.
789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 789 def deploy_via_mdm(computer_ids: nil, group_id: nil, managed: false) raise ArgumentError, 'No computer_ids or group_id provided' unless computer_ids || group_id raise Jamf::MissingDataError, 'No manifest set for this package' if manifest.to_s.empty? raise Jamf::NoSuchItemError, 'This package has no id, it must be saved in Jamf Pro before uploading' unless exist? # convert the full manifest to a ruby hash parsed_manifest = manifest_hash # manifest data for the MDMDeploy command, which is a hash. # hopefully some day Jamf will just use the manifest for the pkg mdm_manifest = {} mdm_manifest['url'] = manifest_url_for_deployment(parsed_manifest) mdm_manifest['hash'], mdm_manifest['hashType'] = manifest_checksum_for_deployment(parsed_manifest) mdm_manifest['bundleId'] = manifest_bundle_identifier_for_deployment(parsed_manifest) mdm_manifest['bundleVersion'] = manifest_bundle_version_for_deployment(parsed_manifest) mdm_manifest['title'] = manifest_title_for_deployment(parsed_manifest) mdm_manifest['sizeInBytes'] = manifest_size_for_deployment(parsed_manifest) set_optional_mdm_manifest_values(parsed_manifest, mdm_manifest) # make sure the computers are in an array computer_ids = [computer_ids].flatten.compact.uniq # make the payload payload = { manifest: mdm_manifest, installAsManaged: managed, devices: computer_ids } payload[:groupId] = group_id.to_s if group_id # send the command @deploy_response = cnx.post(DEPLOYMENT_ENDPOINT, payload) end |
#exist? ⇒ Boolean Originally defined in module CollectionResource
#generate_manifest(filepath, **opts) ⇒ void
This method returns an undefined value.
Generate a manifest plist (xml) for this package from a local .pkg file, and update the #manifest and #manifestFileName attributes
Afterwards, you will need to call #save on the object to save the new values to the server.
See also #manifest= for setting the manifest from a file or string.
The download URL used in the manifest will be the default for the class (if you have set one) usually with the fileName appended. The class default may come from the ruby-jss config, or be set directly on the class, see JPackage.default_manifest_base_url=
Unless set explicitly afterward using #manifestFileName= the manifest filename will be the fileName of the Package object, with spaces converted to dashes, followed by MANIFEST_FILENAME_DEFAULT_SUFFIX. e.g. my-app.pkg-manifest.plist
By default, this method is invoked when uploading the pkg file using #upload and the opts will be passed from that method to this one. When invoked from #upload, the new values will be saved to the Jamf Pro server automatically.
The manifests generated by this method are suitable for use in MDM deployments.
If you don’t provide a bundle_identifier, it will be generated from the packageName, prefixed with ‘com.pixar.ruby-jss.’ and with spaces converted to dashes.
If you don’t provide a bundle_version, it will be ‘0’
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 556 def generate_manifest(filepath, **opts) # make sure the file exists file = Pathname.new(filepath) validate_local_file(file) filesize = file.size # make the manifest new_manifest = MANIFEST_PLIST_TEMPLATE.dup url = build_manifest_url opts[:url], append_filename: opts[:append_filename_to_url] new_manifest[:items][0][:assets][0]['url'] = url.to_s # get the checksum(s) calculate_manifest_checksums(file, new_manifest, chunk_size: opts[:chunk_size]) append_manifest_image('full-size-image', opts[:full_size_image_url], new_manifest) if opts[:full_size_image_url] append_manifest_image('display-image', opts[:display_image_url], new_manifest) if opts[:display_image_url] new_manifest[:items][0][:metadata]['title'] = packageName new_manifest[:items][0][:metadata]['subtitle'] = opts[:subtitle] if opts[:subtitle] new_manifest[:items][0][:metadata]['sizeInBytes'] = filesize new_manifest[:items][0][:metadata]['bundle-identifier'] = (opts[:bundle_identifier] || "#{MANIFEST_BUNDLE_ID_PREFIX}#{packageName.gsub(/\s+/, '-')}") new_manifest[:items][0][:metadata]['bundle-version'] = opts[:bundle_version] if opts[:bundle_version] plist = CFPropertyList::List.new plist.value = CFPropertyList.guess(new_manifest) self.manifest = plist.to_str(CFPropertyList::List::FORMAT_XML, formatted: true) self.manifestFileName = default_manifestFileName end |
#manifest=(new_manifest) ⇒ void
This method returns an undefined value.
Set the manifest from a local file or a String containing an XML plist. If from a file, the manifestFileName attribute is set to the filename
To automatically generate a manifest plist for this package from a locally-readable .pkg file, use #generate_manifest
All manifests require a valid URL for downloading the .pkg file when installing on a client.
No validation of the manifest is done here.
DEPLOYING VIA MDM:
When using this method, if you want to be able to deploy the package using deploy_via_mdm, the manifest MUST include a metadata dictionary with at least the following keys:
- 'kind' = 'software'
- 'bundle-identifier' that preferably matches the bundle identifier of the pkg
- 'bundle-version' = that preferably matches the version of the pkg
- 'title' = the name of the pkg or what it installs
- 'sizeInBytes' = the size of the .pkg in bytes
as well as one of these non-standard keys:
- 'sha256-whole' = the SHA256 digest of the whole file, regardless of chunking data in the 'assets' array
OR
- 'md5-whole' = the MD5 digest of the whole file, regardless of chunking data in the 'assets' array
The non-standard keys are because the Jamf Pro API endpoint for deploying via MDM requires a whole-file checksum even if the file is chunked in the manifest.
See the MANIFEST_PLIST_TEMPLATE constant for an example of the data structure (as a ruby hash, not a plist)
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 462 def manifest=(new_manifest) # if its a string but not an xml plist, assume its a path new_manifest = Pathname.new(new_manifest) if new_manifest.is_a?(String) && !new_manifest.start_with?('<?xml') orig_manifest = manifest new_xml = if new_manifest.is_a? Pathname new_manifest.read elsif new_manifest.is_a? String new_manifest else raise ArgumentError, 'Argument must be a Pathname, or a String containing a path or an XML plist' end @manifest = new_xml note_unsaved_change :manifest, orig_manifest end |
#manifest_hash ⇒ Hash
return the manifest as a ruby hash converted from the plist IMPORTANT: all hash keys are strings, not symbols
487 488 489 490 491 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 487 def manifest_hash return if manifest.to_s.empty? CFPropertyList.native_types(CFPropertyList::List.new(data: manifest).value) end |
#osRequirements=(new_val) ⇒ void
This method returns an undefined value.
Change the os_requirements field in the JSS E.g. 10.5, 10.5.3, 10.6.x
Extra feature: Minumum OS’s can now be specified as a string using the notation “>=10.6.7”.
376 377 378 379 380 381 382 383 384 385 386 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 376 def osRequirements=(new_val) # make sure we have an array new_val = [new_val].flatten.compact.uniq.map(&:to_s) new_val.map! do |vers| vers.start_with?('>=') ? Jamf.(vers) : vers end orig_osRequirements = osRequirements @osRequirements = new_val.join(', ') note_unsaved_change :osRequirements, orig_osRequirements end |
#pretty_print_instance_variables ⇒ Array Originally defined in module JPAPIResource
Remove large cached items from the instance_variables used to create pretty-print (pp) output.
#recalculate_checksum(filepath) ⇒ String
Recalculate the checksum of the package file from a given filepath, and update the object’s checksum and hashValue attributes.
NOTE: This updates the checksum used when installing via a Policy. The checksum(s) used when deploying via MDM is stored in the manifest.
You will need to call #save on the object to save the new checksum to the server.
New checksums are always SHA512
402 403 404 405 406 407 408 409 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 402 def recalculate_checksum(filepath) # update the checksum @checksum = self.class.calculate_checksum(filepath, DEFAULT_CHECKSUM_HASH_TYPE) self.hashType = DEFAULT_CHECKSUM_HASH_TYPE self.sha256 = nil self.md5 = nil self.hashValue = @checksum end |
#receipt ⇒ Pathname
Returns the local receipt when this pkg is installed by a policy.
359 360 361 362 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 359 def receipt # the receipt is the filename with any .zip extension removed. fileName ? (Jamf::Client::RECEIPTS_FOLDER + fileName.to_s.sub(/.zip$/, '')) : nil end |
#save ⇒ Object Originally defined in module JPAPIResource
TODO: error handling
#to_s ⇒ String Originally defined in module CollectionResource
A meaningful string representation of this object
#upload(filepath, **opts) ⇒ void
This method returns an undefined value.
Upload a package file to Jamf Pro.
WARNING: This will automatically call #save, saving any pending changes to the Jamf Pro server!
This uses the Jamf Pro API to upload the file via the package/upload endpoint. If you don’t use an appropriate primary distribution point, this may not work. Also, that endpoint may not upload to any other distribution points.
The fileName attribute of the JPackage object will be updated to the local filename. If that filename is in use by some other package, you’ll get an error:
Field: fileName, Error: DUPLICATE_FIELD duplicate name
This will automatically call #save at least once, and possibly twice. First, in order to ensure the correct fileName in Jamf based on the file being uploaded, and second, in order to update the checksum and manifest in Jamf Pro, if needed. *** Any other outstanding changes will also be saved!
After uploading, the response from the server is in the #upload_response attribute, with a timestamp added to the data from the API.
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 |
# File 'lib/jamf/api/jamf_pro/api_objects/j_package.rb', line 737 def upload(filepath, **opts) file = Pathname.new(filepath) validate_local_file(file) # update the filename if needed # must happen before the upload so it matches the file being uploaded self.fileName = file.basename.to_s # We must save the checksum and manifest to the server before uploading # the file, because otherwise jamf will likely overwrite the manifest # after it uploads to the primary distribution point. # recalulate the checksum unless told no to # NOTE: It appears that the checksum will always be recaluclated by # the Jamf Pro server, as MD5. If you really want our default SHA512, # then do this again later, manually. recalculate_checksum(file) unless opts[:update_checksum] == false # generate a manifest using the new file generate_manifest(file, **opts) unless opts[:update_manifest] == false # save the new fileName, checksum and manifest save # upload the file @upload_response = cnx.jp_upload("#{get_path}/#{UPLOAD_ENDPOINT}", file) @upload_response[:time] = Time.now @upload_response end |