Как стать автором
Обновить
57.09
HOSTKEY
IT-инфраструктура: сервера, VPS, GPU, коло

Развертывание Windows UEFI с использованием Foreman

Время на прочтение5 мин
Количество просмотров2.8K

Автор: DevOps Team Leader компании Hostkey Егор Гараджа

В прошлой статье мы рассказали, как нам удалось решить проблему установки Windows и Linux через Foreman в Legacy-режиме (BIOS/MBR). Другой важной задачей стала поддержка инсталляций в режиме EFI. В случае Foreman этот вопрос решается через использование отдельного загрузчика. Для Linux наш выбор пал на Grub2, и реализация загрузки оказалась достаточно тривиальной — нами была создана конфигурация Grub для загрузки initrd и ядра.

В случае с Windows ситуация сложнее. Изначально загрузка Windows осуществлялась через расширение для iPXE. Проблема, однако, в том, что это расширение, как и многие другие (memdisk и т. п.), не поддерживалось официально для EFI-версии загрузчика. Кнечно, можно попытаться решить этот вопрос самостоятельными правками и сборкой нужных модулей, но мы в целом хотели уйти от iPXE, поскольку это не совсем честный pxe-загрузчик, а скорее мини-операционная система со своими драйверами для сетевых карт, что изредка создавало проблемы при инсталляциях.

Мы сделали попытку использовать модуль Grub2, позволяющий смонтировать по http образ диска и загрузиться с него. Этот вариант не сработал, так как производительность модуля при работе по сети оказалась очень низкой, не говоря уже о стабильности.

В результате изучения вопроса мы пришли к следующим вариантам решения проблемы:

  • Создание процедуры инсталляции, в которой на первом шаге используется Linux, а дальнейшая инсталляция происходит с использованием WindowsPE, без изменений относительно механизма Legacy-установки через iPXE.

  • Встраивание поддержки загрузчика Microsoft в Foreman (потребуется модификация файла /usr/share/foreman/app/models/concerns/pxe_loader_support.rb из поставки Foreman для добавления загрузчика в его меню).

  • Создание инсталляции из шаблонов (аналогично Fog Project) с использованием Microsoft sysprep целиком из Linux, без родного инсталлятора.

Мы попробовали разные варианты, но в этой статье мы хотим рассказать о первом, поскольку сейчас он является основным в нашей инфраструктуре и хорошо испытан. Главный плюс этого подхода — это расширение к существующей процедуре установки ,а потому  не требует поддерживать различную конфигурацию для режимов EFI и Legacy. Главной проблемой стала архитектурная избыточность — не вся ОС ставится через Linux LiveCD, а лишь WindowsPE, что приводит к лишним шагам и потенциальным точкам отказа.

Установка будет проходить через следующие этапы:

  1. Штатная загрузка Linux LiveCD через PXE Grub2.

  2. Скрипт установки Linux должен:

    • произвести разбивку диска для EFI и WindowsPE;

    • загрузить WindowsPE и организовать его EFI-загрузку с диска;

    • загрузить все необходимые скрипты и шаблоны с Foreman для установки Windows;

    • сообщить Foreman о завершении установки, в результате чего следующая загрузка произойдет с диска, то есть загрузится WindowsPE.

  3. Далее установка должна пройти штатно — аналогично legacy-режиму, где сразу грузится WindowsPE.

Штатная загрузка Linux LiveCD через PXE Grub2

<%#
kind: PXEGrub2
name: HK_Windows_PXEGrub2
model: ProvisioningTemplate
oses:
- Windows
%>
set default=0
set timeout=<%= host_param('loader_timeout') || 10 %>
 menuentry '<%= template_name %>' {
  linuxefi (http,<%= host_param('medium_fqdn') %>)/live-master/vmlinuz rootfstype=auto ro rd.neednet=1 rd.live.image rd.luks=0 rd.md=0 rd.dm=0 root=live:<%= host_param('livesystem_url') %>/<%= host_param('live_squash') %> systemd.setenv=BRANCH=<%= host_param('medium_branch') %> systemd.setenv=SPEEDISO=peinstall systemd.setenv=PEMIRROR="<%= medium_uri %>" systemd.setenv=FOREMAN_TOKEN="<%= @host.token %>" systemd.setenv=FOREMAN_FQDN=<%= foreman_server_fqdn %> ipv6.disable=1 noeject
  initrdefi (http,<%= host_param('medium_fqdn') %>)/live-master/initrd
}

Темплейт Grub2 загружает штатный LiveCD, сборку которого мы описывали в предыдущей статье. Параметры systemd.setenv позволяют пробросить в загруженную систему ряд переменных окружений, благодаря чему можно запустить конкретный скрипт для последующей инсталляции и задать ему параметры для получения с Foreman шаблонов.

Скрипт установки Linux

В systemd LiveCD добавляется сервис, который стартует только в том случае, если SPEEDISO=peinstall. Подробнее мы рассказывали об этом в одной из прошлых статей.

Стартовый скрипт выполняет основную магию: выбирает INST_DRIVE среди имеющихся в системе по указанной администратором логике, а затем производит следующие операции:

# Создает, с помощью parted, раздел ESP размером 1 гигабайт в начале диска:

parted -s /dev/${INST_DRIVE} mklabel gpt mkpart fat32 1MiB 1GiB set 1 esp on
EFI_PART=$(lsblk -l | grep "${INST_DRIVE}" | grep part | awk '{print $1}')
mkfs.fat -F32 /dev/$EFI_PART

# Подготавливает директории для монтирования файловых систем:

mkdir -p /mnt/{iso,efipart,wim}

# Загружает WindowsPE ISO с зеркала с помощью wget и монтирует его (вместо загрузки можно воспользоваться функционалом Fuse и сразу приступить к монтированию):

wget ${medium_uri}/${branch}/windowspe.iso
mount -o loop windowspe.iso /mnt/iso

# Подключает EFI-партицию и отправляет туда содержимое WindowsPE ISO, а также EFI-загрузчик Microsoft (мы держим его прямо на LiveCD, но можно закидывать через сеть. Он лежит в директории EFI любого инсталляционного диска Windows).

mount /dev/$EFI_PART /mnt/efipart
rsync -r /mnt/iso/ /mnt/efipart/
rsync -r /root/EFI /mnt/efipart/

# Немного исправляет пути для стандартного шаблона Grub2 с Foreman, обеспечивающего chain-load:

cp /mnt/efipart/EFI/Boot/bootx64.efi /mnt/efipart/EFI/Microsoft/Boot/bootmgfw.efi
umount /mnt/iso

# Забирает скрипты инсталляции Windows с Foreman:

curl -s "http://${foreman_fqdn}/unattended/script?token=${foreman_token}" >> /foreman.ps1
curl -s "http://${foreman_fqdn}/unattended/provision?token=${foreman_token}" >> /unattend.xml

# Добавляет скрипты в bootwim с помощью утилиты из комплекта wim-tools:

echo "add /foreman.ps1 /scripts/foreman.ps1" >> /wimupdate.txt
echo "add /unattend.xml /unattend.xml" >> /wimupdate.txt
wimupdate /mnt/efipart/sources/boot.wim < /wimupdate.txt
umount /mnt/efipart

# Сообщает Foreman, что установка завершена, это позволит осуществить следующую загрузку с диска:

wget "http://${foreman_fqdn}/unattended/built?token=${foreman_token}"
sync && reboot

Дальнейшая установка

После выполнения этих процедур произойдет загрузка с WindowsPE с помощью штатного BCD Microsoft, расположенного на EFI-партиции. Дальнейшая процедура идентична установке с использованием прямой загрузки в WindowsPE — с той лишь разницей, что все необходимые скрипты установки загружены с Foreman, поэтому часть процедуры уже не нужна. Можно включить в startpe.cmd скрипт проверку на наличие этих файлов и перейти к исполнению основного скрипта инсталляции foreman.ps1 сразу, если он есть в системе.

Разбивка диска также чуть усложняется для поддержки EFI. Вот вариант partition_table для Foreman (часть erb-шаблона, с конструкцией выбора efi/legacy):

<% if host_param_true?('uefi') -%>
@"
clean
convert gpt
create partition msr size=16
create partition efi size=500
create partition primary
shrink minimum=500
format quick fs=ntfs label="Windows"
assign letter="C"
create partition primary
format quick fs=ntfs label="Recovery"
assign letter="R"
set id="de94bba4-06d1-4d40-a16a-bfd50179d6ac"
gpt attributes=0x8000000000000001
list volume
exit
"@ | Tee-Object -FilePath "$SysDrive\dp.txt" -Append
<% else -%>
@"
clean
convert mbr
create partition primary size=500
select partition 1
active
format quick fs=ntfs
create partition primary
select partition 2
format quick fs=ntfs label='vg<%= @host.shortname %>'
assign letter='C'
exit
"@ | Tee-Object -FilePath "$SysDrive\dp.txt" -Append
<% end -%>
 
echo "Execute Diskpart..."
& diskpart /s $SysDrive\dp.txt

Поскольку WindowsPE уже загружен в память (речь конкретно о Boot.wim, в который мы добавляли установочные скрипты на этапе Linux), то диск можно полностью зачистить и создать чистую установку в соответствии с рекомендациями Microsoft по разбивке дисков для EFI-инсталляций.

Дальнейшие шаги необходимо описать в foreman.ps1 — это PowerShell-скрипт, который произведет загрузку необходимых драйверов, образа wim (вместе с утилитой setup.exe) со штатного инсталляционного DVD Microsoft и запустит setup.exe с использованием файла ответов unattend.xml.

Результат: установленная ОС Microsoft в режиме EFI с помощью сервиса Foreman и без использования инфраструктуры Microsoft.

Теги:
Хабы:
0
Комментарии2

Публикации

Информация

Сайт
www.hostkey.ru
Дата регистрации
Дата основания
Численность
31–50 человек
Местоположение
Россия