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

121 REPLIES 121

theelysium
New Contributor III

You can make a smart group that filters ARM Architecture.

tcandela
Valued Contributor

@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
New Contributor III

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
New Contributor III

@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
New Contributor III

@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
New Contributor III

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
New Contributor III

@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

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
New Contributor III

@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
Honored 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

davidhogan
New Contributor II

@sdagley I haven't tested that, but i've tested dragging the app to the bin. The Jamf inventory refresh appears to be smart enough to detect that case at least.

davidhogan
New Contributor II

(I got confused there, it was a different app i did that test with, not Rosetta 2)

Hopefully future Big Sur updates don't force remove Rosetta 2, that sounds like a bug to me if it's happening.

mark_mahabir
Valued Contributor

@tcandela AIUI, the Quickadd package method of enrollment does not work in Big Sur - you need to use either the Automated Device Enrollment or User Initiated Enrollment methods.

rstasel
Contributor III

Anyone have an EA for checking for Rosetta being installed? I installed 11.3b1 on our test machine and rosetta broke and required reinstalling. So might be nice to have an EA in place so we can re-trigger the install process if it ever breaks.

Nevermind, I see the solutions above. Why the heck is Apple breaking Rosetta on updates!?!

randy_andersen
New Contributor III

@rstasel https://github.com/grahampugh/Rosetta-2-install/blob/main/Rosetta-2-install.sh can be a good check.

Edit here is the EA:

#!/bin/bash
​
: << DOC
EA to determine whether Rosetta is installed. 
Possible results:
"installed"    - arm64 Mac - Rosetta is installed
"missing"      - arm64 Mac - Rosetta is not installed
"ineligible" - Intel Mac - Rosetta cannot be installed
DOC
​
# is this an ARM Mac?
arch=$(/usr/bin/arch)
if [ "$arch" == "arm64" ]; then
    # is rosetta 2 installed?
    if [[ -f "/Library/Apple/System/Library/LaunchDaemons/com.apple.oahd.plist" ]]; then
        result="installed"
    else
        result="missing"
    fi
else
    result="ineligible"
fi
​
echo "<result>$result</result>"

rstasel
Contributor III

@randy.andersen Awesome, thank you! I'll add this to our EAs. I'm not sure if the package route does/will work.

Thanks! Saved me from doing it. =)

fponcelin
New Contributor II

Has anyone noticed the occasional Apple Silicon reporting its arch type incorrectly? I've had a few occurrences of new machines showing "Processor type: Unknown" and "Arch type: x86_64" (including my own, which is how I discovered this behaviour). Then after a day or two (on the next Inventory Report I guess) they generally fix themselves.
The immediate consequence is that they become scoped incorrectly and potentially receive the wrong profiles and policies!

As a workaround I added these two criteria to my Apple Silicon scoping:
- Model Identifier is MacBookPro17,1
- Model Identifier is MacBookAir10,1

Out of curiosity I created a smart group to catch these machines and see how frequently they appear. So far every week there's been one or two (we have 36 Apple Silicon enrolled so far)!
78832e04e11a449d84d9d9df506b1de3

rstasel
Contributor III

@fponcelin That's... not great. Have you opened a case with Jamf about this?

fponcelin
New Contributor II

I haven't, but will do right away!

David_Lynch
New Contributor

ok how do i create a smart group to add this to the m1 proc. I tried to create one with Processer type Apple M1 but nothing worked

rstasel
Contributor III

@David.Lynch You want a smart group where "Architecture Type" is "arm64".

mickl089
Contributor II

@mwu1876 How did you manage to start the installation process again after the Rosetta installation? Can you show me the complete script or the process? Thank you!