Commit f775b972 authored by Nikos Skalkotos's avatar Nikos Skalkotos
Browse files

Add "windows-legacy" OSFAMILY

Add a new OSFAMILY for Windows OSes prior to Windows Vista that use the
old Windows NT sysprep format. For now, this is only tested in Windows
Server 2003 and Windows XP
parent dd46edc6
......@@ -138,8 +138,8 @@ if ! check_yes_no SNF_IMAGE_PROPERTY_EXCLUDE_ALL_TASKS; then
log_error "Required image property \`ROOT_PARTITION' is missing or empty."
fi
if [[ ! "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^(linux|windows|freebsd|openbsd|netbsd)$ ]]; then
log_error "Supported values for OSFAMILY property are: linux|windows|freebsd|openbsd|netbsd"
if [[ ! "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^(linux|windows|windows-legacy|freebsd|openbsd|netbsd)$ ]]; then
log_error "Supported values for OSFAMILY property are: linux|windows|windows-legacy|freebsd|openbsd|netbsd"
fi
SNF_IMAGE_RESIZE_PART="$(get_partition_to_resize "$SNF_IMAGE_DEV")"
......
......@@ -85,8 +85,10 @@ if [[ "$ptype" == ext[234] ]]; then
elif [[ "$ptype" == "freebsd-ufs" ]]; then
$GROWFS_UFS -y "$device"
elif [[ "$ptype" == "ntfs" ]]; then
# For NTFS, only perform an offline resize if forced
if check_yes_no SNF_IMAGE_PROPERTY_OFFLINE_NTFSRESIZE; then
# For NTFS on newer Windows, only perform an offline resize if forced. On
# Windows XP where online resize is not supported, do this by default.
if (check_yes_no SNF_IMAGE_PROPERTY_OFFLINE_NTFSRESIZE || \
[ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "windows" ]); then
# Be extra safe: Refuse to work on Image with a dirty NTFS
if ! $NTFSINFO -m "$device"; then
log_error "NTFS is dirty, refusing to continue"
......
......@@ -41,6 +41,7 @@ if [ -z "$SNF_IMAGE_PROPERTY_ROOT_PARTITION" ]; then
fi
rootdev="${SNF_IMAGE_DEV}${SNF_IMAGE_PROPERTY_ROOT_PARTITION}"
fs="$($BLKID -s TYPE -o value "$rootdev")" || true
if [ ! -b "$rootdev" ]; then
log_error "Root partition device:\`$rootdev' is not a block device." \
......@@ -63,7 +64,7 @@ if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" == *bsd ]]; then
# See mount_all() for a reason why we do this
$MOUNT -o remount,rw "$SNF_IMAGE_TARGET"
elif [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
elif [ "$fs" = ntfs ]; then
# Special case for Windows:
# Perform a case-insensitive, all-lowercase mount with 'lowntfs-3g'
# to avoid problems with different case between installations,
......@@ -92,7 +93,7 @@ else
$MOUNT -o rw "$rootdev" "$SNF_IMAGE_TARGET"
fi
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
exit 0
fi
......
......@@ -41,7 +41,7 @@ fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
exit 0
fi
......
......@@ -40,7 +40,7 @@ fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "windows" ]; then
if [[ ! "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
exit 0
fi
......@@ -50,34 +50,36 @@ fi
target=$SNF_IMAGE_TARGET
mkdir -p "$target/Windows/Setup/Scripts"
touch "$target/Windows/Setup/Scripts/SetupComplete.cmd"
unattend=$(get_unattend "$target")
if [ -n "$unattend" -a ! check_yes_no SNF_IMAGE_PROPERTY_IGNORE_UNATTEND ]; then
warn "Using the Unattend.xml file found in the image"
else
rm -f "$unattend"
if [ -n "$SNF_IMAGE_UNATTEND" ]; then
echo "Installing custom Unattend.xml file..."
if [ -f "$SNF_IMAGE_UNATTEND" ]; then
cat "$SNF_IMAGE_UNATTEND" > "$target/Unattend.xml"
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = windows ]; then
unattend=$(get_unattend "$target")
if test -n "$unattend" && ! check_yes_no SNF_IMAGE_PROPERTY_IGNORE_UNATTEND; then
warn "Using the Unattend.xml file found in the image"
else
rm -f "$unattend"
if [ -n "$SNF_IMAGE_UNATTEND" ]; then
echo "Installing custom Unattend.xml file..."
if [ -f "$SNF_IMAGE_UNATTEND" ]; then
cat "$SNF_IMAGE_UNATTEND" > "$target/Unattend.xml"
else
log_error "Custom unattend file: \`"$SNF_IMAGE_UNATTEND"' is missing"
fi
else
log_error "Custom unattend file: \`"$SNF_IMAGE_UNATTEND"' is missing"
cat "@commondir@/unattend.xml" > "$target/Unattend.xml"
fi
else
cat "@commondir@/unattend.xml" > "$target/Unattend.xml"
fi
fi
# FIXME: There is no guarantee the answer file is actually named
# C:\unattend.xml. These may have to be modified to use the actual
# name of the answer file, as returned by get_unattend().
# FIXME: There is no guarantee the answer file is actually named
# C:\unattend.xml. These may have to be modified to use the actual
# name of the answer file, as returned by get_unattend().
echo "del /Q /F C:\unattend.xml" > \
"$target/Windows/Setup/Scripts/SetupComplete.cmd"
echo "del /Q /F C:\unattend.xml" >> \
"$target/Windows/Setup/Scripts/SetupComplete.cmd"
echo "del /Q /F C:\windows\panther\unattend.xml" >> \
"$target/Windows/Setup/Scripts/SetupComplete.cmd"
echo "del /Q /F C:\windows\panther\unattend.xml" >> \
"$target/Windows/Setup/Scripts/SetupComplete.cmd"
fi
mkdir -p "$target/Windows/SnfScripts"
......@@ -96,42 +98,44 @@ echo "del /Q /F C:\Windows\SnfScripts\ChangeAdminPassword.cmd" >> \
echo "rmdir C:\Windows\SnfScripts" >> \
"$target/Windows/Setup/Scripts/SetupComplete.cmd"
# If using an old-style (XP / Server 2003) SYSPREP.INF answer file,
# ensure C:\SnfScripts\SetupComplete.cmd is executed via CmdLines.txt
# which must be installed in the InstalledfilesPath from SYSPREP.INF.
sysprepinf=$(get_sysprepinf "$target")
if [ -n "$sysprepinf" ]; then
h=@scriptsdir@/handle-ini-file.py
installfilespath=$($h "$sysprepinf" get Unattended InstallFilesPath)
if [ -z "$installfilespath" ]; then
# Set InstallFilesPath to C:\SYSPREP\i386 explicitly, if missing
$h "$sysprepinf" set Unattended InstallFilesPath 'C:\SYSPREP\i386'
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows-legacy" ]; then
# If using an old-style (XP / Server 2003) SYSPREP.INF answer file,
# ensure C:\SnfScripts\SetupComplete.cmd is executed via CmdLines.txt
# which must be installed in the InstalledfilesPath from SYSPREP.INF.
sysprepinf=$(get_sysprepinf "$target")
if [ -n "$sysprepinf" ]; then
h=@scriptsdir@/handle-ini-file.py
installfilespath=$($h "$sysprepinf" get Unattended InstallFilesPath)
fi
if [ -z "$installfilespath" ]; then
log_error "Failed to get value of InstallFilesPath in SYSPREP.INF"
fi
installfilespath=$(tr [A-Z] [a-z] <<< "$installfilespath")
if [ -z "$installfilespath" ]; then
# Set InstallFilesPath to C:\SYSPREP\i386 explicitly, if missing
$h "$sysprepinf" set Unattended InstallFilesPath 'C:\SYSPREP\i386'
installfilespath=$($h "$sysprepinf" get Unattended InstallFilesPath)
fi
if [ -z "$installfilespath" ]; then
log_error "Failed to get value of InstallFilesPath in SYSPREP.INF"
fi
installfilespath=${installfilespath,,}
if [[ ! "$installfilespath" == 'c:\sysprep\'* ]]; then
log_error "InstallFilesPath from SYSPREP.INF not under C:\\SYSPREP\\"
fi
installfilespath=${installfilespath#'c:\sysprep\'}
installfilespath=$(echo "$installfilespath"|sed 's/\\/\//g')
if [[ ! "$installfilespath" == 'c:\sysprep\'* ]]; then
log_error "InstallFilesPath from SYSPREP.INF not under C:\\SYSPREP\\"
fi
installfilespath=${installfilespath#c:\\sysprep\\}
installfilespath=${installfilespath//\\//}
# Ensure final location for InstallFilesPath is still under $target
oemdir="$target"/sysprep/"$installfilespath"/'$OEM$'
if ! readlink -f "$oemdir"|grep -q "^$target"; then
log_error "Invalid value for InstallFilesPath in SYSPREP.INF"
fi
# Ensure final location for InstallFilesPath is still under $target
oemdir="$target/sysprep/$installfilespath"/'$OEM$'
if ! readlink -f "$oemdir"|grep -q "^$target"; then
log_error "Invalid value for InstallFilesPath in SYSPREP.INF"
fi
mkdir -p "$oemdir"
cmdlinestxt="$oemdir"/CmdLines.txt
if [ ! -f "$cmdlinestxt" ]; then
echo "[Commands]" >"$cmdlinestxt"
mkdir -p "$oemdir"
cmdlinestxt="$oemdir/CmdLines.txt"
if [ ! -f "$cmdlinestxt" ]; then
echo "[Commands]" >"$cmdlinestxt"
fi
echo '"C:\Windows\SnfScripts\ChangeAdminPassword.cmd"' >>"$cmdlinestxt"
echo '"C:\Windows\Setup\Scripts\SetupComplete.cmd"' >>"$cmdlinestxt"
fi
echo "\"C:\\Windows\\SnfScripts\\ChangeAdminPassword.cmd\"" >>"$cmdlinestxt"
echo "\"C:\\Windows\\Setup\\Scripts\\SetupComplete.cmd\"" >>"$cmdlinestxt"
fi
exit 0
......
......@@ -41,6 +41,25 @@ fi
# Check if the image overwrites the task
check_if_overwritten
windows-legacy_hostname() {
local target hostname sysprepinf
target="$1"
hostname="$2"
check_windows_computer_name "$hostname"
sysprepinf=$(get_sysprepinf "$target")
if [ -z "$sysprepinf" ]; then
log_error 'No C:\SYSPREP\SYSPREP.INF found in the instance.'
fi
echo -n "Assigning new computer name..."
@scriptsdir@/handle-ini-file.py "$sysprepinf" set UserData ComputerName "$hostname"
echo done
}
windows_hostname() {
local target hostname unattend tmp_unattend namespace
target="$1"
......@@ -55,28 +74,13 @@ windows_hostname() {
namespace="urn:schemas-microsoft-com:unattend"
# Windows XP / Server 2003:
# Set the hostname inside a SYSPREP.INF answer file, if found
sysprepinf=$(get_sysprepinf "$target")
# Windows Vista / Server 2008 and later:
# Use Unattend.xml or similar
unattend=$(get_unattend "$target")
if [ -z "$sysprepinf" -a -z "$unattend" ]; then
log_error "No C:\SYSPREP\SYSPREP.INF or Unattend.xml found in Image."
fi
if [ -n "$sysprepinf" ]; then
@scriptsdir@/handle-ini-file.py \
"$sysprepinf" set UserData ComputerName "$hostname"
if [ -z "$unattend" ]; then
log_error "No Unattend.xml found in the instance."
fi
if [ -n "$unattend" ]; then
"$XMLSTARLET" ed -N x=$namespace -u "/x:unattend/x:settings/x:component/x:ComputerName" -v "$hostname" "$unattend" > "$tmp_unattend"
cat "$tmp_unattend" > "$unattend"
fi
"$XMLSTARLET" ed -N x=$namespace -u "/x:unattend/x:settings/x:component/x:ComputerName" -v "$hostname" "$unattend" > "$tmp_unattend"
cat "$tmp_unattend" > "$unattend"
echo done
}
......
......@@ -169,10 +169,11 @@ fi
#trim users var
SNF_IMAGE_PROPERTY_USERS=$(echo $SNF_IMAGE_PROPERTY_USERS)
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
if [ -n "${SNF_IMAGE_PASSWD_HASH+dummy}" ]; then
log_error "On Windows images password hash is not applicable."
fi
windows_password "$SNF_IMAGE_TARGET" "$SNF_IMAGE_PASSWD"
else
if [ -n "${SNF_IMAGE_PASSWD_HASH+dummy}" ]; then
......
......@@ -52,7 +52,7 @@ fi
# Check if the image overwrites the task
check_if_overwritten
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" != "windows" ]; then
if [[ ! "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
exit 0
fi
......
......@@ -61,14 +61,6 @@ if [ "$ptype" = "ntfs" -a "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
warn "Task ${PROGNAME:2} will not run. Offline NTFS resize requested."
exit 0
fi
# Windows XP / Server 2003
# No online resize is supported, emit a warning
sysprepinf=$(get_sysprepinf "$target")
if [ -n "$sysprepinf" ]; then
warn "Found SYSPREP.INF. Cannot perform online resize on XP / Server 2003."
warn "Set the OFFLINE_NTFSRESIZE property to yes to request an offline resize."
fi
# Write a diskpart script to %SystemDrive%\Windows\SnfScripts. Sysprep will
# try to execute this script during the specialize pass.
cat > "$SNF_IMAGE_TARGET/Windows/SnfScripts/ExtendFilesystem" <<EOF
......
......@@ -50,7 +50,7 @@ if [ -z "$SNF_IMAGE_PERSONALITY" ]; then
exit 0
fi
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
echo "$SNF_IMAGE_PERSONALITY" |
@scriptsdir@/inject-files.py "$SNF_IMAGE_TARGET"
exit 0
......
......@@ -39,7 +39,7 @@ fi
umount_all "$SNF_IMAGE_TARGET"
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows" ]; then
if [[ "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
# Ensure any NTFS-3G processes are gone after umounting NTFS.
# Otherwise, we run the risk of continuing while data may still be
# written to the underlying block device.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment