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

Windows MSI Packaging #141

Merged
merged 104 commits into from
Jul 3, 2020
Merged

Windows MSI Packaging #141

merged 104 commits into from
Jul 3, 2020

Conversation

rozmansi
Copy link
Contributor

@rozmansi rozmansi commented Nov 13, 2018

This PR adds MSI packaging side-by-side with NSIS packaging.

Quick Instructions

MSI Packaging

See detailed instructions in https://github.com/rozmansi/openvpn-build/blob/feature/windows-msi/windows-msi/README.rst.

Binaries for Initial Impression

Compiled, signed and MSI packaged OpenVPN is available at https://github.com/rozmansi/openvpn/releases/tag/v2.4.6m. This is for informational purposes, to get a quick overview of setup experience.

Final Note

Please mind that this PR starts with a packaging of OpenVPN 2.4.6 version instead of 2.5._git on purpose. We need to have previous version of the package to test the upgrading process before 2.5 is published.

Copy link
Member

@mattock mattock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me in general. I added some inline comments and will test this next.

windows-msi/README.rst Outdated Show resolved Hide resolved
windows-msi/bookmarks/howto.url Show resolved Hide resolved
windows-msi/boot.wsf.in Outdated Show resolved Hide resolved

dnl The upgrade GUIDs MUST persist for all versions of the same product line.
dnl Please use own upgrade GUIDs when deploying a non-official OpenVPN release.
define([PRODUCT_UPGRADE_GUID_x86], [{1195A47B-A37A-4055-9D34-B7A691F7E97B}])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How were/are these GUIDs created?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uuidgen | tr [a-f] [A-F]

I just picked some random to get started. Any unique hexadecimal number is OK. Old MSI versions required all uppercase GUIDs and I stick to that recommendation.

PRODUCT_UPGRADE_GUID_... are called upgrade code(s) and are used by MSI to follow the product line across versions, 3rd party products to detect OpenVPN is installed... The upgrade code is rarely changed - it is the product identifier. However, I choose not to hard-code them to allow 3rd party vendors to package their own "OpenVPN" product line.

Use of platform-specific upgrade codes teaches Group Policy Management Editor not to mix 32 and 64-bit packages when updating. Example: MS Office 2016 has something like {00160000-008C-0000-0000-0000000FF1CE} for 32-bit version and {00160000-008C-0000-1000-0000000FF1CE} for 64-bit.

If you want some fancy ones to mark the official line of 32 and 64-bit OpenVPN MSI packages, it is time to set them now.

Copy link
Contributor

@selvanair selvanair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know little about MSI or WiX so only randomly looked at a few places -- great job indeed!
It may be hard to get all cross-dependencies and nuances about upgrading from previous NSIS install right in the first round, so we can merge, test, fix, repeat, I guess.

windows-msi/Makefile Outdated Show resolved Hide resolved
windows-msi/msi.wxs Show resolved Hide resolved
windows-msi/msi.wxs Show resolved Hide resolved
@selvanair
Copy link
Contributor

And one more thing: If the service or GUI is running is it stopped to allow for file updates or does the user have to intervene? Quitting the GUI is easy for the user, but at least for the service we should stop and restart as/when required. Couldn't figure how/whether that's done.

@rozmansi
Copy link
Contributor Author

And one more thing: If the service or GUI is running is it stopped to allow for file updates or does the user have to intervene? Quitting the GUI is easy for the user, but at least for the service we should stop and restart as/when required. Couldn't figure how/whether that's done.

Services are authored to stop on component uninstall and start on component install. (But, I'll double check that.)

The applications (i.e. openvpn-gui.exe) does not. Fortunately, the MSI has files-in-use detection out-of-the-box. The user will be prompted that an "OpenVPN GUI" application is opened and is preventing some files to update. The user will then be able to close the application her/himself and choose Retry, or choose to proceed with installation and restart computer later. Installer Service saves the files it was unable to update and updates them on next restart.

@selvanair
Copy link
Contributor

Services are authored to stop on component uninstall and start on component install. (But, I'll double check that.)

That would work for updates or fresh install but not for "upgrade" from NSIS installed version, would it? Note that even if services are not getting updated, openvpnserv2 has to be stopped to terminate any running openvpn.exe.

In case of upgrading from nsis, if service is running the install may just fail or lead to a broken setup? I don't yet have a setup to build and test this, so just guessing.

Triggering the nsis uninstall script if previous install detected may be an option. As msi installer will be only for 2.5 (?) looking for a pre 2.5 openvpn.exe, and, if found, uninstall first may also be an option?

For GUI, prompting the user to stop it or reboot later is fine.

@rozmansi
Copy link
Contributor Author

rozmansi commented Nov 16, 2018

For a better illustration...

  1. Installed NSIS OpenVPN 2.4.6 on a vanilla computer and configured a VPN connection.
  2. Connected to VPN.
  3. Launched the new MSI install to update.

As expected, I get the following prompt.
image

(OpenVPN Deamon process is openvpn.exe)

Now I can choose to terminate the VPN connection and close the OpenVPN GUI myself before updating. Or, proceed with the update and restart computer later.

  1. Ignore the warning.
  2. The update proceeds. When it stops the interactive service, the VPN connection is terminated, OpenVPN GUI pops-up to warn that.
  3. After the update both openvpn.exe and openvpn-gui.exe were updated in C:\Program Files\OpenVPN\bin (verified by signatures), and a reboot was not required. The OpenVPN GUI is still running in the system tray. This puzzles me, because it works too good to be true.

This is the log of the update: OpenVPN-install.log
(BTW: When using EXE installer, the msiexec.exe is launched with /l* "%TEMP%\OpenVPN-install.log". Just type the %TEMP%\OpenVPN-install.log in Windows Explorer or the Run... dialog and you should get your install log.)

@selvanair
Copy link
Contributor

selvanair commented Nov 16, 2018

3. After the update both openvpn.exe and openvpn-gui.exe were updated in `C:\Program Files\OpenVPN\bin` (verified by signatures), and a reboot was not required. The OpenVPN GUI is still running in the system tray. This puzzles me, because it works too good to be true.

Interesting.. I guess it must be moving the original gui exe to a temp location and let it continue running. Renaming files in use is supported by ntfs (though the file explorer UI may not allow it). What executable path and name are shown in the running process properties?

Updating from a 2.4.4 or older NSIS install to 2.4.5 or 6 should show this clearly --- the running GUI should report a version of 11.9.0.0 in its settings->About menu but the newly installed file will show 11.10.0.0. The GUI version did not change between 2.4.5 and 2.4.6.

@rozmansi
Copy link
Contributor Author

  1. Installed 2.3.11, openvpn-gui.exe version 10
  2. Configured and established a VPN connection.
  3. Launched OpenVPN 2.4.6 MSI update over the VPN connection: the MSI file was located on the share accessible via VPN connection.
  4. Update warned about the files-in-use. I clicked ignore.
  5. Update finished. No prompt for a restart. Files in C:\Program Files\OpenVPN were updated. VPN connection was still established. openvpn-gui.exe still running (version 10). The Image path name and Command line of the openvpn-gui.exe and openvpn.exe processes in the Task Manager did not change.
  6. Closing and restarting openvpn-gui.exe the version 11.10 showed up.

This confirms @selvanair's assumptions. The update indeed allows the established VPN connections to persist until the processed are recycled. This means very good news for updating remote computers over an OpenVPN connection.

Test machine: up-to-date Windows 8.1 Pro.

Now I need to use even older version, to test the TAP driver update.

Copy link
Contributor

@selvanair selvanair left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means an update of the service will require a reboot (or a manual service restart if the user knows how to do that) for the update to take effect, right? Could lead to inconsistencies if the user just restarts the GUI so that an updated openvpn.exe will get used with an older interactive service.

Does it show a warning that updates will be effective only after a system restart or some such or can we provide an optional service restart at the end of the installation?

@rozmansi
Copy link
Contributor Author

rozmansi commented Nov 23, 2018

Meanwhile, I have tested and confirmed that live updating works on Windows 7 too.

Yes, Selva... This currently means that user is responsible for restarting OpenVPN (daemon, interactive service, GUI, and/or openvpnserv2.exe) or completely restarting the computer to actually start using the up-to-date version.

We have two opposing design options now:

  1. Don't restart anything on update:
    Pros: allows updating over live VPN connection
    Cons: requires restarting to complete the update

  2. Close/stop OpenVPN - update - run/start OpenVPN
    Pros: no additional user intervention to complete the update required
    Cons: live VPN connections are terminated on update

Initially, I was targeting at option 2. However, after observing that live update is possible, I started leaning towards option 1.

My last patch at [openvpn-devel] mailing list combined with the last patch in this PR demonstrate that it is possible to detect live VPN connections in the update process.

I am thinking about challenges if we take hybrid approach: When live VPN connections are detected, user is given a choice: "Do you want to preserve established VPN connections? (Note: You will need to restart OpenVPN later to switch to the new version.)" If there are no live connections or user chooses No for the previous question, the MSI does stop-update-start; otherwise update only.

@selvanair
Copy link
Contributor

I am thinking about challenges if we take hybrid approach: When live VPN connections are detected, user is given a choice: "Do you want to preserve established VPN connections? (Note: You will need to restart OpenVPN later to switch to the new version.)" If there are no live connections or user chooses No for the previous question, the MSI does stop-update-start; otherwise update only.

I think this is okay, but we could be a little more helpful by saying the service also need to be restarted and how to do that. Alternatively just say that a reboot is required for changes to take effect (if service was updated) --- Windows users are used to rebooting anyway :)

@mattock may have better suggestions.

@mattock
Copy link
Member

mattock commented Nov 26, 2018

I think the two options suggested by @rozmansi are for different audiences/use-cases:

  1. Enterprises / upgrading remote nodes managed via VPN links: you don't want to loose VPN connectivity during upgrades.
  2. End-users / upgrading the local computer: you want to avoid having to manually restart services or reboot after OpenVPN upgrade.

A hybrid approach would be best of course. If it is difficult to implement then let's think about which one of the above we should choose. There are good arguments for both. That said, enterprise sysadmins are able to figure out ways to work around caveats in option 2, whereas typical end users might be caught badly off-guard by 1.

@rozmansi
Copy link
Contributor Author

The current implementation of MSI packets was the 1st option already. Because it was the simplest to implement. :)

I have changed the MSI package to:

  1. Attempt to stop OpenVPN GUI before commencing ExecuteAction. Since this action is authored in the InstallUISequence, it'll execute only for interactive MSI sessions. The silent (GPO) installs are not affected. Furthermore, since it launches non-elevated and as the current user, it can send the WM_CLOSE signal to modern non-elevated running OpenVPN GUI windows only. Therefore, the MSI will not close the old OpenVPN GUI when updating a prehistoric OpenVPN installation.

  2. Stop all OpenVPN services before updating.

  3. The interactive service will start back after the update. The legacy and openvpnserv2.exe will remain stopped.

  4. When the user clicks "Close" on the final MSI page, the OpenVPN GUI is relaunched. Again, this happens only for interactive MSI sessions. Furthermore, it is launched only when the "Launch on User Logon" feature is selected.

One more thing about services: The Microsoft Installer is designed to install, configure and start services in a constant way = update resets everything back to defaults. Stock MSI actions are pretty limited. It is impossible to use a variable for the required service state and startup. Hence, the legacy and the openvpnserv2.exe will always stop and reset to a manual start on OpenVPN updates. This is a regression from the NSIS based updates users of openvpnserv2.exe service might not fancy.

I am desperately trying to find time to add a new set of custom actions to detect which services were running before the update, what startup type they had, and to start and configure them the same after the update is complete. Much like the NSIS installer does now. It's a lot of work and basically means reinventing the wheel (in other words: replacing entire MSI service management by a custom one).

Unless we can afford to have the openvpnserv2.exe users start and set for auto-start the openvpnserv2.exe manually after each OpenVPN update. (in other words: We don't care. If you want it, it's still there, start it yourself.)

BTW, a transform can be authored for those users to have it applied at installation/update time to set the openvpnserv2.exe to start on install/update and set its startup type to auto-start. Or, have a batch file to activate the service for them.

