Deploy Rosetta on M1 machines before everything else

mwu1876
Contributor

We have several M1 chip MacBooks that we want to deploy. How can we push and ensure the Rosetta policy to install (softwareupdate --install-rosetta) gets installed before all the other policies (i.e. Office, TeamViewer, etc.) ? If not, the other installs will fail. I can create a separate policy for each application that has a different scope but that becomes a pain.

1 ACCEPTED SOLUTION

mwu1876
Contributor

So, I got this working. What I did was create a Smart Group for M1 machines. Then, then only policy that I had that kicked off as Enrollment complete is one that installs Rosetta. If it's not an M1 then it kicks off the rest of the policies. Once Rosetta is install I have an event trigger that fires off the rest of the policies. So far it's worked. This allows me more flexibility to quickly change around policies.

View solution in original post

135 REPLIES 135

Kristopher
New Contributor III

@mwu1876 So how did that work if the Jamf binary won't enroll the machine without Rosetta? Meaning, policies won't run if it's not enrolled and it can't install Rosetta as a policy without being enrolled.

kburns
New Contributor III

@Kristopher Jamf running 10.25.2 or 10.26 should natively support Apple Silicon, and enrollments should work fine. I haven't gotten my M1 yet to test/confirm, but that's what the Jamf documentation states.

mwu1876
Contributor

@Kristopher So if you ask Jamf to upgrade you to 10.25.2 it will enroll M1 machines. That's what I did. The upgrade too minutes and then I was able to enroll them. I still had to push out Rosetta. 10.25.2 supports M1. They sent, I believe, an email that said it's not a automatic deployment and that you have to request the version.

Kristopher
New Contributor III

@kburns @mwu1876 Thanks! I will give that a shot. So you still need to push a Rosetta script to get that installed and going I see. Not bad. Need to figure out what all changes. So used to KEX and all that. Sophos is broken until they update it.

yungstump
New Contributor II

@mwu1876 That is what I did as well, I made Rosetta run initially and reported it installed successfully. The policies after still fails to install and says Rosetta is required and needs to be installed. Not sure if a computer needs to be rebooted first after a Rosetta install.
@pbowden I did not update the OS, testing this out a fresh out of the box M1

dmiguel
New Contributor II

What criteria did you guys use to flag apple m1 chip macs for your smart group?

dmiguel
New Contributor II

@txhaflaire how would you package the scrip on prestage? So this will ignore intel machines and only install on m1. looks good

!/bin/bash

arch=$(/usr/bin/arch)
if [ "$arch" == "arm64" ]; then echo "Apple Silicon - Installing Rosetta" /usr/sbin/softwareupdate --install-rosetta --agree-to-license
elif [ "$arch" == "i386" ]; then echo "Intel - Skipping Rosetta"
else echo "Unknown Architecture"
fi

dmiguel
New Contributor II

@mwu1876 What criteria did you use to flag apple m1 chip macs for your smart group?

ccliff
New Contributor II

you can try the criteria Architecture Type is arm64

ThijsX
Valued Contributor
Valued Contributor

@dmiguel Just set it as a postinstall script when creating your package and that simply it is.

mwu1876
Contributor

@dmiguel @ccliff is correct. I only have one criteria in the smart group and it's to look for anything with an Architecture Type of "arm64". I use that smart group for several things including installing Rosetta but also for apps like Chrome which have a specific version for M1 processors.

analog_kid
Contributor

I really hope Rosetta becoming dysfunctional after an OS update is a bug, not a feature.

theelysium
New Contributor III

You can make a smart group that filters ARM Architecture.

tcandela
Valued Contributor II

@mwu1876 can you describe your event trigger that kicks off after the enrollment policy installs rosetta?

is the event trigger a policy with a script, and the script then calls each policy using the (jamf policy -id ????)

konfio
New Contributor II

You know why Self Service in M1 already with Rosetta Installed does not work when installing Intel Apps, it remains in a loop but does not install anything.

jelockwood
Contributor

I don't know how big Rosetta2 is but if it is less than 1GB arguably it should be installed as standard, especially as all other OS components are. (Apple has not had a customisable OS installer for a very long time.)

