5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

OS X El Capitan(10.11.6)のインストールISOイメージ作成

Last updated at Posted at 2016-09-09

概要

環境

  • AppStore から、El Capitanがダウンロードできる OS X 実行環境

手順

  1. AppStoreから、OS X El Capitanをダウンロード

    • なんか言われるけど、[続ける]
      AppStoreOSX
    • インストーラが立ち上がるので、とりあえず終了
      終了する
    • アプリケーション に OS X El Capitan インストールというのができてる。
  2. ターミナルを開いて、スクリプト取得し、実行。

    iso作成スクリプト取得、実行

cd ~
mkdir iso
cd iso
curl -O https://raw.githubusercontent.com/kholia/OSX-KVM/master/create_osx_install_iso.sh
chmod +x ./create_osx_install_iso.sh
curl -O https://raw.githubusercontent.com/kholia/OSX-KVM/master/pbzx
chmod +x ./pbzx
time sudo ./create_osx_install_iso.sh -n -m 2

3. 待つ

    ```shell-session:実行例
bash-3.2$ cd ~
bash-3.2$ mkdir iso
bash-3.2$ cd iso
bash-3.2$ curl -O https://raw.githubusercontent.com/kholia/OSX-KVM/master/create_osx_install_iso.sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 26823  100 26823    0     0  56285      0 --:--:-- --:--:-- --:--:-- 56350
bash-3.2$ chmod +x ./create_osx_install_iso.sh
bash-3.2$ time sudo ./create_osx_install_iso.sh -n -m 2
Looking for downloaded OS upgrades... found
Using "/Applications/Install OS X El Capitan.app".
Detecting OS X name for installation... OS X El Capitan
Creating temporary directory... succeed
Mounting InstallESD.dmg... 
/dev/disk1              GUID_partition_scheme          
/dev/disk1s1            EFI                            
/dev/disk1s2            Apple_HFS                       
.
.
.
.
Converting succeed

    Resulting .iso location:
/Users/mt08/iso/Install_OS_X_10.11.6_El_Capitan.iso

    Removing temporary files...

    real    22m45.122s
user    0m12.968s
sys     0m21.926s
bash-3.2$

その他

  • メモ

    ほにゃらら.vmx

...
smc.present = "TRUE"
smc.version = "0"


<!--
![VMWareOSX01.png](https://qiita-image-store.s3.amazonaws.com/0/75594/01c3b4cf-8019-0ec5-8c7c-0dd9f591ddb7.png)

- 夢を見たようです.. ググってください。<br>![VMWareOSX01.png](https://qiita-image-store.s3.amazonaws.com/0/75594/01c3b4cf-8019-0ec5-8c7c-0dd9f591ddb7.png)

```bash
#!/bin/bash

# Script for building bootable .iso images from downloaded OS X upgrade
# Copyright (C) 2015-2016 Karlson2k (Evgeny Grin)
#
# You can run, copy, modify, publish and do whatever you want with this
# script as long as this message and copyright string above are preserved.
# You are also explicitly allowed to reuse this script under any LGPL or
# GPL license or under any BSD-style license.
#
#
# Latest version:
# https://raw.githubusercontent.com/Karlson2k/k2k-OSX-Tools/master/Create_osx_install_iso/create_osx_install_iso.sh
#
# Version 1.0.6

function myreadlink() {
  (
    cd $(dirname $1)
    if [[ -L $1 ]] ; then
        cd $(dirname $(readlink $1))
    else
        cd $(dirname $1)
    fi
    echo $PWD/$(basename $1)
  )
}

readonly script_org_name='create_osx_install_iso.sh' || exit 127
unset work_dir script_name tmp_dir OSX_inst_name OSX_inst_inst_dmg_mnt \
	OSX_inst_img_rw_mnt OSX_inst_img_rw_dev || exit 127
work_dir="$PWD"
script_dir="$(dirname $(myreadlink "$0"))"
cd "$work_dir"
save_IFS="$IFS" || exit 127
export LANG='en_US.UTF-8' || exit 127 # prevent localization of output, not really required

[[ `ps -o comm -p $$ | tail -n1 2>/dev/null` =~ bash$ ]] || {
	echo "Script is designed to be run only with bash"
	exit 127
}
[[ "$(uname -s)" == Darwin ]] || {
	echo "Script can be run only on Mac OS X"
	exit 127
}

cleanup() {
	trap - SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP EXIT
	if [[ -n $tmp_dir ]] && [[ -e "$tmp_dir" ]]; then
		if [[ -e "$OSX_inst_img_rw_dev" ]]; then
			echo "Unmounting writable image..."
			hdiutil detach "$OSX_inst_img_rw_dev" -force
		fi
		if [[ -e "$OSX_inst_img_rw_mnt" ]]; then
			echo "Unmounting writable image..."
			hdiutil detach "$OSX_inst_img_rw_mnt" -force
		fi
		if [[ -e "$OSX_inst_inst_dmg_mnt" ]]; then
			echo "Unmounting temporary mounted source image..."
			hdiutil detach "$OSX_inst_inst_dmg_mnt" -force
		fi
		echo "Removing temporary files..."
		rm -fdR "$tmp_dir"
	fi
}

trap '{ exit_code="$?"; cleanup; exit $exit_code; }' EXIT

echo_term_ansi_m() {
	local n_param=''
	if [[ "$1" == "-n" ]]; then
		n_param="$1"
		shift
	elif [[ -z "$1" ]]; then shift
	fi
	local m_code="$1"
	shift
	if [[ -t 1 ]]; then
		echo $n_param $'\e['"${m_code}m$@"$'\e[0m'
	else
		echo $n_param "$@"
	fi
}

echo_neutral() {
	echo "$@"
}

echo_enh() {
	echo_term_ansi_m '1;97' "$@"
}

echo_enh_n() {
	echo_term_ansi_m -n '1;97' "$@"
}

echo_positive() {
	echo_term_ansi_m '1;92' "$@"
}

echo_positive_n() {
	echo_term_ansi_m -n '1;92' "$@"
}

echo_warning() {
	echo_term_ansi_m '1;93' "$@"
}

echo_warning_n() {
	echo_term_ansi_m -n '1;93' "$@"
}

echo_error() {
	echo_term_ansi_m '1;91' "$@" 1>&2
}
echo_error_n() {
	echo_term_ansi_m -n '1;91' "$@" 1>&2
}

exit_with_error() {
	trap - SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP EXIT
	if [[ -n $1 ]]; then
		echo_error "Error: $1"
	else
		echo_error "Error."
	fi
	cleanup
    [[ $2 > 0 ]] && exit $2
    exit 1
}

trap '{ exit_with_error "unexpected interrupt at line $LINENO"; exit 255; }' SIGHUP SIGTERM SIGQUIT SIGINT SIGSTOP SIGTSTP

# trap 'echo "Line number: $LINENO"; read -p "\"Enter\" to continue" ' DEBUG

stage_start() {
	echo_enh_n "$@... "
}

stage_start_nl() {
	stage_start "$@"
	echo ''
}

stage_end_ok() {
	if [[ -z "$@" ]]; then
		echo_positive "OK"
	else
	    echo_positive "$@"
	fi
}

stage_end_warn() {
	if [[ -z "$@" ]]; then
		echo_warning "OK, but with warnings"
	else
	    echo_warning "$@"
	fi
}

is_answer_valid() {
	local answ="$1"
	shift
	while [[ -n $1 ]]; do
		[[ "$answ" == "$1" ]] && return 0
		shift
	done
	return 1
}

script_name="$(basename "${BASH_SOURCE[0]}" 2>/dev/null)"
[[ -n "$script_name" ]] || script_name="${0##*/}" # fallback
[[ -n "$script_name" ]] || script_name="${script_org_name}" # second fallback

script_version="$(sed -n -e '\|^# Version| {s|^# Version \(.*$\)|\1|p; q;}' "${BASH_SOURCE[0]}" 2>/dev/null)" || unset script_version
[[ -n "$script_version" ]] || script_version="Unknown"

print_help() {
	echo "\
Script for creating .iso images from downloaded OS X upgrade application.
Usage:"
	echo_enh_n "      $script_name"; echo " [options]

Valid options are:
      -a, --app[lication] <OS X Install app>
                   Path and name of OS X upgrade application.
                   Path can be omitted if application is located at
                   default path.
      -i, --iso <path with name for .iso>
                   Path with optional name for output .iso
      -m, --method <D>
                   Use method number D to create installation image:
                   Method 1 create image that most close to Apple's image,
                   but potentially less compatible with some BIOSes/EFI.
                   Method 2 create more BIOS/EFI-friendly images, but
                   require more disk space for conversion.
                   Method 3 can produce bootable images without super
                   user rights.
      -n, --nosudo
                   Do not use sudo command
      -v, --verify
                   Do not skip verifications (slow down image creation)
      -h, --help   Print this message and exit
      -V, --version
                   Print version information and exit"

}

print_version() {
	echo "${script_org_name} version $script_version"
}

exit_with_cmd_err() {
	echo_error "$@"
	print_help 1>&2
	exit 32
}