Or, we could simply author the MSI to start and set for auto-start the openvpnserv2.exe too, but demote this feature to level 3 (not selected by default). Of course, the warning should be displayed: "If you choose to install this feature all your existing .ovpn connections will attempt to connect immediately." The feature selection is preserved across the updates. So, users of openvpnserv2.exe will need to select this feature on the initial installation only; and those who do not want this service, will absolutely have to not select it to install.

Just thinking aloud...

@selvanair
Copy link
Contributor

selvanair commented Nov 27, 2018

If it wont be too much work, an option is to check whether the service is running and if so set a registry key named autostart_config_dir (only if absent) to the same value as config_dir. Else leave it blank. If that's easier to do, we can change the service code to auto start configs in that directory and let the service start type to auto by default. This check is needed only for the first move (from NSIS to MSI) --anyway, we are already doing a some housekeeping jobs during install in that case.

I never liked openvpn service autostarting all configs in the same central config folder that the GUI also reads. We should have had a separate location for such configs or a way of selecting which configs to autostart. This may be an opportunity to do so.

@rozmansi
Copy link
Contributor Author

If it wont be too much work, an option is to check whether the service is running and if so set a registry key named autostart_config_dir (only if absent) to the same value as config_dir. Else leave it blank. If that's easier to do, we can change the service code to auto start configs in that directory and let the service start type to auto by default. This check is needed only for the first move (from NSIS to MSI) --anyway, we are already doing a some housekeeping jobs during install in that case.

This is not too much work and it would provide a seamless update for openvpnserv2.exe users indeed. Of course, it will introduce an inconsistency in folder layout for upgraded vs. fresh installs. I wonder what will cause more head-scratching to sysadmins:

  1. Getting a different folder layout for upgraded vs. fresh installs: different autostart_config_dir equals different behaviour of openvpnserv2.exe.
  2. Having to read the "Breaking Changes in v2.5" chapter and moving their auto-start .ovpn files from C:\Program Files\OpenVPN\config to C:\Program Files\OpenVPN\config-autostart.

In the long term, I think it is cleaner and more consistent we always set autostart_config_dir to C:\Program Files\OpenVPN\config-autostart (and preserve this registry value on future updates), while instructing users of openvpnserv2.exe they need to move their auto-start .ovpn files to the newly introduced folder - or - set the autostart_config_dir to C:\Program Files\OpenVPN\config.

Another problem with openvpnserv2.exe is .NET Framework dependency. I am researching how to disable the openvpnserv2.exe feature when .NET Framework is absent before authoring MSI to start this service and set it to auto-start. When MSI installs a service and tries to start it, but the service fails to start, the entire MSI session is considered a failure and is rolled back.

I never liked openvpn service autostarting all configs in the same central config folder that the GUI also reads. We should have had a separate location for such configs or a way of selecting which configs to autostart. This may be an opportunity to do so.

I totally agree. I vote for the separate config folder approach:

  • A similar solution is used on Linux already: /etc/openvpn/client and /etc/openvpn/server
  • It is simpler to implement.

(Note that using two separate config folders means user needs to move/duplicate all external files referenced in .ovpn by the relative path too. We could keep the same config folder but have a .ovpn and .ovpn-auto config files. Unfortunately, Windows Explorer makes it difficult to change the file extensions by default. We could change the openvpnserv2.exe to pick only *-service.ovpn files, while openvpn-gui.exe ignores them. Both proposals are $100 solution for a ¢2 problem.)

@mattock
Copy link
Member

mattock commented Nov 27, 2018

👍 to having a separate folder for automatically started config files. I'm also not against having separate config directories for client and server configs, as long as there are no implicit assumptions about auto-starting based on type. For example, my wife has an always-on client connection to her workplace, so autostarting is not just a thing for servers. But it could get tricky if we also need to distinguish between client, server and autostart configs.

@rozmansi
Copy link
Contributor Author

Dividing the config folder into client/server on Windows would only bring confusion. Heck, I don't even see the rationale behind dividing openvpn@.service into openvpn-client@.service and openvpn-server@.service on Linux.

  • C:\Program Files\OpenVPN\config + C:\Program Files\OpenVPN\config-auto, or
  • C:\Program Files\OpenVPN\config + C:\Program Files\OpenVPN\config\service

...comes to my mind. The later would still allow OpenVPN-GUI to run a .ovpn from config\service manually, should a user wish to stop the service and connect manually. While preventing openvpnserv2.exe from start connecting immediately when user upgrades with the MSI setup.

@selvanair
Copy link
Contributor

selvanair commented Nov 27, 2018

I agree with not distinguishing server and client configs. Very few people run server on Windows and they can fend for themselves.

As for config-auto vs config\service, I prefer the former -- the latter where the GUI sees these configs brings us back closer to the current state: users may try to start those configs from the GUI, may even succeed (if there are enough tap adapters) and cause the auto-started one to disconnect or the two to usurp each other back and forth.

What I had in mind was something like this (using some key and folder names for concreteness, not saying these are the best names)

if regkey autostart_config_dir is present 
    do nothing
else if fresh install
    set reg key autostart_config_dir = C:\ProgramFiles\OpenVPN\config-auto
else if OpenVPNService is Running
    set reg key autostart_config_dir = C:\ProgramFiles\OpenVPN\config

Then update the service code to use autostart_config_dir reg key to find the config file locations and ignore if its blank, missing, unreadable, empty etc. Also update NSIS installer to create this reg key if we distribute the updated service with future 2.4.x releases.

The only real downside is what @rozmansi mentioned: the change of config location for new installs. That's the price to pay for separating the two kinds of configs.

As for users who want to stop the auto-start, they should either move the configs away or rename the folder or the registry key. Stopping the service is not a good method (except as a stopgap measure), as upgrades will bring the service back on.

BTW, "auto" may not be the right word to describe these configs -- in the GUI also we can have some configs to "autostart" so the meaning of auto is context-dependent. That said, I don't have a better word -- "service", "daemon", "always-on", "prestarted" ? -- and am ok with "auto".

@mattock
Copy link
Member

mattock commented Nov 27, 2018

On Linux there was solid reasoning behind separating client and server configs, but I've forgotten the details. It probably had to do with init script / systemd unit file ordering on boot, but I could be mistaken. On Windows I think it would just confuse people. For me config-auto seems reasonable. The pseudo-code by @selvanair looks good.

@selvanair
Copy link
Contributor

@rozmansi To avoid your concern about folder name depends on upgrade/fresh-install issue, we could copy the contents of config to config-auto when appropriate: key not found but service running, so we add the key and copy the contents of config. Then the reg key value also stays independent of fresh install or upgrade.

Documenting the change becomes easier that way.

@rozmansi
Copy link
Contributor Author

@selvanair Can you do the openvpnserv2.exe part, please? And I do the MSI part following your recommendations.

@selvanair
Copy link
Contributor

selvanair commented Nov 28, 2018

Looking at openvpnserv2 -- it reads both 32 bit and 64 bit registries and starts configs in both (using appropriate exe_path found in each place). Is that what is expected or can we just require 64 bit OpenVPN installation on 64 bit machines?

Else the installer doing 64 bit install will have to also look for existing 32 bit install and update its registry, copy config folder etc..

@mattock: any suggestions?

@rozmansi
Copy link
Contributor Author

The MSI packages will install binaries according to the next matrix:

Windows Architecture Driver Native binaries[*] openvpnserv2.exe
x86 x86 x86 AnyCPU
x64 x64 x64 AnyCPU
ARM64 ARM64 x86 AnyCPU

[*] openvpn.exe, openvpn-gui.exe, openvpnserv.exe, required DLLs...

Therefore, we can't just always expect 64-bit OpenVPN installation on 64-bit Windows. We will shoot ourselves in the foot when we release ARM64 version. What we can assume is, no system shall have both 32 and 64-bit versions of binaries installed at once.

We don't have MinGW, OpenSSL and other libraries available for ARM64 yet and will have to use x86 user-space native binaries for the time being. However, we will hit a problem when we go out with an all-ARM64 package: updating the ARM64/x86 Frankenstein installations will require migrating config files from C:\Program Files (x86)\OpenVPN\config to C:\Program Files\OpenVPN\config, and registry keys from Wow6432Node key.