The issue about it being 'broken' again when the OS is update is a bigger problem and frankly I consider this to be a bug, it should see it already installed and do an update for Rosetta2 as part of the OS update. Just like an OS update may also update Safari.

To fix Apple's mess here, does anyone know how to check the version of Rosetta2 that is installed? We could then have a script which compares the version to the OS version and hence then if needed trigger another Rosetta2 install command. Perhaps looking at a date stamp of an OS file would be a way? That is if the OS file is 'newer' than the Rosetta2 file then trigger another Rosetta2 install.

It would be helpful if someone could list the file paths for the various Rosetta2 components.

mwu1876
Contributor

Sure. So here's how I have everything work. 1. Smart Group with the criteria for Architecture Type is arm64
2. You will want to create two scripts. The first is simple script to install Rosetta

#!/bin/sh
/usr/sbin/softwareupdate --install-rosetta --agree-to-license

3. The second script is to trigger all the remainder policies using sudo jamf policy -event trigger unless you're using DEPNotify.
4. Next I created a policy that only runs with the smart group for M1 processors. The triggers are Enrollment and a Custom Event called install-rosetta (just in case I need to use it manually or via another script).
5. Then I created a second policy to run after Rosetta is installed which fires off the second script that runs the remainder of the policies. That one is only set to run via Custom Event start-enrollmentinstallers.

So far everything is working. I'm testing out DEPNotify which does change how this is done but for now, it's fine.

rcole
Contributor II

Wow, this is pretty freaking awesome. Thanks, for sharing this. I am going to give this a try. I'm curious how to execute was workflow like this utilizing DEPNotify.  Fascinating!

Use a script to install rosetta, and trigger it 'Before' other tasks in your provisioning policies. For example, this is our depNotify-based policy that's triggered by Enrollment. At the end (cut off from the screenshot) is our customized depNotify-starter script, running 'After' everything else.

CSUMB-depNotify-rosetta-policy.png

 

michael_madsen
Contributor

@txhaflaire

For prestage enrollments you can create a prestage package which runs a simple script with something like below for instance

Did you actually try this?
I used Composer to create an "empty" package with a preinstall script inside. However when running this on an M1 mac without Rosetta, it says:

To install "package", you need to install Rosetta. Do you want to install it now?

so I'm back to square one.

mrheathjones
New Contributor III

@michael.madsen I use the following script (credit to rtrouton) in a Policy with the "Enrollment" trigger. This is scoped to all machines as the script has logic to exit if it detects an intel Mac. The policy name begins with < _00 - > forcing it to run 1st in our enrollment process. Seems to work extremely well, but of course more testing is needed. Hope this helps.
bb4661a9b1a14296afa96cd14c506d4f

#!/bin/bash

# Installs Rosetta as needed on Apple Silicon Macs.

exitcode=0

# Determine OS version
# Save current IFS state

OLDIFS=$IFS

IFS='.' read osvers_major osvers_minor osvers_dot_version <<< "$(/usr/bin/sw_vers -productVersion)"

# restore IFS to previous state

IFS=$OLDIFS

# Check to see if the Mac is reporting itself as running macOS 11

if [[ ${osvers_major} -ge 11 ]]; then

  # Check to see if the Mac needs Rosetta installed by testing the processor

  processor=$(/usr/sbin/sysctl -n machdep.cpu.brand_string | grep -o "Intel")

  if [[ -n "$processor" ]]; then
    echo "$processor processor installed. No need to install Rosetta."
  else

    # Check Rosetta LaunchDaemon. If no LaunchDaemon is found,
    # perform a non-interactive install of Rosetta.

    if [[ ! -f "/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist" ]]; then
        /usr/sbin/softwareupdate --install-rosetta --agree-to-license

        if [[ $? -eq 0 ]]; then
            echo "Rosetta has been successfully installed."
        else
            echo "Rosetta installation failed!"
            exitcode=1
        fi

    else
        echo "Rosetta is already installed. Nothing to do."
    fi
  fi
  else
    echo "Mac is running macOS $osvers_major.$osvers_minor.$osvers_dot_version."
    echo "No need to install Rosetta on this version of macOS."
fi

