Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(MAINT) WIP User installer for Windows #339

Closed
wants to merge 1 commit into from
Closed
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
3 changes: 2 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ gem 'csv', '3.1.5' if Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.5
gem 'rake'

gem 'gems' # Rubygems API

gem 'pry'
gem 'pry-stack_explorer'
#gem 'rubocop', "~> 0.34.2"
group :ci do
# in the ci pipeline, we calculate required ressources for TEST_TARGETS with bhg
Expand Down
4 changes: 4 additions & 0 deletions configs/components/pdk-runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
"chmod 755 #{settings[:ruby_bindir].sub(/C:/, '/cygdrive/c')}/*"
]

if settings[:install_scope] == 'perUser'
install_commands << 'mv /cygdrive/c/ProgramFiles64Folder /cygdrive/c/LocalAppDataFolder'
end

settings[:additional_rubies].each do |_rubyver, local_settings|
install_commands << "chmod 755 #{local_settings[:ruby_bindir].sub(/C:/, '/cygdrive/c')}/*"
end
Expand Down
1 change: 1 addition & 0 deletions configs/components/pdk-templates.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
build_commands << build_module(settings, pdk_bin ,settings[:cachedir], settings[:privatedir], template_ref, platform.is_windows?)

settings[:additional_rubies]&.each do |_rubyver, local_settings|
require 'pry'; binding.pry
build_commands << build_module(local_settings, pdk_bin, settings[:cachedir], settings[:privatedir], template_ref, platform.is_windows?)
end

Expand Down
9 changes: 9 additions & 0 deletions configs/projects/pdk-system-install.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
project 'pdk-system' do |proj|
# This project exists so that we can build per user machine for PDK.
# It's only used for the Windows platform.
# Additionally, there is no difference between the using this project and the
# base pdk project.
proj.setting(:install_scope, 'perMachine')
proj.setting(:runtime_project, 'pdk-runtime-system')
instance_eval File.read('configs/projects/pdk.rb')
end
7 changes: 7 additions & 0 deletions configs/projects/pdk-user-install.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
project 'pdk-user' do |proj|
# This project exists so that we can build per user installs for PDK.
# It's only used for the Windows platform.
proj.setting(:install_scope, 'perUser')
proj.setting(:runtime_project, 'pdk-runtime-user')
instance_eval File.read('configs/projects/pdk.rb')
end
31 changes: 30 additions & 1 deletion configs/projects/pdk.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,36 @@


project 'pdk' do |proj|
# Inherit a bunch of shared settings from pdk-runtime config
runtime_config = JSON.parse(File.read(File.join(__dir__, '..', 'components', 'puppet-runtime.json')))
runtime_config = JSON.parse(File.read('configs/components/puppet-runtime.json'))
proj.setting(:pdk_runtime_version, runtime_config['version'])
proj.inherit_settings 'pdk-runtime', 'https://github.com/puppetlabs/puppet-runtime', proj.pdk_runtime_version

# This is a mess and needs to be refactored.
# In order to build a user MSI we need to override the default path in all of the settings
# from pdk-runtime.
def update_hash(proj, s)
s.each do |key, value|
if value.is_a?(String) && value.include?('ProgramFiles64Folder')
proj.setting(key, value.gsub(/ProgramFiles64Folder/, 'LocalAppDataFolder'))
elsif key == :additional_rubies
updated_additional_rubies = {}
value.each do |rubyver, settings|
updated_settings = {}
settings.each do |key, value|
if value.is_a?(String) && value.include?('ProgramFiles64Folder')
updated_settings[key] = value.gsub(/ProgramFiles64Folder/, 'LocalAppDataFolder')
end
end
updated_additional_rubies[rubyver] = settings.merge!(updated_settings)
end
proj.setting(:additional_rubies, updated_additional_rubies)
end
end
end

update_hash(proj, settings) if settings[:install_scope] == 'perUser'

