Привет, народ! У меня получилось настроить cloud init для Windows с небольшими изменениями в Proxmox и шаблоне Windows. Раз все остальные обсуждения на эту тему не работают (по крайней мере, у меня не получилось их завести), решил поделиться своим опытом. Ключевой момент — это настройка Proxmox для сохранения паролей Windows в открытом виде, иначе шаблон не сможет их прочитать.
Я отредактировал файл `/usr/share/perl5/PVE/API2/Qemu.pm` (старый код, строка 1022):
Perl: `if (defined(my $cipassword = $param->{cipassword})) { ... }` заменяется на:
Perl: `my $conf = PVE::QemuConfig->load_config($vmid);
my $ostype = $conf->{ostype};
if (defined(my $cipassword = $param->{cipassword})) {
# Same logic as in cloud-init (but with the regex fixed...)
if (!(PVE::QemuServer::windows_version($ostype))) {
$param->{cipassword} = PVE::Tools::encrypt_pw($cipassword)
if $cipassword !~ /^\$(?:[156]|2[ay])(\$.+){2}/;
}
}
Затем, изменил код для передачи метаданных в ВМ (строка 210 в `/usr/share/perl5/PVE/QemuServer/Cloudinit.pm`), заменив функцию `configdrive2_metadata` на:
Perl: `sub configdrive2_metadata { ... }`
Этот код передаёт имя хоста и SSH-ключи, а также добавляет пароль.
В функции `generate_configdrive2` (ниже), изменил:
Perl: `if (!defined($meta_data)) { ... }` на `if (!defined($meta_data)) { ... }`
Это связано с тем, что теперь функции требуются дополнительные аргументы.
Еще один момент — небольшая опечатка в Proxmox для DNS-серверов и домена поиска (домен поиска пока не работает, вернусь к этому позже). Измените `_` на `-` в файле `/usr/share/perl5/PVE/QemuServer/Cloudinit.pm`, например:
Perl: `if ($nameservers && @$nameservers) { ... }` и `if ($searchdomains && @$searchdomains) { ... }`
После этого можно начинать создание шаблона Windows. Скачайте ISO-образ Windows Server, установите, установите Qemu Guest Agent и VirtIO Tools (обычные действия). Можно сразу сделать снимок (snapshot), чтобы иметь чистую копию.
Установите Cloudbase-Init. Убедитесь, что у ВМ есть последовательный порт (serial port) и вы выбрали COM1 при установке для логирования. Используйте Administrator в качестве имени пользователя при установке. Не запускайте Sysprep и не перезагружайтесь после установки. Снова сделайте снимок (snapshot), если хотите.
Теперь нужно немного поправить код Cloudbase. Сначала настройте автоматическое извлечение диска cloud init после завершения работы Cloudbase, чтобы пользователи не могли его видеть (дополнительная безопасность, особенно учитывая, что пароль сейчас в открытом виде). Подробности здесь: [ >)
Теперь можно редактировать конфигурацию Cloudbase в `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf`. Ознакомьтесь с документацией, чтобы понять, что можно настроить. Вам понадобится служба метаданных configdrive, а также inject_user_password=no, чтобы можно было войти в систему через RDP без изменения пароля через VNC. Включите необходимые плагины. Вот пример моей конфигурации:
Code:
[DEFAULT]
username=Administrator
groups=Administrators
inject_user_password=no
config_drive_raw_hhd=true
config_drive_cdrom=true
config_drive_vfat=true
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
verbose=true
debug=true
logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
logfile=cloudbase-init.log
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
logging_serial_port_settings=COM1,115200,N,8
mtu_use_dhcp_config=false
ntp_use_dhcp_config=false
metadata_services=cloudbaseinit.metadata.services.configdrive.ConfigDriveService
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
check_latest_version=true
plugins=cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin,cloudbaseinit.plugins.common.mtu.MTUPlugin,cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin,cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin,cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin
После этого убедитесь, что файл Unattend.xml соответствует обычному файлу конфигурации.
Запустите Sysprep с командами:
Code:
cd C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf
C:\Windows\System32\sysprep\sysprep.exe /generalize /oobe /unattend:Unattend.xml
Затем преобразуйте в шаблон и протестируйте. Откройте последовательную консоль, чтобы просмотреть логи, если что-то пойдет не так. Сообщите мне об ошибках, если что-то не работает, и я постараюсь помочь.
Я отредактировал файл `/usr/share/perl5/PVE/API2/Qemu.pm` (старый код, строка 1022):
Perl: `if (defined(my $cipassword = $param->{cipassword})) { ... }` заменяется на:
Perl: `my $conf = PVE::QemuConfig->load_config($vmid);
my $ostype = $conf->{ostype};
if (defined(my $cipassword = $param->{cipassword})) {
# Same logic as in cloud-init (but with the regex fixed...)
if (!(PVE::QemuServer::windows_version($ostype))) {
$param->{cipassword} = PVE::Tools::encrypt_pw($cipassword)
if $cipassword !~ /^\$(?:[156]|2[ay])(\$.+){2}/;
}
}
Затем, изменил код для передачи метаданных в ВМ (строка 210 в `/usr/share/perl5/PVE/QemuServer/Cloudinit.pm`), заменив функцию `configdrive2_metadata` на:
Perl: `sub configdrive2_metadata { ... }`
Этот код передаёт имя хоста и SSH-ключи, а также добавляет пароль.
В функции `generate_configdrive2` (ниже), изменил:
Perl: `if (!defined($meta_data)) { ... }` на `if (!defined($meta_data)) { ... }`
Это связано с тем, что теперь функции требуются дополнительные аргументы.
Еще один момент — небольшая опечатка в Proxmox для DNS-серверов и домена поиска (домен поиска пока не работает, вернусь к этому позже). Измените `_` на `-` в файле `/usr/share/perl5/PVE/QemuServer/Cloudinit.pm`, например:
Perl: `if ($nameservers && @$nameservers) { ... }` и `if ($searchdomains && @$searchdomains) { ... }`
После этого можно начинать создание шаблона Windows. Скачайте ISO-образ Windows Server, установите, установите Qemu Guest Agent и VirtIO Tools (обычные действия). Можно сразу сделать снимок (snapshot), чтобы иметь чистую копию.
Установите Cloudbase-Init. Убедитесь, что у ВМ есть последовательный порт (serial port) и вы выбрали COM1 при установке для логирования. Используйте Administrator в качестве имени пользователя при установке. Не запускайте Sysprep и не перезагружайтесь после установки. Снова сделайте снимок (snapshot), если хотите.
Теперь нужно немного поправить код Cloudbase. Сначала настройте автоматическое извлечение диска cloud init после завершения работы Cloudbase, чтобы пользователи не могли его видеть (дополнительная безопасность, особенно учитывая, что пароль сейчас в открытом виде). Подробности здесь: [ >)
Теперь можно редактировать конфигурацию Cloudbase в `C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf`. Ознакомьтесь с документацией, чтобы понять, что можно настроить. Вам понадобится служба метаданных configdrive, а также inject_user_password=no, чтобы можно было войти в систему через RDP без изменения пароля через VNC. Включите необходимые плагины. Вот пример моей конфигурации:
Code:
[DEFAULT]
username=Administrator
groups=Administrators
inject_user_password=no
config_drive_raw_hhd=true
config_drive_cdrom=true
config_drive_vfat=true
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
verbose=true
debug=true
logdir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
logfile=cloudbase-init.log
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
logging_serial_port_settings=COM1,115200,N,8
mtu_use_dhcp_config=false
ntp_use_dhcp_config=false
metadata_services=cloudbaseinit.metadata.services.configdrive.ConfigDriveService
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
check_latest_version=true
plugins=cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin,cloudbaseinit.plugins.common.mtu.MTUPlugin,cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin,cloudbaseinit.plugins.common.sshpublickeys.SetUserSSHPublicKeysPlugin,cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin
После этого убедитесь, что файл Unattend.xml соответствует обычному файлу конфигурации.
Запустите Sysprep с командами:
Code:
cd C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf
C:\Windows\System32\sysprep\sysprep.exe /generalize /oobe /unattend:Unattend.xml
Затем преобразуйте в шаблон и протестируйте. Откройте последовательную консоль, чтобы просмотреть логи, если что-то пойдет не так. Сообщите мне об ошибках, если что-то не работает, и я постараюсь помочь.