exit $exitcode

michael_madsen
Contributor

@mrheathjones Thanks, but I'm not willing to go this route just yet, as it is too much of a "hack" for me.
I honestly don't understand why Jamf didn't provide a solution for this.

For now the best solution I have heard is to put rosetta install script in prestage package

michael_madsen
Contributor

Here is what I did...

I created an "empty" package with a preinstall script like this:
6d96f127e9e64d49b2251f077f017e79
I tried running this on an M1 mac where Rosetta was not installed (just run manually from desktop). However, it complained:

To install "package", you need to install Rosetta. Do you want to install it now?

However I googled for a while and found that I could expand InstallRosetta.pkg with:

pkgutil --expand "InstallRosetta.pkg" "InstallRosetta"

Then I used BBEdit to edit the file: InstallRosetta/Distribution and added: <options hostArchitectures="arm64,x86_64" />

Then I used command:

pkgutil --flatten "InstallRosetta" "InstallRosetta.pkg"

to put files back to a .pkg again.

Now when I ran the package again on the M1 mac, it didn't complain that Rosetta was missing and when it completed, it had actually installed Rosetta.

So I uploaded this package and added it to our prestage enrollment.

However it still doesn't work :(
I'm not sure why.

Because you need rosetta on the machine to install pkg's

maurits-pro
New Contributor II

@michael.madsen The why: pkgbuild on Big Sur creates packages that do NOT require rosetta. pkgs build on Catalina (and older) DO require rosetta (on M1 macs)
This is independent on the content of the pkg....
see https://scriptingosx.com/2020/12/platform-support-in-macos-installer-packages-pkg/

bside
New Contributor II

For anyone wanting to make this stateful without using an Extension Attribute, you can create a Smart Group based on "Packages Installed By Installer.app/SWU" "Has" "com.apple.pkg.RosettaUpdateAuto" and exclude your Rosetta policy from that.

walt
Contributor III

@michael.madsen curious how the proposed solution is a hack? i don't know where Jamf fits in resolving an issue that Apple should bake into their OS from the get go.

The problem with a pkg is that it either needs to be built in Big Sur or have some sort of plist/xml intended for the M1 architecture. but having script deploy through Jamf at enrollment is (or should be) a cleaner solution. In my instance I have DEPNotify deploy on enrollment complete for DEP and Manual enrollments, but I put the script as a Before in the same DEPNotify policy just to catch everything at once and it can kick off from there...having it separate may be a more appropriate choice but so far does not seem to be an issue as from the policy logs it appears to run as intended.

michael_madsen
Contributor

@walt I use an enrollment policy which contains:
- Package (DEPNotify 1.1.6)
- Script (the script to make DEPNotify do it's thing)

However DEPNotify.app is not even downloaded to the machine if it's an M1 and Rosetta isn't installed.

I don't want to have to name my policies 0something or *something to make them run before other policies - of course this is a hack.

I want Rosetta to be installed in pre-staging

walt
Contributor III

@michael.madsen definitely file feedback with Apple as it should be installed natively with Big Sur at this point. You could also create a feature request with Jamf that perhaps Jamf deploys/checks for rosetta during DEP/ADE/other user enrollment.

I don't agree with the mentioned method being a hack, I mean look at Jamf in the big picture, everyone does things differently with their Jamf environment as its really choose your own adventure, I know there are feature requests to prioritize policies and other methods..so its definitely a method to accomplish what you want to do.

My suggestion is to simply create a new script with the above rtrouton script and add that to your DEPNotify policy as a Before script and it will run before the package is installed and should take care of the issue you are facing. since it's running purely as a script rather than a package (and similar to the separate policy that was recommended earlier, but my use case is its in a single policy).

tcandela
Valued Contributor II

Has anyone tried enrolling an M1 mac Big Sur using enrollment quickadd.pkg? And then with enrollment the Rosatta install script gets kicked off?
Does the quickadd.pkg get stopped?

michael_madsen
Contributor

@walt Thank you, this (Add script to policy as "Before") actually worked.
I already sent feedback to Apple to make Rosetta installed by default. Maybe if enough of us do, they will pay attention :-)

mrheathjones
New Contributor III

I use Ceremony soon to be Octory for my onboarding app, but I ran into the same problem. Rosetta2 not installed throwing an error when installing Ceremony. I made the script its own policy and run that prior to anything else, that way when/if apple decides to bake Rosetta in, I can simply retire the policy that installs it separately rather than re-packaging the Ceremony install. But as was stated, pick your own adventure. Cheers!

georgek
New Contributor

@michael.madsen, I figured out the issue with the pre-stage enrollment if you are still interested in that scenario. The issue is in the package that you use. According to the documentation, the package has to be signed with the valid Apple Developer certificate - https://docs.jamf.com/10.9.0/jamf-pro/administrator-guide/Computer_PreStage_Enrollments.html

I signed the package using the productsign utility, and it works great. The Rosetta installation happens via pre-install script as part of the pre-stage enrollment package.

The downside is only in being an authorized Apple developer that will cost you $300 a year if you enroll for the Enterprise plan.

davidhogan
New Contributor II

Our approach to installing Rosetta 2 before the applications that need it:

  1. Create a new script in Settings --> Computer Management called "Install Rosetta 2" that runs "/usr/sbin/softwareupdate --install-rosetta --agree-to-license"
  2. Create a smart group called "Needs Install: Rosetta 2". Set criteria to "Architecture Type 'is' arm64" AND "Packages Installed By Installer.app/SWU 'does not have' com.apple.pkg.RosettaUpdateAuto"
  3. Create a policy called "Install Rosetta 2" with the scope target set to the "Needs Install: Rosetta 2" smart group, and have it run the "Install Rosetta 2" script.

That takes care of installing Rosetta 2 on ARM macs. Then for each Intel application X, create a smart group similar to above called "Needs Install: X" that finds computers without the application. Then configure a policy that installs X for members of that smart group, but add the "Needs Install: Rosetta 2" smart group to the exclusions list. That way, Intel and ARM macs share most of the configuration - it's just that ARM macs won't install X until Rosetta 2 has been installed.

I'm fairly new to Jamf so apologies if this is all obvious or misses the point.

MacGeek
New Contributor III

David, I think I'm doing the same thing as you but I can't get it to work. I have a smart group already created that will detect the M1 chip. In Composer I made a new install package that only has a preinstall script listed below. When I run the policy it shows that it installed but when I check the Mac it didn't. If I just run the the preinstall script locally it works.

I know I could just set this all up in the Policy itself but I need to have an installer package for our users that aren't in Jamf. What are your thoughts?

 

#!/bin/sh
## preinstall
 
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
 
exit 0 ## Success
exit 1 ## Failure

Saikat
New Contributor III

@mwu1876 I have kept this policy with checked "Enrollment Complete" under general tab. And I have configured scope with SmartGroup Architecture Type arm64. So, once any M1 Mac gets enrolled, this policy will trigger immediately.

Saikat
New Contributor III

@mwu1876 I have kept this policy with checked "Enrollment Complete" under general tab. And I have configured scope with SmartGroup Architecture Type arm64. So, once any M1 Mac gets enrolled, this policy will trigger immediately.

Saikat
New Contributor III

@mwu1876 I have kept this policy with checked "Enrollment Complete" under general tab. And I have configured scope with SmartGroup Architecture Type arm64. So, once any M1 Mac gets enrolled, this policy will trigger immediately.

sdagley
Esteemed Contributor II

@davidhogan It's been reported that installing a Big Sur update will remove any existing install of Rosetta. You may want to check and see if the com.apple.pkg.RosettaUpdateAuto receipt is removed when that happens, otherwise you're going to get a false positive that Rosetta is installed.

jmancuso
New Contributor III

I also used the routon script. You create a policy, enrollment complete, in theory will run before the applications. I change after to before and set to once per computer. I see that some used ongoing. I had other issues when polices ran that way. But, Jamf also has a files and process payload and just execute /usr/sbin/softwareupdate --install-rosetta --agree-to-license... What's the difference? Files and process will give failed logs, because said machines were Intel based... Just wanted to throw that method as well. For me, I used the script this time, but usually use a Files and Process. Jamf installs it as root. Cheers