proj.description 'Puppet Development Kit'
proj.version_from_git
proj.write_version_file File.join(proj.prefix, 'PDK_VERSION')
Expand All @@ -23,6 +50,8 @@
proj.setting(:product_name, 'Puppet Development Kit')
proj.setting(:shortcut_name, 'Puppet Development Kit')
proj.setting(:upgrade_code, '2F79F42E-955C-4E69-AB87-DB4ED9EDF2D9')
proj.setting(:install_scope, "perMachine") unless proj.settings[:install_scope] # Set this to 'perMachine' or 'perUser'
proj.setting(:registry_root, proj.install_scope == 'perUser' ? 'HKCU' : 'HKLM')
proj.setting(:win64, 'yes')
proj.setting(:RememberedInstallDirRegKey, 'RememberedInstallDir64')
proj.setting(:LicenseRTF, 'wix/license/LICENSE.rtf')
Expand Down
11 changes: 9 additions & 2 deletions resources/windows/wix/directorylist.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
<Directory Id="<%= settings[:base_dir] %>" >
<Directory Id="<%= settings[:company_id] %>" Name="<%= settings[:pl_company_name] %>">
<Directory Id='INSTALLDIR' Name="<%= settings[:product_id] %>">
<%= @platform.generate_service_bin_dirs(self.get_services, self) %>
<Component Id="cmp<%= settings[:base_dir] %>" Guid="e9c4a394-1ae7-4b64-94c1-9ce5321ed922">
<RegistryValue Root="<%= settings[:registry_root] %>" Key="Software\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>\PuppetLabs" Name="Uninstall" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="<%= settings[:company_id] %>" Directory="<%= settings[:company_id] %>" On="uninstall" />
<RemoveFolder Id="<%= settings[:product_id] %>" Directory="INSTALLDIR" On="uninstall" />
</Component>
</Directory>
</Directory>

Expand All @@ -15,6 +19,9 @@
</Directory>
</Directory>
</Directory>
</DirectoryRef>
</DirectoryRef>
<Feature Id="RemovePDKInstallFolderFeature" Level="1">
<ComponentRef Id="cmp<%= settings[:base_dir] %>" />
</Feature>
</Fragment>
</Wix>
2 changes: 1 addition & 1 deletion resources/windows/wix/environment.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Permanent="yes"
Part="last"
Action="set"
System="yes" />
System="<%= settings[:install_scope] == 'perUser' ? 'no' : 'yes' %>" />
</Component>
</ComponentGroup>
</Fragment>
Expand Down
82 changes: 82 additions & 0 deletions resources/windows/wix/filter.xslt.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
xmlns="http://schemas.microsoft.com/wix/2006/wi"
exclude-result-prefixes="xsl wix">

<!-- https://ahordijk.wordpress.com/2013/03/26/automatically-add-references-and-content-to-the-wix-installer/ -->
<!-- http://www.chriskonces.com/using-xslt-with-heat-exe-wix-to-create-windows-service-installs/ -->
<xsl:output method="xml" indent="yes" />
<!--<xsl:strip-space elements="*"/>-->

<xsl:variable name="root" select="/*" />

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>

<!--File keypath to no and add registry keypath-->
<xsl:template match="wix:Component/wix:File">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:attribute name="KeyPath">
<xsl:text>no</xsl:text>
</xsl:attribute>
</xsl:copy>
<wix:RegistryValue Root="<%= settings[:registry_root] %>" Key="Software\<%= settings[:base_dir] %>\<%= settings[:product_id] %>\{../@Id}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</xsl:template>

<xsl:template match="wix:ComponentGroup/wix:Component[(@KeyPath='yes')]">
<xsl:copy>
<xsl:apply-templates select="@*" />
<xsl:attribute name="KeyPath">
<xsl:text>no</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="node()" />
<wix:RegistryValue Root="<%= settings[:registry_root] %>" Key="Software\<%= settings[:base_dir] %>\<%= settings[:product_id] %>\cmp_{generate-id(@Id)}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</xsl:copy>
</xsl:template>

<xsl:template match="wix:DirectoryRef">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<Component Id="cmp_{generate-id(@Id)}">
<xsl:for-each select=".//wix:Directory[@Id]">
<RemoveFolder Id="{@Id}" Directory="{@Id}" On="uninstall" />
</xsl:for-each>
<wix:RegistryValue Root="<%= settings[:registry_root] %>" Key="Software\<%= settings[:base_dir] %>\<%= settings[:product_id] %>\cmp_{generate-id(@Id)}" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</xsl:copy>
</xsl:template>

<xsl:template match="wix:Component[contains(@Id,'cmp_')]">
<xsl:element name="Component">
<xsl:copy-of select="@*"/>
</xsl:element>
</xsl:template>

