35InstallUnattend.in 7.3 KB
Newer Older
1
#! /bin/bash
Nikos Skalkotos's avatar
Nikos Skalkotos committed
2

3
# Copyright (C) 2011, 2015 GRNET S.A. and individual contributors
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

Nikos Skalkotos's avatar
Nikos Skalkotos committed
20
21
### BEGIN TASK INFO
# Provides:		InstallUnattend
22
# RunBefore:		EnforcePersonality
Nikos Skalkotos's avatar
Nikos Skalkotos committed
23
# RunAfter:		MountImage
24
# Short-Description:	Installs Unattend.xml for unattended Windows setup
25
### END TASK INFO
Nikos Skalkotos's avatar
Nikos Skalkotos committed
26
27

set -e
28
. "@commondir@/common.sh"
Nikos Skalkotos's avatar
Nikos Skalkotos committed
29

30
trap task_cleanup EXIT
31
report_task_start
32

33
34
35
# Check if the task should be prevented from running.
check_if_mounted_excluded

Nikos Skalkotos's avatar
Nikos Skalkotos committed
36
if [ -z "$SNF_IMAGE_TARGET" ]; then
37
    log_error "Target dir: \`$SNF_IMAGE_TARGET' is missing"
Nikos Skalkotos's avatar
Nikos Skalkotos committed
38
39
fi

40
41
42
# Check if the image overwrites the task
check_if_overwritten

43
if [[ ! "$SNF_IMAGE_PROPERTY_OSFAMILY" =~ ^windows ]]; then
44
    exit 0
Nikos Skalkotos's avatar
Nikos Skalkotos committed
45
46
fi

Nikos Skalkotos's avatar
Nikos Skalkotos committed
47
if [ ! -f "@commondir@/unattend.xml" ]; then
48
    log_error "File \`@commondir@/unattend.xml' is missing."
Nikos Skalkotos's avatar
Nikos Skalkotos committed
49
50
fi

Nikos Skalkotos's avatar
Nikos Skalkotos committed
51
target=$SNF_IMAGE_TARGET
52
53
54
55
56
arch=$(get_windows_architecture "$target")
if [ -z "$arch" ]; then
    log_error "Unable to determine windows architecture"
fi

Nikos Skalkotos's avatar
Nikos Skalkotos committed
57
mkdir -p "$target/Windows/Setup/Scripts"
58
touch "$target/Windows/Setup/Scripts/SetupComplete.cmd"
Nikos Skalkotos's avatar
Nikos Skalkotos committed
59

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
mkdir -p "$target/Windows/SnfScripts"

echo "exit" > "$target/Windows/SnfScripts/ExtendFilesystem"
echo "del /Q /F C:\Windows\SnfScripts\ExtendFilesystem" >> \
        "$target/Windows/Setup/Scripts/SetupComplete.cmd"

echo "@echo off" > "$target/Windows/SnfScripts/ChangeAdminPassword.cmd"
# For security reasons, overwrite the file before deleting...
spaces=$(printf "%200s");
echo "echo ${spaces// /X} > C:\Windows\SnfScripts\ChangeAdminPassword.cmd" >> \
        "$target/Windows/Setup/Scripts/SetupComplete.cmd"
echo "del /Q /F C:\Windows\SnfScripts\ChangeAdminPassword.cmd" >> \
        "$target/Windows/Setup/Scripts/SetupComplete.cmd"

echo "rmdir C:\Windows\SnfScripts" >> \
        "$target/Windows/Setup/Scripts/SetupComplete.cmd"

77
read nt_version_major nt_version_minor <<<$(get_windows_nt_version "$target")
78

79
if [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = windows ]; then
80
81
82
83
    if [ $nt_version_major -lt 6 ]; then
        log_error "Windows image seems older than Vista. Use 'windows-legacy' as OSFAMILY"
    fi

84
85
86
87
88
89
90
91
92
93
94
95
    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
96
        else
97
            cat "@commondir@/unattend.xml" > "$target/Unattend.xml"
98
        fi
99
        unattend="$target/Unattend.xml"
100
101
    fi

102
103
104
    # 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().
105

106
    echo 'del /Q /F C:\unattend.xml' >> \
107
            "$target/Windows/Setup/Scripts/SetupComplete.cmd"
108

109
    echo 'del /Q /F C:\windows\panther\unattend.xml' >> \
110
            "$target/Windows/Setup/Scripts/SetupComplete.cmd"
Nikos Skalkotos's avatar
Nikos Skalkotos committed
111

112
113
114
115
116
117
118
119
120
121
122
123
124
    # Check if ChangeAdminPassword.cmd and ExtendFilesystem are executed by
    # this unattend.xml file. If this is not the case, then add the proper
    # entries
    xpath='/_:unattend/_:settings/_:component[@processorArchitecture="'"$arch"'"]/_:RunSynchronous/_:RunSynchronousCommand'
    commands=$($XMLSTARLET sel -t -v "$xpath/_:Path"  "$unattend") || true
    max_order=$($XMLSTARLET sel -t -v "($xpath/_:Order[not(. < $xpath/_:Order)])[1]" "$unattend") || true
    order=$((max_order+1)) || true
    if ! grep -i ChangeAdminPassword.cmd <<< "$commands" &> /dev/null; then
        windows_add_synchronous_command "$unattend" "$arch" \
            "Change user passwords" \
            "$((order++))" \
            'C:\Windows\SnfScripts\ChangeAdminPassword.cmd'
    fi
Nikos Skalkotos's avatar
Nikos Skalkotos committed
125

126
127
128
129
130
131
    if ! grep -i ExtendFilesystem <<< "$commands" &> /dev/null; then
        windows_add_synchronous_command "$unattend" "$arch" \
            "Extend the file system" \
            "$((order++))" \
            'diskpart.exe /s C:\Windows\SnfScripts\ExtendFilesystem'
    fi
132
133
134
135
136
137
138

    if [ -n "${SNF_IMAGE_OS_PRODUCT_KEY+dummy}" ]; then
        windows_update_unattend_node "$unattend" specialize \
            "Microsoft-Windows-Shell-Setup" "$arch" ProductKey \
            "$SNF_IMAGE_OS_PRODUCT_KEY"
    fi

139
elif [ "$SNF_IMAGE_PROPERTY_OSFAMILY" = "windows-legacy" ]; then
140
141
142
143
    if [ $nt_version_major -ge 6 ]; then
        log_error "Windows image is not legacy. Use 'windows' as OSFAMILY"
    fi

144
145
146
147
148
149
    # 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
150
        installfilespath=$($h "$sysprepinf" get Unattended InstallFilesPath)
151
152
153
154
155
156
157
158
159
        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,,}
160

161
162
163
164
165
        if [[ ! "$installfilespath" == 'c:\sysprep\'* ]]; then
            log_error "InstallFilesPath from SYSPREP.INF not under C:\\SYSPREP\\"
        fi
        installfilespath=${installfilespath#c:\\sysprep\\}
        installfilespath=${installfilespath//\\//}
166

167
168
169
170
171
        # 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
172

173
174
        mkdir -p "$oemdir"
        cmdlinestxt="$oemdir/CmdLines.txt"
175
176
177
178
        touch "$cmdlinestxt"

        if ! egrep '^[[:space:]]*\[Commands\][[:space:]]*$' "$cmdlinestxt" >/dev/null; then
            echo "[Commands]" >> "$cmdlinestxt"
179
        fi
180

181
182
        echo '"C:\Windows\SnfScripts\ChangeAdminPassword.cmd"' >>"$cmdlinestxt"
        echo '"C:\Windows\Setup\Scripts\SetupComplete.cmd"' >>"$cmdlinestxt"
183
184
185
186
187

        #Install a product key if defined
        if [ -n "${SNF_IMAGE_OS_PRODUCT_KEY+dummy}" ]; then
            $h "$sysprepinf" set UserData ProductKey "$SNF_IMAGE_OS_PRODUCT_KEY"
        fi
188
189
190
    fi
fi

Nikos Skalkotos's avatar
Nikos Skalkotos committed
191
exit 0
192
193

# vim: set sta sts=4 shiftwidth=4 sw=4 et ai :