unset cmd_par_app cmd_par_iso test_name ver_opt cr_method || exit_with_error "Can't unset variable"
ver_opt='--noverify'
while [[ -n "$1" ]]; do
	case "$1" in
		-a | --app | --application ) cmd_par_app="$2"
			[[ -n "$cmd_par_app" ]] && [[ "$cmd_par_app" != "--iso" ]] || exit_with_cmd_err "No Application name given for $1"
			shift 2 ;;
		-i | --iso ) cmd_par_iso="$2"
			[[ -n "$cmd_par_iso" ]] && [[ "$cmd_par_iso" != "--app" ]] || exit_with_cmd_err "No .iso name given for $1"
			shift 2 ;;
		-m | --method ) [[ -z "$2" ]] && exit_with_cmd_err "Method not specified for $1"
			cr_method="method${2}"
			shift 2 ;;
		-m* ) cr_method="method${1#-m}"; shift ;;
		--method* ) cr_method="method${1#--method}"; shift ;;
		-n | --nosudo ) allow_sudo='no'; shift ;;
		-v | --verify ) unset ver_opt; shift ;;
		-h | --h | --help ) print_help; exit 0 ;;
		-V | --version ) print_version; exit 0 ;;
		*) exit_with_cmd_err "Unknown option \"$1\""
	esac
done

[[ "${cr_method-notset}" == "notset" ]] || [[ "$cr_method" =~ ^"method"[1-3]$ ]] || exit_with_cmd_err "Unknown creation method specified: ${cr_method#method}"

check_intall_app() {
	[[ -n "$1" ]] || return 3
	[[ -d "$1" ]] || return 2
	[[ -e "$1/Contents/SharedSupport/InstallESD.dmg" ]] || return 1
	return 0
}