<xsl:template match="wix:ComponentGroup[@Id='AppComponentGroup']">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
<xsl:for-each select="$root//wix:Fragment/wix:DirectoryRef[1]">
<ComponentRef Id="cmp_{generate-id(@Id)}" />
</xsl:for-each>
</xsl:copy>
</xsl:template>
<!-- Filter out all Service File Executables from the Harvest (heat) run as these are specified in the transformed service.components.wxs file -->
<!-- The list of component service files are collected in an array so that a set of unique names can be extracted -->
<!-- we have to substitue the SourceDir\\etc. etc. for $(var.ProjectSourcePath) in order to facilitate heat -->
<!-- being run in two different places, specifically it no longer runs from SourceDir so we needed to pass -->
<!-- in ProjectSourcePath to the heat runs. Thus when this filter does its work the source attribute will -->
<!-- look like $(var.ProjectSourcePath)/puppet/bin/rubyw.exe for example, not -->
<!-- SourceDir/Program64FilesFolder/Puppet/puppet/bin/ruby.exe -->
<%- service_files = Array.new -%>
<%- get_services.each do |service| -%>
<%- service_files << service.service_file.sub("SourceDir\\#{self.settings[:base_dir]}\\#{self.settings[:company_id]}\\#{self.settings[:product_id]}", "$(var.AppSourcePath)") -%>
<%- end -%>
<%- service_files.uniq.each do |service_file| -%>
<xsl:template match="wix:Component[wix:File[@Source='<%= service_file %>']]" />
<%- end -%>
</xsl:stylesheet>
2 changes: 1 addition & 1 deletion resources/windows/wix/project.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

<Package
InstallerVersion="300"
InstallScope="perMachine"
InstallScope="<%= settings[:install_scope] %>"
Description="<%= "#{settings[:product_id]}#{@platform.architecture == "x64" ? " (64-bit)" : ""}" %> Installer"
Comments="<%= @homepage %>"
Compressed="yes"
Expand Down
4 changes: 2 additions & 2 deletions resources/windows/wix/properties.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
<Property Id="INSTALLDIR">
<RegistrySearch
Id="RecallInstallDir"
Root="HKLM"
Root="<%= settings[:registry_root] %>"
Key="SOFTWARE\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>"
Name="<%= settings[:RememberedInstallDirRegKey] %>"
Type="raw"
Expand All @@ -49,7 +49,7 @@
<Property Id="INSTALLDIR_X86" >
<RegistrySearch
Id="RecallInstallDirx86"
Root="HKLM"
Root="<%= settings[:registry_root] %>"
Key="SOFTWARE\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>"
Name="<%= settings[:RememberedInstallDirRegKey] %>"
Type="raw"
Expand Down
4 changes: 2 additions & 2 deletions resources/windows/wix/registryEntries.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Win64="no">

<RegistryKey
Root="HKLM"
Root="<%= settings[:registry_root] %>"
Key="SOFTWARE\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>">
<!-- This is the default (aka 'unnamed') key value of this path -->
<RegistryValue
Expand All @@ -35,7 +35,7 @@
Permanent="yes">

<RegistryKey
Root="HKLM"
Root="<%= settings[:registry_root] %>"
Key="SOFTWARE\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>"
ForceCreateOnInstall="yes" >

Expand Down
9 changes: 7 additions & 2 deletions resources/windows/wix/shortcuts.wxs.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
<!-- These shortcuts will be created in the INSTALLDIR/bin directory -->
<DirectoryRef Id='INSTALLDIR'>
<Directory Id="ShortCutBinDir" Name="bin">
<Component Id="ShortCutBinDir">
<RegistryValue Root="<%= settings[:registry_root] %>" Key="Software\<%= settings[:pl_company_name] %>\<%= settings[:product_id] %>\ShortCutBinDir" Name="installed" Type="integer" Value="1" KeyPath="yes" />
<RemoveFolder Id="ShortCutBinDir" On="uninstall" />
</Component>
</Directory>
</DirectoryRef>
</DirectoryRef>

<!-- Directory Definitions for Start Menu Shortcuts -->
<DirectoryRef Id='TARGETDIR'>
Expand Down Expand Up @@ -43,7 +47,8 @@
Value="1"
Type="integer"
KeyPath="yes" />
</Component>
</Component>
<ComponentRef Id="ShortCutBinDir" />
</ComponentGroup>
</Fragment>
</Wix>
Loading