This commit is contained in:
2020-08-17 12:06:41 -04:00
parent 9fa09f26bd
commit 6eb48873e6
455 changed files with 45184 additions and 14 deletions

View File

@@ -0,0 +1,29 @@
---
language: python
python: "2.7"
# Use the new container infrastructure
sudo: false
# Install ansible
addons:
apt:
packages:
- python-pip
install:
# Install ansible
- pip install ansible
# Check ansible version
- ansible --version
# Create ansible.cfg with correct roles_path
- printf '[defaults]\nroles_path=../' >ansible.cfg
script:
# Basic role syntax check
- ansible-playbook tests/test.yml -i tests/inventory --syntax-check
notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Orcun Atakan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,95 @@
# windows_ovirt_template
This repo contains an Ansible role that builds a Windows VM template from an ISO file on Ovirt/RHV.
You can run this role as a part of CI/CD pipeline for building Windows templates on Ovirt/RHV from an ISO file.
> **_Note:_** This role is provided as an example only. Do not use this in production. You can fork/clone and add/remove steps for your environment based on your organization's security and operational requirements.
Requirements
------------
You need to have the following packages installed on your ansible control machine:
- mkisofs
You need to enable qemu_cmdline hook on your RHV/Ovirt environment, this is required to enable attaching multiple iso files. Follow the instructions documented here:
https://www.ovirt.org/develop/developer-guide/vdsm/hook/qemucmdline.html
Before you can use this role, you need to make sure you have Windows install media iso file uploaded to a iso domain on your RHV/Ovirt environment.
Role Variables
--------------
A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
Dependencies
------------
A list of roles that this role utilizes, make sure to call this out in requirements.yml file under roles directory or download manually:
- oatakan.windows_template_build
Example Playbook
----------------
Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
- name: create a ovirt windows template
hosts: all
gather_facts: False
connection: local
become: no
vars:
template_force: yes #overwrite existing template with the same name
export_ovf: no # export the template to export domain upon creation
local_account_password: ''
local_administrator_password: ''
windows_distro_name: 2019_standard # this needs to be one of the standard values see 'os_short_names' var
template_vm_name: win2019_template
template_vm_root_disk_size: 30
template_vm_guest_id: windows_2019x64
template_vm_memory: 4096
template_vm_efi: false # you need to install efi file to use this, false should be fine in most cases
iso_file_name: '' # name of the iso file
iso_image_index: '' # put index number here from the order inside the iso, for example 1 - standard, 2 - core etc
iso_product_key: ''
vm_ansible_port: 5986
vm_ansible_winrm_transport: credssp
vm_upgrade_powershell: false # only needed for 2008 R2
install_updates: false # it will take longer to build with the updates, set to true if you want the updates
ovirt_datacenter: '' # name of the datacenter
ovirt_cluster: '' # name of the cluster
ovirt_data_domain: '' # name of the data domain
ovirt_export_domain: '' # name of the iso domain
ovirt_iso_domain: '' # this is deprecated as of 4.3 you can omit if not used
template_vm_network_name: ovirtmgmt
template_vm_ip_address: 192.168.10.95 # static ip is required
template_vm_netmask: 255.255.255.0
template_vm_gateway: 192.168.10.254
template_vm_domain: example.com
template_vm_dns_servers:
- 8.8.4.4
- 8.8.8.8
roles:
- oatakan.windows_ovirt_template
For disconnected environments, you can overwrite this variable to point to a local copy of a script to enable winrm:
**winrm_enable_script_url:** https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
you can also localize virtio-win and update the virtio_iso_url variable to point to your local url:
**virtio_iso_url:** https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.173-2/virtio-win.iso
License
-------
MIT
Author Information
------------------
Orcun Atakan

View File

@@ -0,0 +1,68 @@
---
instance_wait_retry_limit: 300
instance_wait_connection_timeout: 400
# this will remove existing template with the same name
template_force: no
template_found: no
export_ovf: no
enable_auto_logon: yes
remove_vm_on_error: yes
vm_failed: no
virtio_iso_url: https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.173-2/virtio-win.iso
winrm_enable_script_url: https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1
windows_build_role: oatakan.windows_template_build
local_administrator_password: Chang3MyP@ssw0rd21
local_account_username: ansible
local_account_password: Chang3MyP@ssw0rd21
windows_distro_name: 2019_standard_core
iso_file_name: 17763.253.190108-0006.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us.iso
windows_sysprep_template_folder: windows_server
vm_ansible_port: 5986
vm_ansible_winrm_transport: credssp
vm_upgrade_powershell: no
template_vm_name: windows-2019-standard-core-auto
template_vm_root_disk_size: 30
template_vm_root_disk_format: cow
template_vm_root_disk_interface: virtio
template_vm_memory: 4096
template_vm_cpu: 2
template_vm_guest_id: windows_2019x64
template_vm_efi: no
template_vm_network_name: ovirtmgmt
template_vm_ip_address: 192.168.10.95
template_vm_netmask: 255.255.255.0
template_vm_gateway: 192.168.10.254
template_vm_domain: home.ad
template_vm_dns_servers:
- 192.168.1.254
- 8.8.8.8
template_convert_timeout: 900
template_convert_seal: no
template_timezone: 'GMT Standard Time'
ovirt_datacenter: mydatacenter
ovirt_cluster: production
ovirt_data_domain: data_domain
ovirt_export_domain: export_domain
ovirt_iso_domain: iso_domain
os_short_names:
2008_r2_standard: 2k8R2
2012_r2_standard: 2k12R2
2012_r2_datacenter: 2k12R2
2016_standard: 2k16
2016_standard_core: 2k16
2019_standard: 2k19
2019_standard_core: 2k19

View File

@@ -0,0 +1,2 @@
install_date: Wed Jun 24 18:44:33 2020
version: master

View File

@@ -0,0 +1,28 @@
---
galaxy_info:
author: Orcun Atakan
description: Ansible galaxy role for building a Windows VM templates from an ISO file on Ovirt/RHV.
role_name: windows_ovirt_template
company: Red Hat
license: MIT
min_ansible_version: 2.5
platforms:
- name: Windows
versions:
- all
cloud_platforms:
- oVirt
galaxy_tags:
- windows
- ovirt
- rhv
- cloud
- multicloud
- template
dependencies: []

View File

@@ -0,0 +1,10 @@
---
- name: convert to template
ovirt_template:
auth: "{{ ovirt_auth }}"
name: "{{ template.name }}"
vm: "{{ template.name }}"
cluster: "{{ providers.ovirt.cluster }}"
timeout: "{{ template_convert_timeout }}"
seal: "{{ template_convert_seal }}"
when: template is defined

View File

@@ -0,0 +1,22 @@
---
- block:
- name: remove iso file from data_domain
ovirt_disk:
auth: "{{ ovirt_auth }}"
name: "{{ iso_file }}"
storage_domain: "{{ providers.ovirt.data_domain | default('data_domain') }}"
state: absent
rescue:
- include_tasks: wait_iso_disk_unlock_pre29.yml
when: ansible_version.full is version('2.9', '<')
- include_tasks: wait_iso_disk_unlock.yml
when: ansible_version.full is version('2.9', '>=')
- name: remove iso file from data_domain
ovirt_disk:
auth: "{{ ovirt_auth }}"
name: "{{ iso_file }}"
storage_domain: "{{ providers.ovirt.data_domain | default('data_domain') }}"
state: absent

View File

@@ -0,0 +1,22 @@
---
- name: upload iso file to data_domain
ovirt_disk:
auth: "{{ ovirt_auth }}"
name: "{{ iso_file }}"
upload_image_path: "{{ playbook_dir }}/{{ temp_directory }}/windows_{{ windows_distro_name }}_autounattend_autogen.iso"
storage_domain: "{{ providers.ovirt.data_domain | default('data_domain') }}"
size: 20MiB
wait: true
bootable: true
format: raw
content_type: iso
force: yes
register: disk_iso_file
- name: set iso file disk id
set_fact:
ks_iso_file_disk_id: "{{ disk_iso_file.disk.id }}"
ks_iso_file_image_id: "{{ disk_iso_file.disk.image_id }}"
ovirt_datacenter_id: "{{ disk_iso_file.disk.quota.href | regex_replace('^/ovirt-engine/api/datacenters/(.*)/quotas.*$', '\\1') }}"
ovirt_datastore_id: "{{ disk_iso_file.disk.storage_domains[0].id }}"

View File

@@ -0,0 +1,20 @@
---
- name: export template to export domain
ovirt_template:
auth: "{{ ovirt_auth }}"
state: exported
name: "{{ template.name }}"
export_domain: "{{ providers.ovirt.export_domain }}"
cluster: "{{ providers.ovirt.cluster }}"
async: 7200
poll: 0
register: export_ovf_file
- name: wait for export to complete
async_status:
jid: "{{ export_ovf_file.ansible_job_id }}"
register: ovf
until: ovf.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10

View File

@@ -0,0 +1,119 @@
---
- name: obtain SSO token with using username/password credentials
ovirt_auth:
url: "{{ lookup('env', 'OVIRT_URL')|default(ovirt.url) }}"
username: "{{ lookup('env', 'OVIRT_USERNAME')|default(ovirt.username) }}"
password: "{{ lookup('env', 'OVIRT_PASSWORD')|default(ovirt.password) }}"
insecure: yes
- include_tasks: preflight_check_pre29.yml
when: ansible_version.full is version('2.9', '<')
- include_tasks: preflight_check.yml
when: ansible_version.full is version('2.9', '>=')
# remove existing template
- block:
- include_tasks: remove_template.yml
when:
- template_force|bool
- template_found|bool
- block:
- include_tasks: make_iso.yml
- include_tasks: provision_vm.yml
- name: refresh inventory
meta: refresh_inventory
- name: clear gathered facts
meta: clear_facts
- name: clear any host errors
meta: clear_host_errors
- name: add host
add_host:
hostname: template_host
ansible_host: "{{ template_vm_ip_address }}"
ansible_user: "{{ unattend.local_accounts[0].name }}"
ansible_password: "{{ unattend.local_accounts[0].password }}"
ansible_port: "{{ vm_ansible_port | default('5986') }}"
ansible_connection: winrm
ansible_winrm_transport: "{{ vm_ansible_winrm_transport | default('credssp') }}"
ansible_winrm_server_cert_validation: ignore
ansible_winrm_operation_timeout_sec: 250
ansible_winrm_read_timeout_sec: 280
ansible_win_async_startup_timeout: 60
- include_role:
name: "{{ windows_build_role }}"
apply:
vars:
target_ovirt: yes
install_updates: yes
remove_apps: yes
clean_up_components: yes
upgrade_powershell: "{{ vm_upgrade_powershell | default('no') }}"
delegate_to: template_host
- name: refresh SSO credentials
ovirt_auth:
url: "{{ lookup('env', 'OVIRT_URL')|default(ovirt.url) }}"
username: "{{ lookup('env', 'OVIRT_USERNAME')|default(ovirt.username) }}"
password: "{{ lookup('env', 'OVIRT_PASSWORD')|default(ovirt.password) }}"
insecure: yes
- include_tasks: stop_vm.yml
- include_tasks: convert_to_template.yml
- include_tasks: export_ovf.yml
when: export_ovf|bool
rescue:
- name: refresh SSO credentials
ovirt_auth:
url: "{{ lookup('env', 'OVIRT_URL')|default(ovirt.url) }}"
username: "{{ lookup('env', 'OVIRT_USERNAME')|default(ovirt.username) }}"
password: "{{ lookup('env', 'OVIRT_PASSWORD')|default(ovirt.password) }}"
insecure: yes
- include_tasks: remove_template.yml
when: remove_vm_on_error|bool
- name: set vm_failed variable
set_fact:
vm_failed: yes
always:
- name: refresh SSO credentials
ovirt_auth:
url: "{{ lookup('env', 'OVIRT_URL')|default(ovirt.url) }}"
username: "{{ lookup('env', 'OVIRT_USERNAME')|default(ovirt.username) }}"
password: "{{ lookup('env', 'OVIRT_PASSWORD')|default(ovirt.password) }}"
insecure: yes
- include_tasks: remove_vm.yml
when: remove_vm_on_error|bool or (not remove_vm_on_error|bool and not vm_failed|bool)
- include_tasks: datastore_iso_remove.yml
- name: remove temporary directory
file:
path: "{{ temp_directory }}"
state: absent
- name: logout from oVirt
ovirt_auth:
state: absent
ovirt_auth: "{{ ovirt_auth }}"
- name: fail if needed
fail:
msg: "fail to create a template."
when: vm_failed|bool

View File

@@ -0,0 +1,30 @@
---
- block:
- name: create temporary directory
file:
path: "{{ temp_directory }}/ks_iso"
state: directory
- name: create Autounattend.xml file
template:
src: "{{ windows_sysprep_template_folder }}/Autounattend.xml.j2"
dest: "{{ temp_directory }}/ks_iso/Autounattend.xml"
- name: include virtio drivers
include_tasks: virtio_drivers.yml
- name: create iso
command: mkisofs -V ADDISO -r -iso-level 4 -o {{ playbook_dir }}/{{ temp_directory }}/windows_{{ windows_distro_name }}_autounattend_autogen.iso .
args:
chdir: "{{ playbook_dir }}/{{ temp_directory }}/ks_iso"
- include_tasks: datastore_upload.yml
always:
- name: remove temporary files
file:
path: "{{ temp_directory }}/{{ item }}"
state: absent
loop:
- windows_{{ windows_distro_name }}_autounattend_autogen.iso
- virtio_win.iso
- ks_iso/

View File

@@ -0,0 +1,73 @@
---
- name: get the datacenter name
ovirt_datacenter_info:
auth: "{{ ovirt_auth }}"
pattern: "Clusters.name = {{ providers.ovirt.cluster }}"
register: datacenter_info
- name: get storage information
ovirt_storage_domain_info:
auth: "{{ ovirt_auth }}"
pattern: "datacenter={{ datacenter_info.ovirt_datacenters[0].name }}"
register: storage_info
when:
- template_disk_storage is undefined
- name: get data domain
set_fact:
disk_storage_domain: "{{ storage_info.ovirt_storage_domains|json_query(the_query)|list|first|default(None) }}"
when:
- template_disk_storage is undefined
vars:
the_query: "[?type=='data']"
- name: get iso domain (deprecated as of oVirt/RHV 4.3)
set_fact:
iso_domain: "{{ storage_info.ovirt_storage_domains|json_query(the_query)|list|first|default(None) }}"
vars:
the_query: "[?type=='iso']"
- name: check if template already exists
ovirt_template_info:
auth: "{{ ovirt_auth }}"
pattern: "name={{ template.name }} and datacenter={{ datacenter_info.ovirt_datacenters[0].name }}"
register: template_info
- block:
- name: set template_found to yes
set_fact:
template_found: yes
- name: fail with message
fail:
msg: "Existing template found on ovirt/rhv: {{ template.name }}"
when: not template_force|bool
when:
- template_info.ovirt_templates is defined
- template_info.ovirt_templates | length > 0
- name: check iso file on data domain
ovirt_disk_info:
auth: "{{ ovirt_auth }}"
pattern: "name={{ iso_file_name }}"
register: ovirt_disk_main_iso
when: iso_file_name is defined
- debug:
msg: "{{ ovirt_disk_main_iso }}"
- name: set file id of the iso file
set_fact:
iso_file_id: "{{ ovirt_disk_main_iso.ovirt_disks[0].id }}"
when:
- ovirt_disk_main_iso.ovirt_disks | length > 0
- ovirt_disk_main_iso.ovirt_disks[0].id is defined
- ovirt_disk_main_iso.ovirt_disks[0].content_type == 'iso'
- name: fail with message
fail:
msg: "iso file ({{ iso_file_name }}) could not be found on the data domain and iso domain does not exists"
when:
- iso_file_id is undefined
- iso_domain is undefined or iso_domain|length == 0

View File

@@ -0,0 +1,69 @@
---
- name: get the datacenter name (<2.9)
ovirt_datacenter_facts:
auth: "{{ ovirt_auth }}"
pattern: "Clusters.name = {{ providers.ovirt.cluster }}"
- name: get storage information (<2.9)
ovirt_storage_domain_facts:
auth: "{{ ovirt_auth }}"
pattern: "datacenter={{ ovirt_datacenters[0].name }}"
when:
- template_disk_storage is undefined
- name: get data domain (<2.9)
set_fact:
disk_storage_domain: "{{ ovirt_storage_domains|json_query(the_query)|list|first }}"
when:
- template_disk_storage is undefined
vars:
the_query: "[?type=='data']"
- name: get iso domain (deprecated as of oVirt/RHV 4.3) (<2.9)
set_fact:
iso_domain: "{{ ovirt_storage_domains|json_query(the_query)|list|first }}"
vars:
the_query: "[?type=='iso']"
- name: check if template already exists (<2.9)
ovirt_template_facts:
auth: "{{ ovirt_auth }}"
pattern: "name={{ template.name }} and datacenter={{ ovirt_datacenters[0].name }}"
- block:
- name: set template_found to yes
set_fact:
template_found: yes
- name: fail with message
fail:
msg: "Existing template found on ovirt/rhv: {{ template.name }}"
when: not template_force|bool
when:
- ovirt_templates is defined
- ovirt_templates | length > 0
- name: check iso file on data domain
ovirt_disk_facts:
auth: "{{ ovirt_auth }}"
pattern: "name={{ iso_file_name }}"
when: iso_file_name is defined
- debug:
msg: "{{ ovirt_disks }}"
- name: set file id of the iso file
set_fact:
iso_file_id: "{{ ovirt_disks[0].id }}"
when:
- ovirt_disks | length > 0
- ovirt_disks[0].id is defined
- ovirt_disks[0].content_type == 'iso'
- name: fail with message
fail:
msg: "iso file ({{ iso_file_name }}) could not be found on the data domain and iso domain does not exists"
when:
- iso_file_id is undefined
- iso_domain is undefined or iso_domain|length == 0

View File

@@ -0,0 +1,123 @@
---
- name: provision a new vm
ovirt_vm:
auth: "{{ ovirt_auth }}"
name: "{{ template.name }}"
cluster: "{{ providers.ovirt.cluster|default('Default') }}"
state: present
wait: yes
memory: "{{ template.memory }}MiB"
cpu_sockets: "{{ template.cpu }}"
boot_devices:
- hd
- cdrom
cd_iso: "{{ template.cd_iso }}"
type: server
high_availability: true
nics:
- name: nic1
profile_name: "{{ template.networks[0].name }}"
network: "{{ template.networks[0].name }}"
custom_properties: "{{ custom_properties | default(omit) }}"
operating_system: "{{ template_vm_guest_id | default(omit) }}"
timezone: "{{ template_timezone | default(omit) }}"
async: 7200
poll: 0
register: deploy
- name: wait for instance creation to complete
async_status: jid="{{ deploy.ansible_job_id }}"
register: instance
until: instance.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10
- name: create a disk
ovirt_disk:
auth: "{{ ovirt_auth }}"
name: "{% if item.name_prefix | default(false) %}{{ template.name }}_{% endif %}{{ item.name }}"
vm_name: "{{ template.name }}"
size: "{{ item.size | default(omit) }}"
format: "{{ item.format | default(omit) }}"
interface: "{{ item.interface | default(omit) }}"
bootable: "{{ item.bootable | default(omit) }}"
storage_domain: "{{ item.storage_domain | default(omit) }}"
activate: yes
state: present
wait: yes
async: 7200
poll: 0
register: create_disks
loop: "{{ template.disks }}"
when:
- template is defined
- template.disks is defined
- name: wait for disk creation to complete
async_status:
jid: "{{ item.ansible_job_id }}"
register: disks_creation
until: disks_creation.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10
loop: "{{ create_disks.results }}"
when:
- template is defined
- create_disks.results is defined
- item.ansible_job_id is defined
- include_tasks: wait_disk_unlock_pre29.yml
when:
- ansible_version.full is version('2.9', '<')
- template is defined
- template.disks is defined
- disks_creation.results is defined
- include_tasks: wait_disk_unlock.yml
when:
- ansible_version.full is version('2.9', '>=')
- template is defined
- template.disks is defined
- disks_creation.results is defined
- name: assign tags to provisioned vms
ovirt_tag:
name: "{{ item }}_{{ instance.item.item[item] }}"
vms: ["{{ instance.item.item.name }}"]
state: attached
loop:
- app_name
- role
when:
- template is defined
- instance is defined
- instance.vm is defined
- instance.item.item[item] is defined
- name: start vm
ovirt_vm:
auth: "{{ ovirt_auth }}"
name: "{{ template.name }}"
cluster: "{{ providers.ovirt.cluster|default('Default') }}"
state: running
async: 7200
poll: 0
register: start
- name: wait for instance creation to complete
async_status: jid="{{ start.ansible_job_id }}"
register: instance
until: instance.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10
- name: waiting for server to come online
wait_for:
host: "{{ template.networks[0].ip }}"
port: "{{ template.ansible_port | default(vm_ansible_port) | default(ansible_port) | default('5986') }}"
timeout: "{{ instance_wait_connection_timeout }}"
when:
- instance is changed
- template is defined
ignore_errors: yes

View File

@@ -0,0 +1,20 @@
---
- name: remove template
ovirt_template:
auth: "{{ ovirt_auth }}"
cluster: "{{ providers.ovirt.cluster }}"
name: "{{ template.name }}"
state: absent
async: 7200
poll: 0
register: undeploy
when: template is defined
- name: wait for template deletion to complete
async_status:
jid: "{{ undeploy.ansible_job_id }}"
register: instance
until: instance.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10

View File

@@ -0,0 +1,20 @@
---
- name: remove vm
ovirt_vm:
auth: "{{ ovirt_auth }}"
cluster: "{{ providers.ovirt.cluster }}"
name: "{{ template.name }}"
state: absent
async: 7200
poll: 0
register: undeploy
when: template is defined
- name: wait for template deletion to complete
async_status:
jid: "{{ undeploy.ansible_job_id }}"
register: instance
until: instance.finished
retries: "{{ instance_wait_retry_limit }}"
delay: 10

View File

@@ -0,0 +1,35 @@
---
- block:
- name: wait for server to stop responding
wait_for:
host: "{{ template_vm_ip_address }}"
port: "{{ vm_ansible_port | default('5986') }}"
timeout: 120
state: stopped
ignore_errors: yes
- include_tasks: wait_vm_poweredoff_pre29.yml
when: ansible_version.full is version('2.9', '<')
- include_tasks: wait_vm_poweredoff.yml
when: ansible_version.full is version('2.9', '>=')
rescue:
- name: ignoring any error
debug:
msg: "ignoring error..."
- name: reconfigure vm
ovirt_vm:
auth: "{{ ovirt_auth }}"
cluster: "{{ providers.ovirt.cluster }}"
name: "{{ template.name }}"
boot_devices:
- hd
cd_iso: ""
custom_properties: "{{ custom_properties_efi if template_vm_efi|bool else '' }}"
force: yes
state: present
when: template is defined

View File

@@ -0,0 +1,40 @@
---
- name: download virtio win iso file
get_url:
url: "{{ virtio_iso_url }}"
dest: "{{ temp_directory }}/virtio_win.iso"
register: download_virtio_iso
until: download_virtio_iso is success
delay: 3
retries: 5
- name: set list of directories to copy
set_fact:
virtio_iso_list_of_directories_to_extract:
- /viostor/{{ os_short_names[windows_distro_name] | default('2k16') }}/amd64
- /NetKVM/{{ os_short_names[windows_distro_name] | default('2k16') }}/amd64
- name: get a list of files from template iso
shell: >
set -o pipefail &&
isoinfo -f -R -i {{ playbook_dir }}/{{ temp_directory }}/virtio_win.iso |
grep -E "^{{ virtio_iso_list_of_directories_to_extract | join('|^') }}"
changed_when: False
register: virtio_iso_list_of_files
- name: copy files from virtio iso to target
shell: |
set -o pipefail &&
isoinfo -f -R -i {{ playbook_dir }}/{{ temp_directory }}/virtio_win.iso |\
grep -E "^{{ virtio_iso_list_of_directories_to_extract | join('|^') }}" | while read line; do
d=$(dirname $line)
od=".${d}"
[ -f $od ] && rm -f $od
[ -d $od ] || mkdir -p $od
[ -d ".${line}" ] || isoinfo -R -i \
{{ playbook_dir }}/{{ temp_directory }}/virtio_win.iso -x $line > ".${line}"
done
changed_when: True
args:
chdir: "{{ playbook_dir }}/{{ temp_directory }}/ks_iso"

View File

@@ -0,0 +1,11 @@
---
- name: wait until the image is unlocked by the oVirt engine
ovirt_disk_info:
auth: "{{ ovirt_auth }}"
pattern: "name={% if item.name_prefix | default(false) %}{{ template.name }}_{% endif %}{{ item.name }}"
register: ovirt_disk_info
until: (ovirt_disk_info.ovirt_disks is defined) and (ovirt_disk_info.ovirt_disks | length > 0) and (ovirt_disk_info.ovirt_disks[0].status != "locked")
retries: 10
delay: 3
loop: "{{ template.disks }}"

View File

@@ -0,0 +1,10 @@
---
- name: wait until the image is unlocked by the oVirt engine (<2.9)
ovirt_disk_facts:
auth: "{{ ovirt_auth }}"
pattern: "name={% if item.name_prefix | default(false) %}{{ template.name }}_{% endif %}{{ item.name }}"
until: (ovirt_disks is defined) and (ovirt_disks | length > 0) and (ovirt_disks[0].status != "locked")
retries: 10
delay: 3
loop: "{{ template.disks }}"

View File

@@ -0,0 +1,11 @@
---
- name: wait until the disk is unlocked by the oVirt engine
ovirt_disk_info:
auth: "{{ ovirt_auth }}"
pattern: "name={{ iso_file }}"
register: ovirt_disk_info
until: (ovirt_disk_info.ovirt_disks is defined) and (ovirt_disk_info.ovirt_disks | length > 0) and (ovirt_disk_info.ovirt_disks[0].status != "locked")
retries: 10
delay: 3
when: iso_file is defined

View File

@@ -0,0 +1,10 @@
---
- name: wait until the disk is unlocked by the oVirt engine (<2.9)
ovirt_disk_facts:
auth: "{{ ovirt_auth }}"
pattern: "name={{ iso_file }}"
until: (ovirt_disks is defined) and (ovirt_disks | length > 0) and (ovirt_disks[0].status != "locked")
retries: 10
delay: 3
when: iso_file is defined

View File

@@ -0,0 +1,13 @@
---
- name: wait for vm status to be poweredoff
ovirt_vm_info:
auth: "{{ ovirt_auth }}"
pattern: name={{ template.name }} and cluster={{ providers.ovirt.cluster }}
register: ovirt_vm_info_result
until:
- ovirt_vm_info_result.ovirt_vms is defined
- ovirt_vm_info_result.ovirt_vms|length > 0
- ovirt_vm_info_result.ovirt_vms[0].status == 'down'
delay: 5
retries: 30

View File

@@ -0,0 +1,12 @@
---
- name: wait for vm status to be poweredoff
ovirt_vm_facts:
auth: "{{ ovirt_auth }}"
pattern: name={{ template.name }} and cluster={{ providers.ovirt.cluster }}
until:
- ovirt_vms is defined
- ovirt_vms|length > 0
- ovirt_vms[0].status == 'down'
delay: 5
retries: 30

View File

@@ -0,0 +1,404 @@
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<!-- look for drivers on floppy -->
<component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DriverPaths>
<PathAndCredentials wcm:keyValue="1" wcm:action="add">
<Path>E:\</Path>
</PathAndCredentials>
</DriverPaths>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<InputLocale>en-US</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>en-US</UserLocale>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DiskConfiguration>
<Disk wcm:action="add">
{% if template_vm_efi is undefined or not template_vm_efi|bool %}
<ModifyPartitions>
<ModifyPartition wcm:action="modify">
<Active>true</Active>
<Format>NTFS</Format>
<Label>boot</Label>
<Order>1</Order>
<PartitionID>1</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="modify">
<Format>NTFS</Format>
<Label>{{ windows_distro_name[0:31] }}</Label>
<Letter>C</Letter>
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
<CreatePartitions>
<CreatePartition wcm:action="add">
<Type>Primary</Type>
<Order>1</Order>
<Size>350</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
{% else %}
<ModifyPartitions>
<ModifyPartition wcm:action="modify">
<Order>1</Order>
<Format>NTFS</Format>
<PartitionID>1</PartitionID>
<Label>WINRE</Label>
</ModifyPartition>
<ModifyPartition wcm:action="modify">
<Order>2</Order>
<Format>FAT32</Format>
<PartitionID>2</PartitionID>
<Label>System</Label>
</ModifyPartition>
<ModifyPartition wcm:action="modify">
<Order>3</Order>
<PartitionID>3</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="modify">
<Format>NTFS</Format>
<Letter>C</Letter>
<Order>4</Order>
<PartitionID>4</PartitionID>
<Label>{{ windows_distro_name[0:31] }}</Label>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Type>Primary</Type>
<Size>300</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Type>EFI</Type>
<Size>100</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>3</Order>
<Type>MSR</Type>
<Size>128</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>4</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
{% endif %}
</Disk>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/INDEX </Key>
<Value>{{ iso_image_index }}</Value>
</MetaData>
</InstallFrom>
<InstallTo>
<DiskID>0</DiskID>
{% if template_vm_efi is undefined or not template_vm_efi|bool %}
<PartitionID>2</PartitionID>
{% else %}
<PartitionID>4</PartitionID>
{% endif %}
</InstallTo>
</OSImage>
</ImageInstall>
<UserData>
<AcceptEula>true</AcceptEula>
<FullName>Ansible</FullName>
<Organization>Your Org.</Organization>
<ProductKey>
{% if unattend.product_key is defined and unattend.product_key|length %}
<Key>{{ unattend.product_key }}</Key>
{% endif %}
<WillShowUI>OnError</WillShowUI>
</ProductKey>
</UserData>
</component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipRearm>1</SkipRearm>
</component>
<component name="Microsoft-Windows-PnpSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<PersistAllDeviceInstalls>false</PersistAllDeviceInstalls>
<DoNotCleanUpNonPresentDevices>false</DoNotCleanUpNonPresentDevices>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<InputLocale>en-US</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UserLocale>en-US</UserLocale>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OOBE>
<HideEULAPage>true</HideEULAPage>
{% if not '2008' in windows_distro_name %}
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
{% endif %}
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Home</NetworkLocation>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
<TimeZone>{{ settings.time_zone | default('UTC') }}</TimeZone>
<UserAccounts>
{% if unattend.administrator_password is defined %}
<AdministratorPassword>
<Value>{{ unattend.administrator_password }}</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
{% endif %}
{% if unattend.local_accounts is defined %}
<LocalAccounts>
{% for local_account in unattend.local_accounts %}
<LocalAccount wcm:action="add">
{% if local_account.password is defined %}
<Password>
<Value>{{ local_account.password }}</Value>
<PlainText>true</PlainText>
</Password>
{% endif %}
{% if local_account.description is defined %}
<Description>{{ local_account.description }}</Description>
{% endif %}
{% if local_account.display_name is defined %}
<DisplayName>{{ local_account.display_name }}</DisplayName>
{% endif %}
{% if local_account.group is defined %}
<Group>{{ local_account.group }}</Group>
{% endif %}
{% if local_account.name is defined %}
<Name>{{ local_account.name }}</Name>
{% endif %}
</LocalAccount>
{% endfor %}
</LocalAccounts>
{% endif %}
</UserAccounts>
{% if enable_auto_logon and unattend.local_accounts and unattend.local_accounts[0].name and unattend.local_accounts[0].password %}
<AutoLogon>
<Password>
<Value>{{ unattend.local_accounts[0].password }}</Value>
<PlainText>true</PlainText>
</Password>
<Username>{{ unattend.local_accounts[0].name }}</Username>
<Enabled>true</Enabled>
</AutoLogon>
{% endif %}
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-NetConnectionProfile -NetworkCategory Private"</CommandLine>
<Description>Set network connection profile to private</Description>
<Order>1</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
<Description>Set Execution Policy 64 Bit</Description>
<Order>2</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% if '2008' in windows_distro_name %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm quickconfig -q</CommandLine>
<Description>winrm quickconfig -q</Description>
<Order>4</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm quickconfig -transport:http</CommandLine>
<Description>winrm quickconfig -transport:http</Description>
<Order>5</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config @{MaxTimeoutms="1800000"}</CommandLine>
<Description>Win RM MaxTimoutms</Description>
<Order>6</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config/winrs @{MaxMemoryPerShellMB="800"}</CommandLine>
<Description>Win RM MaxMemoryPerShellMB</Description>
<Order>7</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}</CommandLine>
<Description>Win RM AllowUnencrypted</Description>
<Order>8</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}</CommandLine>
<Description>Win RM auth Basic</Description>
<Order>9</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config/client/auth @{Basic="true"}</CommandLine>
<Description>Win RM client auth Basic</Description>
<Order>10</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c winrm set winrm/config/listener?Address=*+Transport=HTTP @{Port="5985"} </CommandLine>
<Description>Win RM listener Address/Port</Description>
<Order>11</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c netsh firewall add portopening TCP 5985 "Port 5985"</CommandLine>
<Description>Win RM port open</Description>
<Order>12</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c net stop winrm</CommandLine>
<Description>Stop Win RM Service </Description>
<Order>13</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c sc config winrm start= auto</CommandLine>
<Description>Win RM Autostart</Description>
<Order>14</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c net start winrm</CommandLine>
<Description>Start Win RM Service</Description>
<Order>15</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% endif %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "& $([scriptblock]::Create((New-Object Net.WebClient).DownloadString('{{ winrm_enable_script_url }}'))) -ForceNewSSLCert -EnableCredSSP"</CommandLine>
<Description>Enable winrm</Description>
<Order>20</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Enable-WSManCredSSP -Role Server -Force"</CommandLine>
<Description>Enable winrm server role</Description>
<Order>21</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-Item -Path 'WSMan:\localhost\Service\Auth\CredSSP' -Value $true"</CommandLine>
<Description>Enable credssp authentication</Description>
<Order>22</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% if template.networks is defined and template.networks[0].ip is defined and template.networks[0].gateway is defined and template.networks[0].netmask is defined %}
{% if not '2008' in windows_distro_name %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "New-NetIPAddress IPAddress {{ template.networks[0].ip }} -DefaultGateway {{ template.networks[0].gateway }} -PrefixLength {{ (template.networks[0].ip + '/' + template.networks[0].netmask) | ipaddr('prefix') }} -InterfaceIndex (Get-NetAdapter).InterfaceIndex"</CommandLine>
<Description>Set static ip</Description>
<Order>50</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% else %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c netsh int ipv4 set address "Local Area connection" static {{ template.networks[0].ip }} {{ template.networks[0].netmask }} {{ template.networks[0].gateway }}</CommandLine>
<Description>Set static ip</Description>
<Order>50</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% endif %}
{% if template.networks[0].dns_servers is defined %}
{% if not '2008' in windows_distro_name %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-DNSClientServerAddress InterfaceIndex (Get-NetAdapter).InterfaceIndex ServerAddresses {{ template.networks[0].dns_servers|join(',') }}"</CommandLine>
<Description>Set static ip</Description>
<Order>51</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% else %}
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c netsh int ipv4 set dns "Local Area connection" static {{ template.networks[0].dns_servers[0] }}</CommandLine>
<Description>Set static ip</Description>
<Order>51</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
{% endif %}
{% endif %}
{% endif %}
</FirstLogonCommands>
</component>
</settings>
<settings pass="specialize">
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-IE-ESC" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<IEHardenAdmin>false</IEHardenAdmin>
<IEHardenUser>false</IEHardenUser>
</component>
<component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SearchScopes>
<Scope wcm:action="add">
<ScopeDefault>true</ScopeDefault>
<ScopeDisplayName>Google</ScopeDisplayName>
<ScopeKey>Google</ScopeKey>
<ScopeUrl>http://www.google.com/search?q={searchTerms}</ScopeUrl>
</Scope>
</SearchScopes>
<DisableAccelerators>true</DisableAccelerators>
<DisableFirstRunWizard>true</DisableFirstRunWizard>
<Home_Page>about:blank</Home_Page>
</component>
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<fDenyTSConnections>false</fDenyTSConnections>
</component>
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserAuthentication>0</UserAuthentication>
</component>
<component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<FirewallGroups>
<FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop">
<Active>true</Active>
<Group>Remote Desktop</Group>
<Profile>all</Profile>
</FirewallGroup>
</FirewallGroups>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SkipAutoActivation>{{ settings.skip_auto_activation | default('true') }}</SkipAutoActivation>
</component>
</settings>
<settings pass="offlineServicing">
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<EnableLUA>false</EnableLUA>
</component>
</settings>
</unattend>

View File

@@ -0,0 +1 @@
localhost

View File

@@ -0,0 +1,7 @@
---
- hosts: localhost
gather_facts: False
connection: local
become: no
roles:
- ../.

View File

@@ -0,0 +1,71 @@
---
temp_directory: tmp{{ awx_job_id | default('') }}
iso_file: "windows_{{ windows_distro_name }}_autounattend{{ awx_job_id | default('') }}.iso"
export_dir: "{{ playbook_dir }}/{{ temp_directory }}"
unattend:
administrator_password: "{{ local_administrator_password }}"
local_accounts:
- name: "{{ local_account_username }}"
display_name: "{{ local_account_username }}"
description: "{{ local_account_username }} user"
group: Administrators
password: "{{ local_account_password }}"
settings:
computer_name: wintemp
time_zone: UTC
skip_auto_activation: true
product_key: "{{ iso_product_key | default('') }}"
providers:
ovirt:
datacenter: "{{ ovirt_datacenter }}"
cluster: "{{ ovirt_cluster }}"
data_domain: "{{ ovirt_data_domain }}"
export_domain: "{{ ovirt_export_domain }}"
iso_domain: "{{ ovirt_iso_domain }}"
template:
name: "{{ template_vm_name }}"
role: windows_template
app_name: windows_template_generate
domain: "{{ template_vm_domain }}"
disks:
- name: "{{ template_vm_name }}"
size: "{{ template_vm_root_disk_size }}GiB"
format: "{{ template_vm_root_disk_format }}"
interface: "{{ template_vm_root_disk_interface | default('virtio') }}"
bootable: yes
storage_domain: "{{ providers.ovirt.data_domain | default('data_domain') }}"
memory: "{{ template_vm_memory }}"
cpu: "{{ template_vm_cpu }}"
networks:
- name: "{{ template_vm_network_name }}"
ip: "{{ template_vm_ip_address }}"
netmask: "{{ template_vm_netmask }}"
gateway: "{{ template_vm_gateway }}"
domain: "{{ template_vm_domain }}"
device_type: e1000
dns_servers: "{{ template_vm_dns_servers }}"
cd_iso: "{{ iso_file_id | default(iso_file_name) }}" # if using data domain, file name does not work, need to use id
qemu_cmdline_second_iso:
- -device
- ide-cd,bus=ide.3,unit=0,drive=drive-ua-0001,id=ua-0001,bootindex=3
- -drive
- format=raw,if=none,id=drive-ua-0001,werror=report,rerror=report,readonly=on,file=/rhev/data-center/{{ ovirt_datacenter_id }}/{{ ovirt_datastore_id }}/images/{{ ks_iso_file_disk_id }}/{{ ks_iso_file_image_id }}
qemu_cmdline_efi:
- -drive
- if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd
custom_properties:
- name: qemu_cmdline
value: "{{ ((qemu_cmdline_second_iso + qemu_cmdline_efi) | to_json) if template_vm_efi|bool else (qemu_cmdline_second_iso | to_json) }}"
custom_properties_efi:
- name: qemu_cmdline
value: "{{ qemu_cmdline_efi | to_json }}"