Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM plus3it/tardigrade-ci:0.28.7
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
chrome-browser-formula
==================

A SaltStack formula designed to install and configure Google's [Chrome Browser](https://www.google.com/chrome).

It is primarily expected that this formula will be run via [P3](https://www.plus3it.com/)'s "[watchmaker](https://watchmaker.readthedocs.io/en/stable/)" framework.

This formula is able to install the Chrome browser on both Linux[^1] and Windows Server[^2] operating environments:

* On Linux hosts, it will install using the distro's native package-manager[^1]
* On Windows hosts, it will install using the installer-EXE[^3]

## Available states

- [chrome-browser](#chrome-browser)
- [chrome-browser.clean](#chrome-browser.clean)
- [chrome-browser.package](#chrome-browser.package)
- [chrome-browser.package.clean](#chrome-browser.package.clean)
- [chrome-browser.config](#chrome-browser.config)
- [chrome-browser.config.clean](#chrome-browser.config.clean)

### chrome-browser

Executes the `package` and `config` states to install and configure the Chrome Browser

### chrome-browser.clean

Executes the `package` and `config` states' `clean` actions to fully uninstall the Chrome Browser and remove previously-installed browser policy-configs (and, on Windows, associated registry entries)

### chrome-browser.package

Executes _just_ the `package` state to install the Chrome Browser package.

### chrome-browser.package.clean

Executes _just_ the `package.clean` state to uninstall the Chrome Browser package.

### chrome-browser.config

Executes _just_ the `config` state to install/configure the Chrome policy files

### chrome-browser.config.clean

Executes _just_ the `config` state to uninstall the Chrome policy files and, on Windows, remove any registry-keys set by prior install-runs of the formula.



[^1]: As of this README's writing, only Enterprise Linux and related distros (Red Hat and Oracle Enterprise, CentOS Stream, Rocky and Alma Linux). It has only been specifically tested with EL **_9_** variants.
[^2]: As of this README's writing, this functionality has only been tested on Windows Server 2022
[^3]: Future iterations _may_ allow the use of MSI-based installers.
22 changes: 22 additions & 0 deletions chrome-browser/config/win_clean.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# vim: ft=sls

{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- from tplroot ~ "/map.jinja" import mapdata as chrome with context %}

{%- for key in chrome.policy_extras.registry_keys %}
Remove Registry Key {{ loop.index }}:
reg.absent:
- name: {{ key }}
- onchanges:
- cmd: Uninstall Google Chrome
{%- endfor %}

{%- for id, path in chrome.policy_extras.policy_files.items() %}
Remove Chrome Policy File "{{ id }}":
file.absent:
- name: {{ path }}
- onchanges:
- cmd: Uninstall Google Chrome
{%- endfor %}
104 changes: 104 additions & 0 deletions chrome-browser/config/win_file.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# -*- coding: utf-8 -*-
# vim: ft=sls
#
{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- from tplroot ~ "/map.jinja" import mapdata as chrome with context %}

{%- set policy_path = 'C:/Windows/PolicyDefinitions' %}
{%- set source_root = 'C:/Windows/Temp/Chrome/full_extract/windows/admx' %}
{%- set ChromeTmp = 'C:/Windows/Temp/Chrome' %}
{%- set no_update_value = chrome.policy_extras.settings.no_update | string | lower %}
{%- set hklm_root = 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Google\Chrome' %}
{%- set chrome_files = {
'google_admx': {'src': source_root ~ '/google.admx', 'dest': policy_path ~ '/google.admx'},
'chrome_admx': {'src': source_root ~ '/chrome.admx', 'dest': policy_path ~ '/chrome.admx'},
'chrome_adml': {'src': source_root ~ '/en-US/chrome.adml', 'dest': policy_path ~ '/en-US/chrome.adml'}
}
%}

Cleanup Chrome Temp Directory:
file.absent:
- name: '{{ ChromeTmp }}'
- require:
{%- for id in chrome_files.keys() %}
- file: 'Deploy file {{ id }}'
{%- endfor %}

{%- if chrome.policy_extras.settings.home_page %}
Configure Chrome Homepage:
reg.present:
- name: '{{ hklm_root }}'
- vname: 'HomepageLocation'
- vdata: '{{ chrome.policy_extras.settings.home_page }}'
- vtype: REG_SZ
- require:
{%- for id in chrome_files.keys() %}
- file: 'Deploy file {{ id }}'
{%- endfor %}
{%- endif %}

{%- if chrome.policy_extras.settings.managed_bookmarks_enabled | string | lower == 'true' and chrome.policy_extras.settings.managed_bookmarks %}
Configure Managed Bookmarks:
reg.present:
- name: '{{ hklm_root }}'
- vname: 'ManagedBookmarks'
- vdata: {{ chrome.policy_extras.settings.managed_bookmarks | json }}
- vtype: REG_SZ
- require:
{%- for id in chrome_files.keys() %}
- file: 'Deploy file {{ id }}'
{%- endfor %}
{%- endif %}

{%- for id, paths in chrome_files.items() %}
Deploy file {{ id }}:
file.copy:
- name: '{{ paths.dest }}'
- source: '{{ paths.src }}'
- force: True
- makedirs: True
- require:
- archive: 'Extract Chrome Bundle'
{%- endfor %}

{%- if no_update_value == 'true' %}
Disable Chrome Auto-Update:
reg.present:
- name: '{{ hklm_root | replace('\\Chrome', '\\Update') }}'
- vname: 'UpdateDefault'
- vdata: 0
- vtype: REG_DWORD
- require:
{%- for id in chrome_files.keys() %}
- file: 'Deploy file {{ id }}'
{%- endfor %}
{%- endif %}

{%- if chrome.policy_extras.settings.password_manager_enabled | string | lower == 'false' %}
Disable Chrome Password Manager:
reg.present:
- name: '{{ hklm_root }}'
- vname: 'PasswordManagerEnabled'
- vdata: 0
- vtype: REG_DWORD
- require:
{%- for id in chrome_files.keys() %}
- file: 'Deploy file {{ id }}'
{%- endfor %}
{%- endif %}

Ensure Chrome TempDir Exists:
file.directory:
- name: '{{ ChromeTmp }}'
- makedirs: True

Extract Chrome Bundle:
archive.extracted:
- name: '{{ ChromeTmp }}/full_extract'
- source: 'https://dl.google.com/dl/edgedl/chrome/policy/policy_templates.zip'
- skip_verify: True
- enforce_toplevel: False
- overwrite: True
- require:
- file: 'Ensure Chrome TempDir Exists'
40 changes: 40 additions & 0 deletions chrome-browser/files/uninstall_chrome.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
$RealPF = [System.Environment]::GetEnvironmentVariable("ProgramW6432")
if (-not $RealPF) { $RealPF = $env:ProgramFiles }

$ChromePath = Join-Path $RealPF "Google\Chrome\Application"
$ChromeExe = Join-Path $ChromePath "chrome.exe"

# PRE-CONDITION (State Check)
if (Test-Path $ChromeExe) {
Write-Output "Found chrome-binary '$ChromeExe'"
}
elseif (-not (Test-Path $ChromeExe)) {
# Salt will see this string in the 'comment' or 'stdout' field
Write-Output "State: Already Absent"
exit 100
}

# EXECUTION
$VDir = Get-ChildItem -Path $ChromePath | Where-Object { $_.Name -match '^\d' } | Select-Object -First 1
if ($VDir) {
$VerPath = Join-Path -Path $ChromePath -ChildPath $VDir.Name
$Setup = Join-Path -Path $VerPath -ChildPath "Installer\setup.exe"

if ( Test-Path $Setup ) {
Write-Output "Found uninstaller (setup utility) at '$Setup'"
Write-Output "Uninstalling version $( $VDir.Name )..."
$Proc = Start-Process "$Setup" -ArgumentList '--uninstall --multi-install --chrome --system-level --force-uninstall' -Wait -PassThru
$Proc.WaitForExit()

# FINAL VERIFICATION
if ( -not ( Test-Path $ChromeExe ) ) {
Write-Output "State: Success"
exit 0
} else {
Write-Error "State: Failed to remove binary"
exit 1
}
}
}

exit 100
6 changes: 6 additions & 0 deletions chrome-browser/package/clean.sls
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# -*- coding: utf-8 -*-
# vim: ft=sls

{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- set sls_config_clean = tplroot ~ '.config.clean' %}
{%- from tplroot ~ "/map.jinja" import mapdata as TEMPLATE with context %}

include:
- {{ sls_config_clean }}
{%- if grains.kernel == "Linux" %}
- .lin_clean
{%- elif grains.kernel == "Windows" %}
Expand Down
2 changes: 2 additions & 0 deletions chrome-browser/package/install.sls
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ include:
{%- if grains.kernel == "Linux" %}
- .lin_install
{%- elif grains.kernel == "Windows" %}
- .win_pre-install
- .win_install
- .win_post-install
{%- endif %}
22 changes: 22 additions & 0 deletions chrome-browser/package/win_clean.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# vim: ft=sls

{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- set sls_config_clean = tplroot ~ '.config.clean' %}
{%- from tplroot ~ "/map.jinja" import mapdata as TEMPLATE with context %}

Purge Chrome Directory:
file.absent:
- name: 'C:\Program Files\Google\Chrome\Application'
- onchanges:
- cmd: Uninstall Google Chrome

Uninstall Google Chrome:
cmd.script:
- source: salt://{{ tplroot }}/files/uninstall_chrome.ps1
- shell: powershell
- success_retcodes: [
0,
100
]
37 changes: 37 additions & 0 deletions chrome-browser/package/win_install.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# vim: ft=sls
{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- from tplroot ~ "/map.jinja" import mapdata as chrome with context %}
{%- if salt.grains.get('cpuarch') == "AMD64" %}
{%- set temp_exe = 'C:/Windows/Temp/ChromeStandaloneSetup64.exe' %}
{%- else %}
{%- set temp_exe = 'C:/Windows/Temp/ChromeStandaloneSetup32.exe' %}
{%- endif %}

Clean staged Chrome Standalone EXE-based installer:
file.absent:
- name: '{{ temp_exe }}'
- require:
- cmd: 'Install Google Chrome EXE'

Download Chrome Standalone EXE-based installer:
file.managed:
- name: '{{ temp_exe }}'
- source: '{{ chrome.pkg.installer_uri }}'
- skip_verify: True
- makedirs: True

Install Google Chrome EXE:
cmd.run:
- name: |
Start-Process "{{ temp_exe }}" -ArgumentList '/silent /install' -Wait
Start-Sleep -Seconds 5
- require:
- file: 'Download Chrome Standalone EXE-based installer'
- shell: powershell
- success_retcodes: [
0,
3010
]
- unless: 'if (Test-Path "${env:ProgramFiles}\Google\Chrome\Application\chrome.exe") { exit 0 } else { exit 1 }'
41 changes: 41 additions & 0 deletions chrome-browser/package/win_post-install.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# vim: ft=sls
{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- from tplroot ~ "/map.jinja" import mapdata as chrome with context %}
{%- set hklm_root = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components' %}
{%- set hklm_path = 'SOFTWARE\Microsoft\Active Setup\Installed Components' %}
{%- set salt_reg_root = 'HKEY_LOCAL_MACHINE\\' ~ hklm_path %}
{%- set ps_reg_root = 'HKLM:\\' ~ hklm_path %}

Re-enable IE ESC for Administrators:
reg.present:
- name: '{{ salt_reg_root }}\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}'
- vname: IsInstalled
- vtype: REG_DWORD
- vdata: 1
- require:
- cmd: 'Install Google Chrome EXE'
- cmd: 'Revert IE ESC to Original States'

Re-enable IE ESC for Users:
reg.present:
- name: '{{ salt_reg_root }}\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}'
- vname: IsInstalled
- vtype: REG_DWORD
- vdata: 1
- require:
- cmd: 'Install Google Chrome EXE'
- cmd: 'Revert IE ESC to Original States'

Revert IE ESC to Original States:
cmd.run:
- name: |
$path = "C:/Windows/Temp/ie_esc_original_state.txt"
if (Test-Path $path) {
$s = (Get-Content $path).Split(',')
if ($s[0] -eq "1") { Set-ItemProperty '{{ ps_reg_root }}\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}' IsInstalled 1 }
if ($s[1] -eq "1") { Set-ItemProperty '{{ ps_reg_root }}\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}' IsInstalled 1 }
Remove-Item $path -Force
}
- shell: powershell
36 changes: 36 additions & 0 deletions chrome-browser/package/win_pre-install.sls
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# vim: ft=sls
{#- Get the `tplroot` from `tpldir` #}
{%- set tplroot = tpldir.split('/')[0] %}
{%- from tplroot ~ "/map.jinja" import mapdata as chrome with context %}
{%- set hklm_root = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components' %}
{%- set hklm_path = 'SOFTWARE\Microsoft\Active Setup\Installed Components' %}
{%- set salt_reg_root = 'HKEY_LOCAL_MACHINE\\' ~ hklm_path %}
{%- set ps_reg_root = 'HKLM:\\' ~ hklm_path %}

Capture Original IE ESC States:
cmd.run:
- name: |
$admin = (Get-ItemProperty '{{ ps_reg_root }}\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}').IsInstalled
$user = (Get-ItemProperty '{{ ps_reg_root }}\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}').IsInstalled
"$admin,$user" | Out-File 'C:/Windows/Temp/ie_esc_original_state.txt' -Encoding ascii
- shell: powershell
- creates: C:/Windows/Temp/ie_esc_original_state.txt

Disable IE ESC for Administrators:
reg.present:
- name: '{{ salt_reg_root }}\\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}'
- require:
- cmd: 'Capture Original IE ESC States'
- vname: IsInstalled
- vtype: REG_DWORD
- vdata: 0

Disable IE ESC for Users:
reg.present:
- name: '{{ salt_reg_root }}\\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}'
- require:
- cmd: 'Capture Original IE ESC States'
- vname: IsInstalled
- vtype: REG_DWORD
- vdata: 0
Loading
Loading