Skip to content

Commit

Permalink
Merge branch 'release/0.2.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
a-vogel committed Oct 24, 2024
2 parents e5b4e20 + afca4bb commit e325831
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 25 deletions.
13 changes: 10 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# Changelog


## Unreleased
## [0.2.3](https://github.com/wycomco/misty/releases/tag/v0.2.3) – 2024-10-24 (Public pre-release)

### Info
- See [Testing methods](./README.md#testing-methods) and [To Do](./README.md#to-do) sections of the README if you plan to use *misty* at the current state.
### Added
- Check for presence of repo if remote – [PR#17](https://github.com/wycomco/misty/pull/17)
- Create workflow for signed and notarized installer – [PR#20](https://github.com/wycomco/misty/pull/20)
- Check owner and group of subdirectories defined in `$munki_path`[PR#22](https://github.com/wycomco/misty/pull/22)

### Changed
- Checking order, output of launchd logs on exit 1 – [PR#18](https://github.com/wycomco/misty/pull/18)
- Increased storage requirement for installers – [PR#19](https://github.com/wycomco/misty/pull/19)
- Handling of special characters in password for repo share – [PR#21](https://github.com/wycomco/misty/pull/21)


## [0.2.2](https://github.com/wycomco/misty/releases/tag/v0.2.2) – 2024-09-17 (Pre-release)
Expand Down
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ This script checks for the availability of new macOS releases currently supporte

Since this is a pre-release with frequent updates, the installer has not yet been signed or notarized. To run the downloaded installer, please right-click the `.pkg` file and select 'Open'.

Sequoia note: If you are running the installer on macOS 15, you need to right-click the installer and choose "Open". macOS will not allow you to run the installer immediately, so you need to click on "Done". After that, allow the execution of the installer in System Settings => Privacy & Security. Scroll down to the "Security" section, where you will find the message *"misty" was blocked to protect your Mac.* Tick "Open Anyway". This will bring up a pop-up window where you need to confirm that you want to "Open Anyway" the *misty* installer. Finally, grant the installer permission to control "System Events.app".

See the [Changelog](./CHANGELOG.md) for details on version history and updates.

## Goals of this Script
Expand Down Expand Up @@ -128,7 +126,6 @@ This is a pre-release. It is working, but we have some tasks on our to-do list:

- Testing in different environments, preferably with SMB and Samba shares.
- Ensure all items that require FDA are mentioned.
- Calculate space requirements based on actual number of available macOS versions
- Function `rm_previous_files` states one previous version when no version is available
- Improve message output.
- Harmonize variable names.
Expand Down
16 changes: 15 additions & 1 deletion misty/build-info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,29 @@
<string>/</string>
<key>name</key>
<string>misty-${version}.pkg</string>
<key>notarization_info</key>
<dict>
<key>asc_provider</key>
<string>wycomcoGmbH</string>
<key>keychain_profile</key>
<string>WYC_AC_PASSWORD</string>
<key>stapler_timeout</key>
<string>600</string>
</dict>
<key>ownership</key>
<string>recommended</string>
<key>postinstall_action</key>
<string>none</string>
<key>preserve_xattr</key>
<false/>
<key>signing_info</key>
<dict>
<key>identity</key>
<string>Developer ID Installer: wycomco GmbH (CD4727XSC2)</string>
</dict>
<key>suppress_bundle_relocation</key>
<true/>
<key>version</key>
<string>0.2.2</string>
<string>0.0.0</string>
</dict>
</plist>
77 changes: 59 additions & 18 deletions misty/payload/usr/local/wycomco/misty
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@
# Functions #
################################################################################

check_and_chown() {
local current_path="$1"
if [[ -d "$current_path" ]]; then
current_owner=$(ls -ld "$current_path" | awk '{print $3":"$4}')
if [[ "$current_owner" != "$Repo_uid_gid" ]]; then
log_message "stdout" "Changing ownership of $current_path to $Repo_uid_gid"
chown "$Repo_uid_gid" "$current_path"
fi
else
log_message "stderr" "$current_path does not exist, please check your repository's structure."
exit_error
fi
}

check_daemon() {
DaemonHourPlist=$(PlistBuddy -c "print :StartCalendarInterval:Hour" $DaemonPath 2>/dev/null)
DaemonMinutePlist=$(PlistBuddy -c "print :StartCalendarInterval:Minute" $DaemonPath 2>/dev/null)
Expand Down Expand Up @@ -82,51 +96,57 @@ check_repo() {
if [[ "$Is_SMB" == "yes" || "$Is_SMB" == "y" || "$Is_SMB" == "Y" || "$Is_SMB" == "Yes" || "$Is_SMB" == "YES" ]]; then
local RepoShare=$(echo "$RepoPath" | awk -F'/' '{print $3}')
if ! mount | grep -q "/Volumes/${RepoShare}"; then
if ! ping -q -c2 "${RepoName}" > /dev/null 2>&1; then
log_message "stderr" "Error: Remote repository \"$RepoName\" not accessible, please check."
exit_error
fi
local interval=1
local timeout=30
local elapsed=0
# Create the mount point if it doesn't exist
mkdir -p "/Volumes/${RepoShare}"
mount_smbfs "//${RepoUser}:${RepoPass}@${RepoName}/${RepoShare}" "/Volumes/${RepoShare}"
# URL-encode the password for special characters like "@"
EncodedPass=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${RepoPass}'))")
mount_smbfs "//${RepoUser}:${EncodedPass}@${RepoName}/${RepoShare}" "/Volumes/${RepoShare}"
while ! ls "${RepoPath}" &>/dev/null; do
sleep $interval
((elapsed+=interval))
if [ $elapsed -ge $timeout ]; then
log_message "stderr" "Repositories' share cannot be mounted within 30 seconds. Exiting ..."
exit 1
exit_error
fi
done
log_message "stdout" "Share ${RepoShare} was mounted."
fi
# 'Elif' loop applicable for locally attached volumes (USB, Thunderbolt)
elif [[ ! -d "$RepoPath" ]]; then
log_message "stderr" "Error: Repository \"$RepoPath\" not accessible, please check."
exit 1
exit_error
fi
}

check_space() {
local boot_disk=$(df -P "$Base_Path" | awk 'NR==2{print $1}')
local boot_space=$(df -k "$boot_disk" | awk 'NR==2{print int($4 / 1024 / 1024)}')
local boot_space=$(df -k "$Base_Path" | awk 'NR==2{print int($4 / 1024 / 1024)}')
local repo_disk=$(df -P "$RepoPath" | awk 'NR==2{print $1}')
local repo_space=$(df -k "$RepoPath" | awk 'NR==2{print int($4 / 1024 / 1024)}')

if [[ "$repo_disk" == "$boot_disk" ]]; then
local total_required_space=$((repo_required + diskspace_required))
if (( boot_space < total_required_space )); then
log_message "stderr" "Less than $total_required_space GB on the boot disk holding both repo and boot volume. Please provide more space."
exit 1
exit_error
fi
fi

if (( repo_space < repo_required )); then
log_message "stderr" "Less than $repo_required GB space on repo left. Please provide more space."
exit 1
exit_error
fi

if (( boot_space < diskspace_required )); then
log_message "stderr" "Less than $diskspace_required GB space on boot volume left. Please provide more space."
exit 1
exit_error
fi
}

Expand Down Expand Up @@ -187,6 +207,13 @@ download_macos() {
fi
}

exit_error() {
log_message "stdout" "misty run finished with errors, see \"/var/log/misty.log\" for error messages."
launchd_echo
exit 1

}

extract_macos_version() {
sed -n 's/.*macOS '"$1"'[^0-9]*\([0-9.]*\).*/\1/p' "$2" | tr -d '[:space:]'
}
Expand Down Expand Up @@ -218,6 +245,12 @@ get_timestamp() {
echo $(date -r "$current_time" +"%Y-%m-%d %H:%M:%S").$milliseconds
}

launchd_echo() {
if [[ ! -t 1 ]]; then
echo
fi
}

# Unified logging function
log_message() {
local log_type="$1" # Either 'stdout' or 'stderr'
Expand Down Expand Up @@ -424,8 +457,8 @@ if [[ ! -t 1 ]]; then
exec 2> >(while IFS= read -r line; do log_message "stderr" "$line"; done)
fi

repo_required=28 # Size required on repo for arm64 and x86_64 installer in GB, needed during creation
diskspace_required=30 # Size required on boot disk for installer and cache in GB
repo_required=30 # Size required on repo for arm64 and x86_64 installer in GB, needed during creation
diskspace_required=32 # Size required on boot disk for installer and cache in GB
Base_Path="/var/root/misty"
Mist_Path="/Users/Shared/Mist"
LogPath="$Base_Path/Logs"
Expand All @@ -439,20 +472,20 @@ fi
mist_check=$(which mist)
if [ $? -ne 0 ]; then
log_message "stderr" "Error: mist not found. Please install mist-cli or put it into the PATH."
exit 1
exit_error
fi
munkiimport_check=$(which munkiimport)
if [ $? -ne 0 ]; then
log_message "stderr" "Error: munkiimport not found. Please check your munki installation."
exit 1
exit_error
fi
if [[ ! -d "$LogPath" ]]; then
mkdir -p "$LogPath"
chmod 0700 "$LogPath"
fi
if [[ ! -d "$Template" || ! $(ls -A "$Template") ]]; then
log_message "stderr" "Error: The directory \"$Template\" either does not exist or is empty. Please reinstall misty."
exit 1
exit_error
fi

################################################################################
Expand Down Expand Up @@ -540,6 +573,7 @@ if [[ ! -t 1 ]]; then
log_message "stdout" "Start of misty run."
fi

check_daemon
check_repo

Repo_uid_gid=$(stat -f "%Su:%Sg" "$RepoPath")
Expand Down Expand Up @@ -642,19 +676,26 @@ fi
# Postinstall, makecatalogs #
################################################################################

# Check if any new package(s) were created
# Only proceed if any new package(s) were created
if [[ ( -n "$macos_13" || -n "$macos_14" || -n "$macos_15" ) ]]; then
# Ensure correct permissions in full misty path
munki_path="${munki_path%/}" # Remove trailing slash if present
IFS="/" read -A subdirs <<< "$munki_path" # Split munki_path into its components (subdirectories)
current_pkgs_path="$RepoPath/pkgs"
current_pkgsinfo_path="$RepoPath/pkgsinfo"
for dir in "${subdirs[@]}"; do # Iterate over each subdirectory, checking and applying permissions if needed
current_pkgs_path="$current_pkgs_path/$dir"
current_pkgsinfo_path="$current_pkgsinfo_path/$dir"
check_and_chown "$current_pkgs_path"
check_and_chown "$current_pkgsinfo_path"
done
if [[ -f "$Base_Path/usr/postinstall.sh" ]]; then
"$Base_Path/usr/postinstall.sh"
fi
makecatalogs "$RepoPath" | grep 'warning'
fi

check_daemon
log_message "stdout" "Finished misty run."
# Enter an empty line if run as launchd to StandardOutPath
if [[ ! -t 1 ]]; then
echo
fi

launchd_echo
exit 0
42 changes: 42 additions & 0 deletions mk_misty
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/zsh
#
# Clone the current repo state and create an installer pkg for misty

REPO_URL="https://github.com/wycomco/misty.git"
TMP_DIR="/var/tmp/misty_pkgbuild"
ORIGINAL_DIR=$(pwd)

if [ -d "$TMP_DIR" ]; then
echo "Found previously cloned repo in $TMP_DIR, deleting ..."
rm -rf "$TMP_DIR"
fi

git clone "$REPO_URL" "$TMP_DIR"
if [ $? -ne 0 ]; then
echo "Failed to clone repository."
exit 1
fi

cd "$TMP_DIR" || { echo "Failed to cd into $TMP_DIR"; exit 1; }

VERSION=$(git describe --tags --abbrev=0)
echo "Current version of misty is $VERSION"
echo "Replacing version in build-info.plist..."
sed -E -i '' "s/[0-9]+.[0-9]+.[0-9]+/${VERSION}/g" misty/build-info.plist

munkipkg misty
munkipkg_success="$?"
echo "Resetting version in build-info.plist..."
sed -E -i '' "s/${VERSION}/0.0.0/g" misty/build-info.plist

if [ "$munkipkg_success" -ne 0 ]; then
echo "munkipkg failed."
cd "$ORIGINAL_DIR" # Return to original directory
exit 1
fi

open misty/build
cd "$ORIGINAL_DIR"

exit 0

0 comments on commit e325831

Please sign in to comment.