Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update installinstallmacos.py with new option to create dmg that's friendly for Jamf Pro deployment purposes #81

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

bp88
Copy link

@bp88 bp88 commented Nov 14, 2020

Add an option (--jamf-dmg) to output a compressed read-only dmg that can be used for deployment with Jamf Pro. Jamf Pro can deploy apps through DMGs with a caveat that file structure of the DMG will simply be copied to the target volume. The default --compress option leaves the install macOS app in the root of the DMG which would mean that Jamf Pro would attempt to deploy the app to the root of the target volume which is obviously not desired. Jamf Pro, unlike Munki, is not smart enough to handle seeing an app bundle in the root of a DMG and deploying that to the Applications folder of the target volume.

This change would be particularly helpful given that the "Install macOS Big Sur.app" is too big to be packaged through pkgbuild since the "SharedSupport.dmg" is over 8GB.

Add an option (--jamf-dmg) to output a compressed read-only dmg that can be used for deployment with Jamf Pro. Jamf Pro can deploy apps through DMGs with a caveat that file structure of the DMG will simply be copied to the target volume. The default --compress option leaves the install macOS app in the root of the DMG which would mean that Jamf Pro would attempt to deploy the app to the root of the target volume which is obviously not desired. Jamf Pro, unlike Munki, is not smart enough to handle seeing an app bundle in the root of a DMG and deploying that to the Applications folder of the target volume.

This change would be particularly helpful given that the "Install macOS Big Sur.app" is too big to be packaged through pkgbuild since the "SharedSupport.dmg" is over 8GB.
@bp88 bp88 changed the title Update installinstallmacos.py Update installinstallmacos.py with new option to create dmg that's friendly for Jamf Pro deployment purposes Nov 14, 2020
@gregneagle
Copy link
Contributor

While the approach you've taken (probably) works now, it's fragile long-term.
Instead of deleting things you don't want, it would be better to create a fresh new dmg with the things you do want. Then if Apple changes what gets installed (and installs documentation or a getting-started video, as examples) you don't need to change the script.

@bp88
Copy link
Author

bp88 commented Nov 16, 2020

That certainly makes more sense long term. I'll get back to you with an updated pull request and submit it when I get a chance.

@bp88
Copy link
Author

bp88 commented Nov 17, 2020

Submitted an update where the script is just grabbing whatever is in the parent folder containing the installer app. Let me know what you think.

@gregneagle
Copy link
Contributor

This still seems rather baroque, and I had to read through the code several times to understand what you were doing and why. More explanatory comments would help.

@grahampugh
Copy link

I wonder if this has been obsoleted by https://github.com/scriptingosx/fetch-installer-pkg ?
I'm currently incorporating Armin's work into my fork of installinstallmacos.py. Simply a --pkg option. It'll be posted tonight.

@gregneagle
Copy link
Contributor

Obsoleted if all you care about is Big Sur installers, maybe.
I have concerns that this doesn't actually grab all the needed components, but too early to tell.

@grahampugh
Copy link

Since this only just came up, I assumed that earlier OSes can still be packaged up for uploading to Jamf Pro. Not that I've tried as I don't have any bandwidth issues that would warrant that work.

…iendly for Jamf Pro deployment purposes

Provided additional comments on what code is doing.
@bp88
Copy link
Author

bp88 commented Nov 18, 2020

I added additional comments in the code block I added. I realize it's longer than the actual code itself but you asked for additional comments in the code.

Here's some further elaboration:
The code I've written just makes slight modifications at the end of the code block that basically is used for --compress (the default option). I'm not doing anything drastically different than what the --compress option is already doing as far as simply taking the app bundle and putting it into a dmg. Like I mentioned in the original message, Jamf copies the exact file structure in the DMG onto the target volume so that structure needs to be re-created temporarily in the sparsebundle. The code I've written is simply re-creating that structure.

If we used the resulting DMG we get from --compress, the DMG gives us the file structure of /Install macOS Big Sur.app which would mean that Jamf would try to copy "Install macOS Big Sur.app" to the root of the target volume.

If the file structure in the resulting DMG were /Applications/Install macOS Big Sur.app, Jamf would copy "Install macOS Big Sur.app" to the "Applications folder on the target volume. This is what I'm after with --jamf-dmg.

Because of the way hdiutil works, when you use the find_installer_app() function, it gives you the path to the installer app which means the resulting DMG is basically just a copy of what's in the folder (e.g. "Applications") that contains the installer app.

Don't ask me why but hdiutil treats "folders" and "Installer app bundles" (which I realize are folders) differently. That is,
/usr/bin/hdiutil create -fs HFS+ -srcfolder /Applications /path/to/output.dmg
results in a DMG where the DMG volume name is "Applications" and in the root of the DMG is only "Install macOS Big Sur.app"
vs
/usr/bin/hdiutil create -fs HFS+ -srcfolder "/Applications/Install macOS Big Sur.app" /path/to/output.dmg
results in a DMG where the DMG volume name is "Install macOS Big Sur" (the ".app" is stripped) and in the root of the DMG is "Install macOS Big Sur.app".

For the purposes of Jamf, we cannot just point hdiutil to installer app bundle which is what the find_installer_app() function is doing since that basically gives us the output we get with --compress.

We also cannot go up one folder in the sparsebundle that's temporarily created because that is in fact just the root of the sparsebundle which contains files that we definitely do not need to deploy. Even the --compress option ignores it.

The --jamf-dmg code is simply taking the parent folder where the app bundle exists (e.g. "Applications") and moving that parent folder to another empty folder in the sparsebundle temporarily so that a compressed dmg can be created so we end up with the proper file structure.

--compress is essentially doing:
/usr/bin/hdiutil create -fs HFS+ -srcfolder "../mountpoint/Applications/Install macOS Big Sur.app" diskimagepath
and results in a DMG where the DMG volume name is "Install macOS Big Sur" (the ".app" is stripped) and in the root of the DMG is "Install macOS Big Sur.app".

--jamf-dmg is doing:
/usr/bin/hdiutil create -fs HFS+ -srcfolder "../mountpoint/Install macOS Big Sur" diskimagepath
where "../mountpoint/Install macOS Big Sur/" contains "/Applications/Install macOS Big Sur.app"
and results in a DMG where the DMG volume name is "Install macOS Big Sur" (based on the folder name) and in the root of the DMG is "/Applications/Install macOS Big Sur.app".

Does that explain what's going on?

@grahampugh
Copy link

Don't forget that with hdiutil you can specify the DMG volume name with -volname. I'm not clear on if the only reason you are copying things around in the sparsebundle is to get the correct DMG name, but just in case...

Also, with that in mind, if I were to use this with Jamf I would want a version or build number in the DMG name to allow for testing and incrementation. Something to also think about if you're trying to avoid subsequent manual steps.

@bp88
Copy link
Author

bp88 commented Nov 19, 2020

@grahampugh I did not want to make major modifications to the overall code outside of main(). Since this relies on make_compressed_dmg() and that does not make use of --volname, I had to do what I did to get the friendly volume name. I did consider making that change you're suggesting, but I figured whatever code I contributed had a better chance of getting accepted if there were less modifications made overall to functions outside of main and kept things somewhat isolated. Anyways, I went ahead and made that modification as you suggested. Notice that none of the --jamf-dmg code has any impact on any of the other options that the script takes. I'm submitting new code which has added --volname to make_compressed_dmg().

Keep in mind even with the modification to make_compressed_dmg() to make use of --volname, I would still need to create an empty root directory to move the parent folder of the installer app into. This seems to be what is generating the most confusion. Just need to reiterate here: this is due to the way Jamf supports DMG deployments.

If the concern is the fact that I'm only focusing on the parent folder of the installer app, then that concern should also apply to --compress which as of today only looks at the installer app path.

Also, the resulting DMG file name with --jamf-dmg is the same as the file name you get with --compress which already includes the OS version and build. My proposed code doesn't change the file name of the resulting DMG.

@bp88
Copy link
Author

bp88 commented Dec 3, 2020

Just checking in. Have the last changes I made satisfied the concerns that were raised?

@bp88
Copy link
Author

bp88 commented Feb 1, 2021

@gregneagle Just wanted to check in again. Have the changes I made satisfied the concerns that you had raised?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants