Skip to content

Commit

Permalink
Modernized Windows Support and documentation update
Browse files Browse the repository at this point in the history
  • Loading branch information
yakatz committed May 14, 2024
1 parent fb0ff7d commit 0fb8bc5
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 57 deletions.
26 changes: 3 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,28 +190,8 @@ Where the number (1, 2 etc.) are the number of factsets for that OS and facter c

## Add new Operating System support

There is `Vagrantfile` to automagically populate `facts` directory by spawning a new VM and launches a provisioning scripts.

```
$ cd facts
$ vagrant up --provision
```

Create i386 facts from x86_64's ones

```
for file in facts/*/*-x86_64.facts; do cat $file | sed -e 's/x86_64/i386/' -e 's/amd64/i386/' > $(echo $file | sed 's/x86_64/i386/'); done
```
Create RedHat, Scientific, OracleLinux facts from CentOS's ones

```
$ bundle exec rake rhel_alts
```

Then update the table in this README by running `bundle exec rake table`

*NOTE*: When using Facter version 4, by default some "legacy facts" are hidden from the output.
To generate a fact set with the legacy facts use the command `puppet facts show --show-legacy`
There is `Vagrantfile` to automagically populate `facts` for all supported operating systems by spawning a new VM and launches a provisioning scripts.
Details of how to generate facts for each operating system are [here](facts/README.md).

## Supplying custom external facts

Expand Down Expand Up @@ -306,7 +286,7 @@ powershell> $ENV:FACTERDB_INJECT_SOURCE = 'true'

# Contributing

Please submit issues at https://github.com/camptocamp/facterdb/issues or PRs in the same repository.
Please submit issues at https://github.com/voxpupuli/facterdb/issues or PRs in the same repository.

## Release process

Expand Down
2 changes: 2 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ def factset_to_os_label(fs)
'2016')}"
elsif /windows-2019/.match?(db_filename)
'Windows Server 2019'
elsif /windows-2022/.match?(db_filename)
'Windows Server 2022'
else
"#{os_name} #{os__rel}"
end
Expand Down
101 changes: 101 additions & 0 deletions facts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Building Facts for distribution

There is `Vagrantfile` to automatically populate `facts` for all supported operating systems by spawning a new VM and launches a provisioning scripts.

## Vagrant

[Vagrant](https://www.vagrantup.com/) is a tool for creating reproducible virtual machine builds.
We use it to ensure facts are generated as similarly as possible every time.

Vagrant starts by downloading a `box` - a pre-build skeleton of a virtual machine - and then running multiple steps on it.
Our workflow generally looks like this:

1. One or more setup steps to make the VM ready to install puppet and generate facts (for example, setting up the network)
1. Calling the `get_facts` script which installs multiple versions of Puppet and generates facts for multiple versions of facter.
1. Shutting down the VM (Vagrant doesn't do this automatically).

### Plugins

The vagrant timezone plugin is recommended to prevent unnecessary changes to timezone facts:

```
vagrant plugin install vagrant-timezone
```

## Hypervisor

The distributed facts are built using [VirtualBox](https://www.virtualbox.org/wiki/Downloads).
Building the facts will work with other visualization hosts, but will produce different results (eg. IP ranges) that will break spec tests.

VirtualBox versions 6 and 7 have been tested.
The GPLv3 version of VirtualBox is sufficient - the proprietary `Oracle VM VirtualBox Extension Pack` is not required.

## Building Facts

To build new facts for all supported operating systems (except Windows)

```
$ cd facts
$ vagrant up --provision
```

You can build facts for only a single system or list of specific systems.

```
$ vagrant up --provision debian-11-x86_64
```

Windows facts are not built by default, but can be run manually.

```
$ vagrant up --provision windows-server-2019-x86_64 windows-server-2022-x86_64 windows-10-x86_64 windows-11-x86_64
```

Once new facts are built, the table listing supported facter versions and operating systems needs to be updated.

```
$ bundle exec rake table
```

### Converted Facts

Not all facts can (or should) be built from VMs.
It often isn't necessary to run a separate VM to create some facts that won't be significantly different for existing facts.
Some operating systems are harder to run in VMs.

#### Create i386 facts from x86_64's ones

```
for file in facts/*/*-x86_64.facts; do cat $file | sed -e 's/x86_64/i386/' -e 's/amd64/i386/' > $(echo $file | sed 's/x86_64/i386/'); done
```

#### Create OracleLinux facts from RedHat's ones

```
$ bundle exec rake rhel_alts
```

## Legacy Facts

*NOTE*: When using Facter version 4, by default some "legacy facts" are hidden from the output.
To generate a fact set with the legacy facts use the command `puppet facts show --show-legacy`

## OS-Specific Notes

### Ubuntu 18.04

The default Ubuntu 18.04 `box` creates a console log file (ubuntu-bionic-18.04-cloudimg-console.log).
Newer Ubuntu `boxes` don't do this.
This behavior can be modified by changing the `box` configuration: `config.vm.provider "virtualbox" do |vb| vb.customize ["modifyvm", :id, "--uartmode1", "disconnected"] end`

### Windows

There are publicly available Windows `boxes` for Vagrant.

We currently use publicly-availble `boxes` from Vagrant Community, but we also included packer templates so you can build your own (currently outdated).

run `packer build <file>.json`
followed by `vagrant add <boxname> <boxfile>`

Once the box is added, change the `Vagrantfile` to use your new `box` and run `vagrant up <windows_os_name>`

37 changes: 27 additions & 10 deletions facts/Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -296,26 +296,43 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
host.vm.provision 'shell', path: 'get_facts.sh'
host.vm.provision 'shell', inline: '/sbin/shutdown -h now'
end
config.vm.define 'windows-7-x86_64' do |host|
# Windows boxes can sometimes be picky, so don't include them automatically (autostart: false)
config.vm.define 'windows-server-2019-x86_64', autostart: false do |host|
host.vm.hostname = 'foo'
host.vm.box = 'ferventcoder/win7pro-x64-nocm-lite'
host.vm.box = 'gusztavvargadr/windows-server-2019-standard-core'
host.vm.synced_folder '.', '/vagrant'
host.vm.communicator = 'winrm'
host.vm.guest = :windows
host.windows.set_work_network = true
host.vm.provision 'shell', path: 'windows_get_facts.ps1'
host.vm.provision 'shell', inline: 'shutdown -s -f -c "Fact Collection Complete"'
end
config.vm.define 'windows-server-2022-x86_64', autostart: false do |host|
host.vm.hostname = 'foo'
host.vm.box = 'gusztavvargadr/windows-server-2022-standard-core'
host.vm.synced_folder '.', '/vagrant'
host.vm.communicator = 'winrm'
host.vm.guest = :windows
host.vm.network :private_network, auto_network: true
host.vm.network 'forwarded_port', guest: 22, host: 2200, id: 'ssh', auto_correct: true
host.windows.set_work_network = true
host.vm.provision 'shell', path: 'windows_get_facts.ps1'
# host.vm.provision 'shell', inline: "Stop-Computer -AsJob"
host.vm.provision 'shell', inline: 'shutdown -s -f -c "Fact Collection Complete"'
# host.vm.post_up_message = 'Note that windows machines do not automatically shutdown. You must run a \'vagrant destroy\' or \'vagrant halt\' to terminate/stop the build vm.'
end
config.vm.define 'windows-2012r2-core-x86_64' do |host|
config.vm.define 'windows-10-x86_64', autostart: false do |host|
host.vm.hostname = 'foo'
host.vm.box = 'windows-2012r2-core-x86_64'
host.vm.box = 'gusztavvargadr/windows-10'
host.vm.synced_folder '.', '/vagrant'
host.vm.communicator = 'winrm'
host.vm.guest = :windows
host.windows.set_work_network = true
host.vm.provision 'shell', path: 'windows_get_facts.ps1'
host.vm.provision 'shell', inline: 'shutdown -s -f -c "Fact Collection Complete"'
end
config.vm.define 'windows-11-x86_64', autostart: false do |host|
host.vm.hostname = 'foo'
host.vm.box = 'gusztavvargadr/windows-11'
host.vm.synced_folder '.', '/vagrant'
host.vm.communicator = 'winrm'
host.vm.guest = :windows
host.vm.network :private_network, auto_network: true
host.vm.network 'forwarded_port', guest: 22, host: 2200, id: 'ssh', auto_correct: true
host.windows.set_work_network = true
host.vm.provision 'shell', path: 'windows_get_facts.ps1'
host.vm.provision 'shell', inline: 'shutdown -s -f -c "Fact Collection Complete"'
Expand Down
11 changes: 0 additions & 11 deletions facts/Windows_README.md

This file was deleted.

64 changes: 51 additions & 13 deletions facts/windows_get_facts.ps1
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
param(
[array]$puppetAgentVersions = ('1.1.1','1.2.2','1.4.0'),
[string]$baseUrl = 'https://downloads.puppetlabs.com/windows',
[array]$puppetAgentVersions = ('7.24.0','8.0.0','8.5.1'),
[string]$baseUrl = 'https://downloads.puppetlabs.com/windows/puppet{0}/puppet-agent-{1}-{2}.msi',
[string]$fqdn = 'foo.example.com'
)

$PuppetInstallerPath = 'c:\vagrantshared\resources\installers'
$ComputerName = "foo"
$ComputerDomain = "example.com"

Remove-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "Hostname"
Remove-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "NV Hostname"
Remove-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "Domain"

Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Computername\Computername" -name "Computername" -value $ComputerName
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Control\Computername\ActiveComputername" -name "Computername" -value $ComputerName
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "Hostname" -value $ComputerName
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -name "NV Hostname" -value $ComputerName
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name Domain -Value $ComputerDomain
Set-ItemProperty -path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name DhcpDomain -Value $ComputerDomain

# This doesn't work even though net use does???
#New-SmbMapping -LocalPath 'X:' -RemotePath '\\VBOXSVR\vagrant'
net use X: \\VBOXSVR\vagrant

$VagrantDataPath = 'X:\'
$WorkingDirectory = 'C:\vagrant_working_directory\'

# Make sure we have enough privs to install the things.
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
Expand All @@ -14,21 +33,28 @@ if (! ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Admin
}

# Create our tmp dir if it's not found
if (!(Test-Path $PuppetInstallerPath)) {
Write-Host "Creating folder `'$PuppetInstallerPath`'"
$null = New-Item -Path "$PuppetInstallerPath" -ItemType Directory
if (!(Test-Path $WorkingDirectory)) {
Write-Host "Creating folder `'$WorkingDirectory`'"
$null = New-Item -Path "$WorkingDirectory" -ItemType Directory
}

# Install each puppet version & collect facts.
foreach ($pupAgentVer in $puppetAgentVersions) {
$agentUrl = "$baseUrl/puppet-agent-$pupAgentVer-x64.msi"
$agentInstaller = Join-Path $PuppetInstallerPath "puppet-agent-$pupAgentVer-x64.msi"

$agentUrl = $baseUrl -f $pupAgentVer[0], $pupAgentVer, "x64"
$agentName = "puppet-agent-{1}-{2}.msi" -f $pupAgentVer[0], $pupAgentVer, "x64"
$agentLogNameI = "puppet-{1}-install.log" -f $pupAgentVer[0], $pupAgentVer, "x64"
$agentLogNameU = "puppet-{1}-uninstall.log" -f $pupAgentVer[0], $pupAgentVer, "x64"
$agentInstaller = Join-Path $WorkingDirectory $agentName
$agentLogPathI = Join-Path $WorkingDirectory $agentLogNameI
$agentLogPathU = Join-Path $WorkingDirectory $agentLogNameU

write-Host "Downloading `'$agentUrl`' to `'$agentInstaller`'"
(New-Object Net.WebClient).DownloadFile("$agentUrl", "$agentInstaller")

#Install the actual agent, and
$install_args = @("/qn", "/norestart", "/i", "$agentInstaller", "PUPPET_AGENT_CERTNAME=$fqdn")
#Install the actual agent
$install_args = @("/l*v $agentLogPathI", "/qn", "/norestart", "/i", "$agentInstaller", "PUPPET_AGENT_CERTNAME=$fqdn")
$uninstall_args = @("/l*v $agentLogPathU", "/qn", "/norestart", "/x", "$agentInstaller")
Write-Host "Installing Puppet. running msiexec.exe $install_args"
$agentProcess = Start-Process -FilePath msiexec.exe -ArgumentList $install_args -Wait -PassThru
if ($agentProcess.ExitCode -ne 0) {
Expand All @@ -49,12 +75,24 @@ foreach ($pupAgentVer in $puppetAgentVersions) {
# the domain name will fallback to the hypervisor's domain.
$env:FACTER_fqdn = $fqdn

$facterArgs = @("-j")
$facterProcess = Start-Process -FilePath $facterBin -ArgumentList $facterArgs -Wait -PassThru -RedirectStandardOutput "C:\vagrant\$facterVer\$Os-$Osmaj-$Hw.facts"
$facterArgs = @("-j", "-p", "--show-legacy")
$facterProcess = Start-Process -FilePath $facterBin -ArgumentList $facterArgs -Wait -PassThru -RedirectStandardOutput "X:\$facterVer\$Os-$Osmaj-$Hw.facts"
if ($facterProcess.ExitCode -ne 0) {
Write-Host "Facter failed."
Exit 1
}

# dos2unix: `n in Powershell is a LF character
((Get-Content "X:\$facterVer\$Os-$Osmaj-$Hw.facts") -join "`n") + "`n" | Set-Content -NoNewline "X:\$facterVer\$Os-$Osmaj-$Hw.facts"

Write-Host "Facts collected for $Os-$Osmaj-$Hw with facter $facterVer"
}

Write-Host "Uninstalling Puppet. running msiexec.exe $uninstall_args"
$agentProcess = Start-Process -FilePath msiexec.exe -ArgumentList $uninstall_args -Wait -PassThru
if ($agentProcess.ExitCode -ne 0) {
Write-Host "Installer failed."
Exit 1
}
Write-Host "Puppet Agent $pupAgentVer successfully uninstalled."

}

0 comments on commit 0fb8bc5

Please sign in to comment.