@selvanair
Copy link
Contributor

What we can assume is, no system shall have both 32 and 64-bit versions of binaries installed at once.

Okay, let's go with that but leave the current logic of scanning and starting configs based on both normal and Wow6432Node keys. The new version of service will look for autostart_config_dir key (is that the name we settled on?) in both nodes. Makes it very simple.

We support cases were Wow6432Node key point to a 64 bit installation (exe_path, config_dir etc.) so there could be some corner cases which admins will have to fix manually.

I'm not worried about ARM as there are no existing (NSIS) installations on that platform so we start from a clean slate and the new reg key and config folder will always exist (empty or not). But your point about valid 32 bit installations on 64bit is good to keep in mind.

@rozmansi
Copy link
Contributor Author

rozmansi commented Nov 28, 2018

Okay, let's go with that but leave the current logic of scanning and starting configs based on both normal and Wow6432Node keys. The new version of service will look for autostart_config_dir key (is that the name we settled on?) in both nodes. Makes it very simple.

autostart_config_dir and C:\Program Files\OpenVPN\config-auto is OK with me.

@selvanair
Copy link
Contributor

Agreed.

selvanair added a commit to selvanair/openvpnserv2 that referenced this pull request Nov 28, 2018
This allows to isolate autostarted configs from those accessed
through the GUI into separate directories.

This also allows setting the service start type to default to Auto
(not manual) without unexpectedly starting profiles in config_dir.

If the registry value does not exist or is empty it is ignored. Otherwise
it must point to a directory that exists. The installer should set up
a default value and default directory.

See
OpenVPN/openvpn-build#141 (comment)
and subsequent discussion.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
selvanair added a commit to selvanair/openvpnserv2 that referenced this pull request Nov 29, 2018
This allows to isolate autostarted configs from those accessed
through the GUI into separate directories.

This also allows setting the service start type to default to Auto
(not manual) without unexpectedly starting profiles in config_dir.

If the registry value does not exist or is empty it is ignored. Otherwise
it must point to a directory that exists. The installer should set up
a default value and default directory.

See
OpenVPN/openvpn-build#141 (comment)
and subsequent discussion.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
selvanair added a commit to selvanair/openvpnserv2 that referenced this pull request Nov 29, 2018
This allows to isolate autostarted configs from those accessed
through the GUI into separate directories.

This also allows setting the service start type to default to Auto
(not manual) without unexpectedly starting profiles in config_dir.

If the registry value does not exist or is empty it is ignored. Otherwise
it must point to a directory that exists. The installer should set up
a default value and default directory.

See
OpenVPN/openvpn-build#141 (comment)
and subsequent discussion.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
@selvanair
Copy link
Contributor

selvanair commented Nov 29, 2018

See PR #142 and PR 10 of OpenVPN/openvpnserv2

Based on this patch, I update my previous pseudo code to

create C:\Program Files\OpenVPN\config-auto if not present and add a README to it

if reg value autostart_config_dir is not present
    add reg value autostart_config_dir = C:\Program Files\OpenVPN\config-auto
    if OpenVPNService is running or is set to one of the automatic modes
         copy contents of $config folder to $config-auto folder
else
    pass

Some distributions of GNU utils for Windows install gunzip as a symlink to
gzip.exe (e.g. Git for Windows).  Such symlinks are not supported within
cmd.exe shell. The building script was upgraded to use `gzip.exe -d`
instead. Although Git for Windows installs bunzip2.exe (as a clone of
bzip2.exe), an analogous `bzip2.exe -d` approach was adopted.

Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
At the time developing the MSI packaging, I am using same Windows computer
for digital signing and packaging. I have evolved three batch files to
assist me. If somebody else might find them useful, or merely as a source of
inspiration, I am including those in the distribution.

Signed-off-by: Simon Rozman <simon@rozman.si>
When using BSD tar.exe or tar.exe without GZip/BZip2 support, we must use
piping. This batch explicitly instructs tar.exe to use TAR stream from
stdin.