if [[ -z "$cmd_par_app" ]]; then
	stage_start "Looking for downloaded OS upgrades"
	unset test_name || exit_with_error
	IFS=$'\n'
	dirlist=(`ls -1d "/Applications/Install OS X "*".app/" | sed -n -e 's|^\(/Applications/Install OS X .*\.app\)/$|\1|p' `) || exit_with_error "Can't find downloaded OS X upgrade"
	IFS="$save_IFS"
	[[ ${#dirlist[@]} -eq 0 ]] && exit_with_error "Can't find downloaded OS X upgrade"
	stage_end_ok "found"
	if [[ ${#dirlist[@]} -gt 1 ]]; then
		echo "Several OS upgrades were found."
		echo "Which one OS upgrade do you want to use?"
		valid_answers=()
		unset test_name || exit_with_error
		for ((i=0;i<${#dirlist[@]};i++)); do
			test_name="${dirlist[$i]#/Applications/Install }"
			echo "$((i+1))) ${test_name%.app}"
			valid_answers[$i]="$((i+1))"
		done
		read -n 1 -p "[1-$i, q for quit]: " answer
		echo ''
		until is_answer_valid $answer ${valid_answers[@]} 'q'; do
			echo "'$answer' is incorrect response"
			read -n 1 -p "Select ""$(seq -s ', ' -t '\b\b' 1 $i)"" or q for quit: " answer
			echo ''
		done
		[[ "$answer" == "q" ]] && { echo_warning "Aborted."; exit 2; }
		OSX_inst_app="${dirlist[$((answer-1))]}"
	else
		OSX_inst_app="${dirlist[0]}"
	fi
	echo_enh "Using \"$OSX_inst_app\"."
else
	stage_start "Checking for specified OS upgrade"
	unset OSX_inst_app || exit_with_error
	if check_intall_app "${cmd_par_app%/}"; then
		# direct location with path
		if [[ "${cmd_par_app:0:1}" == "/" ]]; then
			OSX_inst_app="${cmd_par_app%/}" # absolute path
		else
			OSX_inst_app="$(pwd)/${cmd_par_app%/}" # relative path
			test_name="$(cd "$OSX_inst_app/" 2>/dev/null && pwd)" || unset test_name || exit_with_error
			[[ -n "$test_name" ]] && OSX_inst_app="$test_name" # use absolute path if possible
		fi
	elif [[ "${cmd_par_app%%/*}" == "${cmd_par_app%/}" ]]; then
		# check /Applications
		test_name="${cmd_par_app%/}"
		test_name="${test_name%.app}.app"
		if check_intall_app "/Applications/${test_name}"; then
			OSX_inst_app="/Applications/${test_name}"
		elif check_intall_app "/Applications/Install ${test_name}"; then
			OSX_inst_app="/Applications/Install ${test_name}"
		elif check_intall_app "/Applications/Install OS X ${test_name}"; then
			OSX_inst_app="/Applications/Install OS X ${test_name}"
		fi
	fi
	[[ -n "$OSX_inst_app" ]] || exit_with_error "\"$cmd_par_app\" is not valid OS X Install application"
	stage_end_ok "found"
	echo_enh "Using \"$OSX_inst_app\"."
fi

stage_start "Detecting OS X name for installation"
unset test_name OSX_inst_prt_name || exit_with_error
test_name=$(sed -n -e '\|<key>CFBundleDisplayName</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }' \
	 "$OSX_inst_app/Contents/Info.plist" 2>/dev/null) || unset test_name
if [[ -n "$test_name" ]]; then
	OSX_inst_name="${test_name#Install }"
	OSX_inst_prt_name="Install $OSX_inst_name"
	stage_end_ok "$OSX_inst_name"
else
	OSX_inst_name=$(echo "$OSX_inst_app"|sed -n -e's|^.*Install \(OS X .\{1,\}\)\.app.*$|\1|p' 2>/dev/null) || unset OSX_inst_name || exit_with_error
	[[ -z "$OSX_inst_name" ]] && OSX_inst_name="OS X"
	OSX_inst_prt_name="Install $OSX_inst_name"
	stage_end_warn "guessed \"$OSX_inst_name\""
fi

stage_start "Creating temporary directory"
tmp_dir="$(mktemp -d -t osx_iso_tmpdir)" || exit_with_error "Can't create tmp directory"
# mkdir "tmp-tmp"
# tmp_dir=$(cd tmp-tmp && pwd) || exit_with_error "Can't create tmp directory"
stage_end_ok "succeed"

stage_start_nl "Mounting InstallESD.dmg"
OSX_inst_inst_dmg="$OSX_inst_app"'/Contents/SharedSupport/InstallESD.dmg'
OSX_inst_inst_dmg_mnt="$tmp_dir/InstallESD_dmg_mnt"
hdiutil attach "$OSX_inst_inst_dmg" -kernel -readonly -nobrowse ${ver_opt+-noverify} -mountpoint "$OSX_inst_inst_dmg_mnt" || exit_with_error "Can't mount installation image"
OSX_inst_base_dmg="$OSX_inst_inst_dmg_mnt/BaseSystem.dmg" || exit_with_error
stage_end_ok "Mounting succeed"

stage_start "Calculating required image size"
unset OSX_inst_inst_dmg_used_size OSX_inst_base_dmg_real_size OSX_inst_base_dmg_size || exit_with_error "Can't unset variables"
OSX_inst_inst_dmg_used_size=$(hdiutil imageinfo "$OSX_inst_inst_dmg" -plist | \
	sed -En -e '\|<key>Total Non-Empty Bytes</key>| { N; s|^.*<integer>(.+)</integer>.*$|\1|p; q; }') || unset OSX_inst_inst_dmg_used_size
OSX_inst_base_dmg_real_size=$(hdiutil imageinfo "$OSX_inst_base_dmg" -plist | \
	sed -En -e '\|<key>Total Bytes</key>| { N; s|^.*<integer>(.+)</integer>.*$|\1|p; q; }') || unset OSX_inst_base_dmg_real_size
OSX_inst_base_dmg_size=$(stat -f %z "$OSX_inst_base_dmg") || unset OSX_inst_base_dmg_size
((OSX_inst_base_dmg_size=(OSX_inst_base_dmg_size/512)*512)) # round to sector bound
if !((OSX_inst_inst_dmg_used_size)) || !((OSX_inst_base_dmg_real_size)) || !((OSX_inst_base_dmg_size)); then
	((OSX_inst_img_rw_size=10*1024*1024*1024))
	stage_end_warn "Can't calculate, will use $OSX_inst_img_rw_size ($((OSX_inst_img_rw_size/(1024*1024))) MiB)"
else
	((OSX_inst_img_rw_size=OSX_inst_base_dmg_real_size+(OSX_inst_inst_dmg_used_size-OSX_inst_base_dmg_size) ))
	((OSX_inst_img_rw_size+=OSX_inst_img_rw_size/10)) # add 10% for overhead, no need to be precise
	((OSX_inst_img_rw_size=(OSX_inst_img_rw_size/512 + 1)*512)) # round to sector bound
	stage_end_ok "$OSX_inst_img_rw_size ($((OSX_inst_img_rw_size/(1024*1024))) MiB)"
fi

stage_start "Checking for available disk space"
unset tmp_dir_free_space || exit_with_error
tmp_dir_free_space="$(df -bi "$tmp_dir" | \
	sed -nE -e 's|^.+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+([0-9]+)[[:space:]]+[0-9]{1,3}%[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]{1,3}%[[:space:]]+/.*$|\1|p' )" || unset tmp_dir_free_space
if [[ "${tmp_dir_free_space-notset}" == "notset" ]] || ( [[ -n "$tmp_dir_free_space" ]] && !((tmp_dir_free_space)) ); then
	tmp_dir_free_space='0'
	stage_end_warn "Can't determinate"
else
	((tmp_dir_free_space*=512))
	if ((tmp_dir_free_space < OSX_inst_img_rw_size)); then
		stage_end_warn "$tmp_dir_free_space ($((tmp_dir_free_space/(1024*1024))) MiB), image creation may fail"
	else
		stage_end_ok "$tmp_dir_free_space ($((tmp_dir_free_space/(1024*1024))) MiB)"
	fi
fi

stage_start "Checking for super user rights"
unset have_su_rights use_sudo sudo_prf || exit_with_error "Can't unset variables"
if [[ `id -u` != '0' ]]; then
	have_su_rights='no'
else
	have_su_rights='yes'
fi
if [[ "$have_su_rights" == "yes" ]] || [[ "$allow_sudo" != "yes" ]]; then
	use_sudo='no'
	sudo_prf=''
else
	use_sudo='yes'
	sudo_prf='sudo'
fi
if [[ "$have_su_rights" == "yes" ]]; then
	stage_end_ok 'Owned'
else
	stage_end_warn "Not owned"
fi

stage_start "Choosing creation method"
if [[ -n "$cr_method" ]]; then
	stage_end_ok "Method ${cr_method#method}, specified on command line"
	if [[ "$cr_method" != "method3" ]] && [[ "$have_su_rights" != "yes" ]] && [[ "$allow_sudo" != "yes" ]]; then
		echo_warning "Resulting image probably will be unbootable as method ${cr_method#method} require super user rights and sudo was disabled by command line"
	fi
elif [[ "$have_su_rights" != 'yes' ]]; then
	cr_method="method3"
	stage_end_ok "Method 3 as safest without super user right"
elif ((tmp_dir_free_space < OSX_inst_img_rw_size*3)); then
	cr_method="method1"
	stage_end_ok "Method 1 due to limited disk space"
else
	cr_method="method2"
	stage_end_ok "Method 2"
fi

unset img_bootable || exit_with_error
if [[ "$cr_method" == "method1" ]] || [[ "$cr_method" == "method2" ]]; then
	if [[ "$cr_method" == "method1" ]]; then
		stage_start_nl "Converting BaseSystem.dmg to writable image"
		OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
		hdiutil convert "$OSX_inst_base_dmg" -format UDSB -o "$OSX_inst_img_rw" -pmap || exit_with_error "Can't convert to writable image"
		stage_end_ok "Converting succeed"
	elif [[ "$cr_method" == "method2" ]]; then
		stage_start_nl "Creating installation image from BaseSystem.dmg"
		OSX_inst_img_dmg_tmp="$tmp_dir/OS_X_Install.dmg" || exit_with_error
		hdiutil create  "${OSX_inst_img_dmg_tmp}" -srcdevice "$OSX_inst_base_dmg" -layout ISOCD || exit_with_error "Can't create writable image"
		stage_end_ok "Creating succeed"

		stage_start_nl "Converting installation image to writeable format"
		OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
		hdiutil convert "$OSX_inst_img_dmg_tmp" -format UDSB -o "$OSX_inst_img_rw" -pmap || exit_with_error "Can't convert to writable image"
		rm -f "$OSX_inst_img_dmg_tmp"
		stage_end_ok "Converting succeed"
	fi

	stage_start "Resizing writable image"
	hdiutil resize -size "$OSX_inst_img_rw_size" "$OSX_inst_img_rw" -nofinalgap || exit_with_error "Can't resize writable image"
	stage_end_ok "Resizing succeed"

	stage_start_nl "Mounting writable image"
	OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
	hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
	stage_end_ok "Mounting succeed"
elif [[ "$cr_method" == "method3" ]]; then
	stage_start_nl "Creating blank writable image"
	OSX_inst_img_rw="$tmp_dir/OS_X_Install.sparsebundle"
	OSX_inst_img_rw_tmp_name="$OSX_inst_prt_name" || exit_with_error
	hdiutil create -size "$OSX_inst_img_rw_size" "$OSX_inst_img_rw" -type SPARSEBUNDLE -fs HFS+ -layout ISOCD -volname "$OSX_inst_img_rw_tmp_name" || exit_with_error "Can't create writable image"
	stage_end_ok "Creating succeed"

	stage_start_nl "Mounting writable image"
	OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
	hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
	stage_end_ok "Mounting succeed"

	stage_start "Detecting mounted image device node"
	OSX_inst_img_rw_dev=`diskutil info -plist "$OSX_inst_img_rw_mnt" | sed -n -e '\|<key>DeviceIdentifier</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|/dev/\1|p; q; }'` && \
		[[ -n "$OSX_inst_img_rw_dev" ]] || exit_with_error "Can't find device node"
	stage_end_ok "$OSX_inst_img_rw_dev"

	stage_start_nl "Restoring BaseSystem.dmg to writable image"
	asr restore --source "$OSX_inst_base_dmg" --target "$OSX_inst_img_rw_dev" --erase --noprompt $ver_opt --buffers 1 --buffersize 64m || exit_with_error "Can't restore BaseSystem.dmg to writable image"
	unset OSX_inst_img_rw_mnt || exit_with_error # OSX_inst_img_rw_mnt is no valid anymore as image was remounted to different mountpoint
	img_bootable='yes'
	stage_end_ok "Restoring succeed"

	stage_start "Detecting re-mounted image volume name"
	unset OSX_inst_img_rw_volname || exit_with_error
	OSX_inst_img_rw_volname=`diskutil info -plist "$OSX_inst_img_rw_dev" | sed -n -e '\|<key>VolumeName</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }'` || unset OSX_inst_img_rw_folname
	if [[ -z "$OSX_inst_img_rw_volname" ]]; then
		stage_end_warn "can't detect"
	else
		osascript -e "Tell application \"Finder\" to close the window \"$OSX_inst_img_rw_volname\"" &>/dev/null
		stage_end_ok "$OSX_inst_img_rw_volname"
	fi

	stage_start_nl "Remounting writable image to predefined mountpoint"
	hdiutil detach "$OSX_inst_img_rw_dev" -force || exit_with_error "Can't unmount image"
	unset OSX_inst_img_rw_dev
	OSX_inst_img_rw_mnt="$tmp_dir/OS_X_Install_img_rw_mnt"
	hdiutil attach "$OSX_inst_img_rw" -readwrite -nobrowse -mountpoint "$OSX_inst_img_rw_mnt" ${ver_opt+-noverify} || exit_with_error "Can't mount writable image"
	stage_end_ok "Remounting succeed"

else
	exit_with_error "Unknown creation method"
fi

custom_boot_plist=
if [[ -f "$script_dir/org.chameleon.boot.plist" ]] ; then
    custom_boot_plist="$script_dir/org.chameleon.boot.plist"
fi
if [[ -f "$work_dir/org.chameleon.boot.plist" ]] ; then
    custom_boot_plist="$work_dir/org.chameleon.boot.plist"
fi
if [[ -n "$custom_boot_plist" ]] ; then
    stage_start "Installing custom boot.plist"
    mkdir $OSX_inst_img_rw_mnt/Extra
    cp "$custom_boot_plist" "$OSX_inst_img_rw_mnt/Extra/org.chameleon.boot.plist"
    stage_end_ok "done"
fi

stage_start "Detecting OS X version on image"
unset OSX_inst_ver || exit_with_error "Can't unset variable"
OSX_inst_img_rw_ver_file="$OSX_inst_img_rw_mnt/System/Library/CoreServices/SystemVersion.plist" || exit_with_error "Can't set variable"
OSX_inst_ver=`sed -n -e '\|<key>ProductUserVisibleVersion</key>| { N; s|^.*<string>\(.\{1,\}\)</string>.*$|\1|p; q; }' "$OSX_inst_img_rw_ver_file"` || unset OSX_inst_ver
if [[ -z "$OSX_inst_ver" ]]; then
	stage_end_warn "not detected"
else
	stage_end_ok "$OSX_inst_ver"
fi

[[ "$OSX_inst_ver" == "10.11" ]] || [[ "$OSX_inst_ver" =~ 10.11.[1-6] ]] || \
	echo_warning "Warning! This script is tested only with images of OS X versions 10.11 and 10.11.1-10.11.4. Use at your own risk!"

stage_start_nl "Renaming partition on writeable image"
if ! diskutil rename "$OSX_inst_img_rw_mnt" "$OSX_inst_prt_name"; then
	stage_end_warn "Partition was not renamed"
else
	unset OSX_inst_img_rw_volname
	stage_end_ok "Renamed to \"$OSX_inst_prt_name\""
fi

stage_start "Copying BaseSystem.dmg to writeable image"
cp -p "$OSX_inst_base_dmg" "$OSX_inst_img_rw_mnt/" || exit_with_error "Copying BaseSystem.dmg failed"
cp -p "${OSX_inst_base_dmg%.dmg}.chunklist" "$OSX_inst_img_rw_mnt/" || exit_with_error "Copying BaseSystem.chunklist failed"
stage_end_ok

stage_start "Extracting kernel from Essentials.pkg (very slow step)"
cd "$OSX_inst_img_rw_mnt"
"$script_dir/pbzx" "$OSX_inst_inst_dmg_mnt/Packages/Essentials.pkg" | cpio -idmu ./System/Library/Kernels  || exit_with_error "Extraction of kernel failed"
cd "$work_dir"
stage_end_ok

stage_start "Replacing Packages symlink with real files"
rm -f "$OSX_inst_img_rw_mnt/System/Installation/Packages" || exit_with_error "Deleting Packages symlink failed"
cp -pPR "$OSX_inst_inst_dmg_mnt/Packages" "$OSX_inst_img_rw_mnt/System/Installation/" || exit_with_error "Copying Packages failed"
stage_end_ok

stage_start "Configuring image as bootable"
OSX_inst_img_rw_CoreSrv="$OSX_inst_img_rw_mnt/System/Library/CoreServices" || exit_with_error
if bless --folder "$OSX_inst_img_rw_CoreSrv" \
	--file "$OSX_inst_img_rw_CoreSrv/boot.efi" --openfolder "$OSX_inst_img_rw_mnt" --label "Install $OSX_inst_name"; then
	stage_end_ok
else
	stage_end_warn "Failed, image may not be bootable"
fi

stage_start_nl "Unmounting InstallESD.dmg"
hdiutil detach "$OSX_inst_inst_dmg_mnt" -force || exit_with_error "Can't unmount InstallESD.dmg"
unset OSX_inst_img_rw_dev
stage_end_ok "Unmounting succeed"

stage_start_nl "Unmounting writable images"
hdiutil detach "$OSX_inst_img_rw_mnt" -force || exit_with_error "Can't unmount writable image"
unset OSX_inst_img_rw_dev
stage_end_ok "Unmounting succeed"

insert_version_into_name() {
	local name="$1"
	local version="$2"
	[[ -z "$name" ]] && return 1
	[[ -z "$version" ]] && { echo "$name"; return 0; }
	local result
	local ins_aft
	if [[ "$name" =~ (^|[[:space:]])"OS X"($|[[:space:]]) ]]; then
		ins_aft="OS X"
	elif [[ "$name" =~ (^|[[:space:]])"MacOS X"($|[[:space:]]) ]]; then
		ins_aft="MacOS X"
	fi
	if [[ -n "$ins_aft" ]]; then
		result=$(echo -n "$name" | sed -n -e 's|^\(.*[[:<:]]'"$ins_aft"'[[:>:]]\).*$|\1|p') || return 2
		[[ -z "$result" ]] && return 2
		result+=" $version" # allow any regex/special symbols in $version
		result+=$(echo -n "$name" | sed -n -e 's|^.*[[:<:]]'"$ins_aft"'[[:>:]]\(.*\)$|\1|p') || return 2
	else
		result="$name (OS X $version)"
	fi
	[[ -z "$result" ]] && return 1
	echo "$result"
	return 0
}

stage_start "Checking for output directory and image name"
unset iso_name out_dir test_name || exit_with_error
if [[ -z "$cmd_par_iso" ]]; then
	iso_name="$(insert_version_into_name "$OSX_inst_name" "$OSX_inst_ver")" || exit_with_error "Script internal error"
	iso_name="Install_${iso_name// /_}.iso"
	if [[ -z "$work_dir" ]] || [[ ! -w "$work_dir/" ]]; then
		[[ -n "$HOME" ]] &&	out_dir="$HOME/Desktop" # use Desktop as fallback
		if [[ -z "$out_dir" ]] || [[ ! -w "$out_dir/" ]]; then
			# use script location directory as fallback
			script_path="$(dirname "${BASH_SOURCE[0]}" 2>/dev/null)"
			[[ -n "$script_path" ]] || script_path="${0%/*}"
			[[ -n "$script_path" ]] && out_dir="$(cd "$script_path"2 2>/dev/null && pwd)"
		fi
		[[ -n "$out_dir" ]] && [[ -w "$out_dir/" ]] || out_dir="${0%/*}"
		[[ -n "$out_dir" ]] && [[ -w "$out_dir/" ]] || exit_with_error "Can't find writable output directory"
		stage_end_warn "Directory \"$work_dir\" seems to be unwritable, \"$out_dir/$iso_name\" will be used for output"
	else
		out_dir="$work_dir"
		stage_end_ok "$work_dir/$iso_name"
	fi
else
	test_name="${cmd_par_iso}"
	[[ "${test_name:0:1}" == "/" ]] || test_name="$work_dir/$test_name"
	if [[ -d "$test_name" ]] || [[ "${test_name%/}" != "${test_name}" ]]; then
		# cmd_par_iso is output directory without filename
		out_dir="${cmd_par_iso%/}"
	else
		iso_name="${cmd_par_iso##*/}"
		if [[ "$iso_name" == "$cmd_par_iso" ]]; then
			out_dir="$work_dir"
		else
			out_dir="${cmd_par_iso%/*}"
		fi
	fi

	if [[ -z "$iso_name" ]]; then
		iso_name="$(insert_version_into_name "$OSX_inst_name" "$OSX_inst_ver")" || exit_with_error "Script internal error"
		iso_name="Install_${OSX_inst_name// /_}.iso"
	fi
	iso_name="${iso_name%.iso}.iso"

	[[ "${out_dir:0:1}" == "/" ]] || [[ -z "$out_dir" ]] || out_dir="$work_dir/${out_dir}" # relative path
	[[ -d "$out_dir/" ]] || mkdir "$out_dir/" || exit_with_error "Can't create specified output directory."
	unset test_name || exit_with_error
	test_name="$(cd "$out_dir/" 2>/dev/null && pwd)"
	[[ -n "$test_name" ]] && out_dir="$test_name" # replace with absolute path if possible
	stage_end_ok "specified on command line: \"$out_dir/$iso_name\""
fi

stage_start_nl "Converting writeable image to .iso"
unset iso_created || exit_with_error
OSX_inst_result_image_ro="$out_dir/$iso_name" || exit_with_error
OSX_inst_result_flag="$tmp_dir/output_image_is_ready" || exit_with_error
rm -f "$OSX_inst_result_flag" || exit_with_error
[[ -e "$OSX_inst_result_image_ro" ]] && exit_with_error "\"$OSX_inst_result_image_ro\" already exist"
makehybrid_errout="$tmp_dir/hdiutil_makehybrid_erroutput" || exit_with_error
{ { hdiutil makehybrid -o "$OSX_inst_result_image_ro" "$OSX_inst_img_rw" -hfs -udf -default-volume-name "$OSX_inst_prt_name" 2>&1 1>&3 && \
	touch "$OSX_inst_result_flag"; } | tee "$makehybrid_errout"; } 3>&1 1>&2 # output stderr to stderr and save it to file at the same time
if ! [[ -e "$OSX_inst_result_flag" ]]; then
	if fgrep -Fiqs -e 'Operation not permitted' "$makehybrid_errout" && [[ "$have_su_rights" != "yes" ]]; then
		echo_warning "Creation of optimal .iso image failed without super user rights."
		if [[ "$allow_sudo" == "yes" ]]; then
			rm -f "$OSX_inst_result_image_ro"
			echo_warning "Next command will be executed with sudo, you may be asked for password."
			$sudo_prf hdiutil makehybrid -o "$OSX_inst_result_image_ro" "$OSX_inst_img_rw" -hfs -udf -default-volume-name "$OSX_inst_prt_name" && touch "$OSX_inst_result_flag"
		else
			echo_warning "Usage os sudo was disabled by command parameter"
		fi
	fi
fi
if [[ -e "$OSX_inst_result_flag" ]]; then
	img_bootable='yes'
	stage_end_ok "Converting succeed"
else
	rm -f "$OSX_inst_result_image_ro"
	stage_end_warn "Creation of optimal .iso was failed, will try to use workarounds to build usable .iso"
	[[ "$img_bootable" != 'yes' ]] && echo_warning "Resulting image may not be bootable"

	stage_start "Shrinking image"
	if hdiutil resize -sectors min "$OSX_inst_img_rw" -nofinalgap; then
		stage_end_ok "succeed"
	else
		stage_end_warn "failed, image remains larger than required"
	fi

	stage_start_nl "Converting image to .iso-like format"
	OSX_inst_result_tmp_image="${OSX_inst_result_image_ro%.iso}.cdr" || exit_with_error
	[[ -e "$OSX_inst_result_tmp_image" ]] && OSX_inst_result_tmp_image="$tmp_dir/tmp_cdr_img.cdr"
	hdiutil convert "$OSX_inst_img_rw" -format UDTO -o "$OSX_inst_result_tmp_image" && \
		mv -vn "$OSX_inst_result_tmp_image" "$OSX_inst_result_image_ro" && iso_created='yes'
	if [[ "$iso_created" != "yes" ]]; then
		rm -f "$OSX_inst_result_tmp_image"
		rm -f "$OSX_inst_result_image_ro"
		exit_with_error "Image converting failed"
	fi
	stage_end_ok "Converting succeed"
fi

echo_enh "
Resulting .iso location:"
echo "$OSX_inst_result_image_ro
"
[[ "$img_bootable" != 'yes' ]] && echo_warning "Resulting .iso may not be bootable"

-->

5
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?