Installomator Support#
Disclaimer
While every effort is made to match software titles accurately, Installomator remains the source of truth for label definitions. If ever unsure about a match, verify the label directly within Installomator’s repository.
What is Installomator?#
Installomator is an open-source tool designed for automated software installation and management on macOS. It is widely used by MacAdmins to streamline application deployment via MDMs such as Jamf Pro. Installomator retrieves and installs software directly from vendor sources, simplifying the process of keeping applications up to date without requiring manually built packages. Unlike traditional methods, it dynamically determines installation parameters, making it highly flexible and efficient.
Storing Labels#
Instead of fetching label definitions dynamically from the Installomator repository each time the CLI runs, labels are stored locally in ~/Library/Application Support/Patcher/.labels
. This reduces network overhead and speeds up label matching operations. The stored labels are periodically updated to ensure they remain accurate and up to date.
Matching Process#
Patcher matches software titles to Installomator labels using multiple methods to ensure the most accurate results:
Direct Matching: Compares application names directly against Installomator label names.
@staticmethod
def _normalize(app_name: str) -> str:
"""Normalizes app names to better match Installomator labels (e.g. nodejs)."""
return app_name.lower().replace(" ", "").replace(".", "")
def _match_directly(self, app_names: List[str], label_lookup: Dict[str, Label]) -> List[Label]:
"""Attempts direct and normalized name matching."""
matched_labels = []
for app_name in app_names:
Fuzzy Matching: Uses similarity scoring (via rapidfuzz) to find the best-matching label when a direct match isn’t found.
if app_name.lower() in label_lookup:
matched_labels.append(label_lookup[app_name.lower()])
if normalized_name in label_lookup:
matched_labels.append(label_lookup[normalized_name])
return matched_labels
def _match_fuzzy(self, app_names: List[str], label_lookup: Dict[str, Label]) -> List[Label]:
"""Attempts fuzzy matching if no direct match is found."""
matched_labels = []
for app_name in app_names:
Normalized Matching: In the event a match is not found via a direct or fuzzy match, the software titles name is ‘normalized’ and checked against all labels (e.g.,
Node.js
→nodejs
).
if result:
best_match, score, _ = result
if best_match and score >= self.threshold:
matched_labels.append(label_lookup[best_match])
return matched_labels
def _second_pass(
self,
unmatched_apps: List[Dict[str, Any]],
label_lookup: Dict[str, Label],
patch_titles: List[PatchTitle],
) -> int:
"""Attempts to match previously unmatched apps by normalized ``PatchTitle.title`` and fuzzy search."""
matched_count = 0
still_unmatched = []
for entry in unmatched_apps:
patch_name = entry["Patch"]
normalized_patch = self._normalize(patch_name)
patch_title = next((pt for pt in patch_titles if pt.title == patch_name), None)
if normalized_patch in label_lookup:
if patch_title:
patch_title.install_label.append(label_lookup[normalized_patch])
self.log.debug(
f"Second-pass normalized match for {patch_name} → {normalized_patch}"
)
matched_count += 1
continue
result = process.extractOne(normalized_patch, list(label_lookup.keys()), scorer=fuzz.ratio) # type: ignore
if result:
best_match, score, _ = result
if best_match and score >= self.threshold:
if patch_title:
patch_title.install_label.append(label_lookup[best_match])
self.log.debug(
f"Second-pass fuzzy match for {patch_name} → {best_match} (Score: {score})"
)
matched_count += 1
Why Matching Can Be Tricky#
One of the biggest challenges in matching software titles to Installomator labels is inconsistency in naming conventions.
Take ‘Zoom’ for example:
The software title is referenced as Zoom Client for Meetings in Jamf Pro
The application name is
zoom.us.app
Installomator labels are
zoom
,zoomclient
,zoomgov
and others.
To retrieve corresponding Application names for Software Titles, a separate call to the Jamf Pro API is made to the /api/v2/patch-software-title-configurations/{title_id}/definitions
endpoint. The response payload scheme is formatted as follows:
{
"totalCount": 1,
"results": [
{
"version": "10.37.0",
"minimumOperatingSystem": "12.0.1",
"releaseDate": "2010-12-10 13:36:04",
"rebootRequired": false,
"killApps": [
{
"appName": "Firefox"
}
],
"standalone": false,
"absoluteOrderId": "1"
}
]
}
When present, all appName
values are appended to a list and returned along with the software title (PatchTitle
) name. This mapping is then normalized and used to intelligently match titles across different naming formats.
Unmatched Applications#
Applications that are still not matched after matching attempts are written to JSON file at ~/Library/Application Support/Patcher/unmatched_apps.json
. This can be helpful in order to review unmatched applications and manually create labels if needed.
An example of this file could look like:
[
{
"Patch": "Appium",
"App Names": [
"Appium"
]
},
{
"Patch": "Adobe Illustrator",
"App Names": [
"Adobe Illustrator"
]
}
]
Understanding the JSON Format#
The JSON file will consist of a list of objects, where each object represents a software title that could not be matched with an Installomator label. Each object contains the following keys:
"Patch"
(string): Thetitle
attribute of thePatchTitle
in question."App Names"
(list of strings): The application names extracted from the Jamf API response (if present), corresponding to that software title.
How This Data Is Used#
If an Installomator label is later added for an application, it will be removed from
unmatched_apps.json
during the next match attempt.The presence of
App Names
helps identify applications with multiple labels (e.g.,zulujdk8
,zulujdk9
).PatchTitle
objects store these labels in theinstall_label
list attribute.Users can use this file to manually create labels or report missing mappings.
Ignored Software Titles#
Certain software titles are explicitly ignored by Patcher as they are typically not patched via automated means or have deprecated support. These applications usually rely on system updates (e.g., macOS updates via Apple’s software update mechanism) or other vendor-specific mechanisms.
How This Affects Matching
Any software title in this list will be ignored and will not be matched to Installomator label, even if one exists.
Below is the current list of ignored titles:
IGNORED_TITLES = [
"Apple macOS *",
"Oracle Java SE *",
"Eclipse Temurin *",
"Apple Safari",
"Apple Xcode",
"Microsoft Visual Studio",
]
Why These Titles Are Ignored#
Apple software (macOS, Safari, Xcode): Managed either by MDM or Apple’s software update mechanism.
Java and Eclipse Temurin: Often require manual intervention for licensing and security compliance.
Microsoft Visual Studio: This refers to the full Visual Studio for Mac IDE, which has been deprecated by Microsoft as of August 2024.
Note
Microsoft Visual Studio Code is not affected by this deprecation and remains supported.
Retrieving Label Details#
Currently, Patcher only provides a Y/N response indicating whether an Installomator label exists for a given software title. Future updates will enhance this by allowing retrieval of full label details, including installation parameters.
Disabling Installomator#
Installomator support can be disabled entirely if it does not meet the requirements of your environment. To disable Installomator, set the enable_installomator
key to false
in Patcher’s property list file:
$ defaults write ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist enable_installomator -bool false
When this key is set to false
, Patcher will bypass Installomator functionality entirely:
Labels will not be downloaded or fetched
Software title matching will not occur
Upcoming Features#
Installomator features are currently in beta as we build onto this base functionality. We are actively working on implementing:
Policy creation in Jamf for supported titles with available script options
Integration with AutoPkg to expand package deployment capabilities