Note: Only GNU tar.exe is tested which this commit documents.

Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
This prevents repeating `msiexec /fu` calls at user logon issue.

The Active Setup component version is incremented when product
transitions from uninstalled to installed state only now. This means
that uninstalling OpenVPN and then reinstalling same version of OpenVPN
it will still bump the Active Setup component version and trigger
one-time `msiexec /fu` call on first user logon after the
reinstallation.

Signed-off-by: Simon Rozman <simon@rozman.si>
WScript.Shell's method RegDelete is silly enough to throw an error when
a registry value it is trying to delete something that does not exist.
This is not really an error condition as the state we are trying to
achieve is already achieved.

In case there is no StubPath value in the registry, PublishActiveSetup()
fails in the uninstall phase preventing OpenVPN uninstallation.

Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
When there are no TAP-Windows6 adapters present, the tap0901 driver's
service is not (and cannot be) started. This prevents all OpenVPN
services from starting. The no-TAP-Windows6/Wintun adapters present
situation is checked at run-time.

Signed-off-by: Simon Rozman <simon@rozman.si>
The TAP-Windows6 certificate injection will be handled within the oncoming
MSM merge module.

Signed-off-by: Simon Rozman <simon@rozman.si>
The TAP-Windows6 driver installation will be handled by the oncoming MSM
module.

Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
The WiX files were updated to adopt changes and renaming that took place
in openvpn repository.

Signed-off-by: Simon Rozman <simon@rozman.si>
The libopenvpnmsica.dll has been upgraded to support arbitrary hardware ID
network adapter creation on install.

Signed-off-by: Simon Rozman <simon@rozman.si>
There's no "Ethernet" in Wintun. And there might be no "Ethernet" in
TAP-Windows6 either.

Signed-off-by: Simon Rozman <simon@rozman.si>
Return msiDoActionStatusSuccess (i.e. "Action completed successfully.")
rather than zero default, which MSI interpretes as msiDoActionStatusNoAction
(i.e. "Action not executed.").

See-also: https://docs.microsoft.com/en-us/windows/win32/msi/return-values-of-jscript-and-vbscript-custom-actions
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Simon Rozman <simon@rozman.si>
When MSI detects user is using OpenVPNService (the service is running or set
to auto-start), it marks OpenVPN.Service for install. If the config-auto
subfolder does not exist yet, it moves all files from config subfolder to
config-auto. This is a one-time migration of auto-start config files.

Another feature of the MSI installer is a thorough cleanup of all the NSIS
files and registry settings before install.

So far so good. But (there always is a "but", otherwise you wouldn't be
reading this, would you?), both features combined explode!

The RemoveFiles removes the NSIS' config/README.txt file first, while the
MoveFiles action already has a list of files to move from config to
config-auto. With config/README.txt already gone, MoveFiles fails.

I have decided not to clean any NSIS leftover files from the config
subfolder. The README.txt file is overwriten by the same-named MSI supplied
file anyway. And the config subfolder is kind of sacred => it contains user
authored files. Moving them to a different folder is bold enough.

Signed-off-by: Simon Rozman <simon@rozman.si>
@mattock
Copy link
Member

mattock commented Jun 24, 2020

I was able to build MSI packages that use the tap-windows6 MSM. Installation with default settings on a computer with no OpenVPN installations (=uninstalled NSIS beforehand) worked on these platforms:

  • Windows 7 64-bit
  • Windows Server 2016 64-bit
  • Windows 10 32-bit

It failed on Windows 10 arm64 due to tap-windows6 and wintun issues. I ran out of time before being able to debug that further. It could be a problem in my build, or not. I'll fill in more details later. But the "more important" platforms seem to be ok.

For some reason Windows Server 2016 informed me that the computer needs a restart to complete the installation. Not sure why.

My builds are here:

@mattock
Copy link
Member

mattock commented Jul 3, 2020

The MSI installers were produced and "seem to work" just fine.

@mattock mattock merged commit d598bac into OpenVPN:master Jul 3, 2020
@rozmansi rozmansi deleted the feature/windows-msi branch August 11, 2020 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants