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

Using Invoke-ChocolateyBoxstarter to install .NET 4.7 causes Boxstarter to do a Windows update #293

Closed
colin-sim opened this Issue Nov 27, 2017 · 21 comments

Comments

Projects
None yet
4 participants
@colin-sim
Copy link

colin-sim commented Nov 27, 2017

I have been able to reproduce this issue on a bare Windows 8.1 64-bit virtual. The machine has the following applied to it:

  • Install Chocolatey 0.10.5
  • Install Boxstarter 2.10.3
  • UAC remains on
  • Windows updates disabled

I run the following, which installs .NET 4.7; however, Boxstarter starts doing a Windows update while this Chocolatey package is being installed - not desirable. This behaviour is also observed when invoking Boxstarter via the Install-BoxstarterPackage cmdlet but only if .NET 4.7 is the last package.

Import-Module Boxstarter.Chocolatey
Invoke-ChocolateyBoxstarter dotnet4.7

The console output while .NET 4.7 is installed is:

Installed/updated chocolatey-windowsupdate extensions.
The install of chocolatey-windowsupdate.extension was successful.
Software installed to 'C:\ProgramData\chocolatey\extensions\chocolatey-windowsupdate'
[NuGet] Installing 'KB4019990 1.0.0'.
[NuGet] Successfully installed 'KB4019990 1.0.0'.

KB4019990 v1.0.0 (forced) [Approved]
kb4019990 package files install completed. Performing other installation steps.

  • Boxstarter starting Checking for updates...+ Boxstarter starting Checking for updates...

Starting windows update serviceStarting windows update service

@ferventcoder

This comment has been minimized.

Copy link
Member

ferventcoder commented Nov 27, 2017

Looks like starting Windows Update Service triggers this. Packages that install MSUs will typically ensure Windows Update service is turned on.

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Nov 27, 2017

@ferventcoder thanks for the feedback, I thought it may have been something long those lines. However, I don't believe that's the complete picture because:

  1. The Windows update are only applied when installing .NET 4.7, which does depend on MSUs; however, when I install .NET 4.6.1 (for example) that also has dependencies on MSUs, Boxstarter doesn't install Windows updates.
  2. Boxstarter doesn't always start applying Windows updates when .NET 4.7 is installed, only if .NET 4.7 is the last thing it installs, i.e. say if I installed .NET 4.7 followed by 7zip, then Boxstarter doesn't apply Windows updates.
  3. I've noticed that the .NET 4.7 package has a new dependency on chocolatey-windowsupdate.extension but I don't believe that's what's triggering the update for the reasons mentioned previously.

Furthermore, if turning on Windows Update Service is what's triggered the Windows Updates shouldn't the updates be applied in the background service as it usually does?

BTW I've turned of the Windows updates, i.e. the Windows auto-updater. I have not turned off the Windows Update service. Still feels like a bug in Boxstarter.

@mwrock

This comment has been minimized.

Copy link
Member

mwrock commented Nov 27, 2017

The only reason why Boxstarter would perform a windows update is if it is being told to via Install-WindowsUpdate There is no logic in Boxstarter that would call windows update on its own. You might dig into the .Net packages and see if they are explicitly calling that.

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Nov 27, 2017

Isn't Install-WindowsUpdate a Boxstarter function? How would the .Net package know to call that function?

@mwrock

This comment has been minimized.

Copy link
Member

mwrock commented Nov 27, 2017

Boxstarter starting Checking for updates...+ Boxstarter starting Checking for updates indicates Install-WindowsUpdate was called. It is a boxstarter function. Do you mind sharing the package or script that is being passed to Invoke-ChocolateyBoxstarter @colin-sim ?

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Nov 27, 2017

@mwrock The Chocolatey package is dotnet4.7.

dotnet4.7 has a dependency on chocolatey-windowsupdate.extension package, which contains a function Install-WindowsUpdate. That function is used to apply a specific update required by a package. I believe Boxstarter is interpreting that call for a function of it's own (i.e. Boxstarter's implementation of Install-WindowsUpdate instead of the function declared in the chocolatey-windowsupdate.extension package.

@ferventcoder

This comment has been minimized.

Copy link
Member

ferventcoder commented Nov 27, 2017

@colin-sim I think you are on to something

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Nov 29, 2017

Now that we know what the problem is, does anyone have any suggestions on how I might be able to workaround this issue or fixing it in Boxstarter?

@ferventcoder

This comment has been minimized.

Copy link
Member

ferventcoder commented Nov 29, 2017

Scope. The naming of the function is understandable into why there would be a collision. Having the package be able to call back out to Boxstarter functions feels like a scope thing that could be corrected. As far as how exactly... that I'm not sure on. Since you can't control the scoping issue in the packages themselves, control the scoping at the Boxstarter level.

Alternatie ideas:

  • Rename that function in boxstarter to something with Boxstarter in the name - may not be feasible or may be a breaking change.
  • Rename that function in the Chocolatey package and update all references in other packages - probably not feasible, would result in lots of churn and broken packages.
  • Pre-install .NET 4.7 outside of Boxstarter or kb4019990 - not a good workaround
  • Accept the Windows updates - probably not something you are keen to as you had it turned off in the first place
  • Other ideas

Tangent - why isn't the Boxstarter one called Install-WindowsUpdates? That seems more appropriate given it will install zero or more.

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Dec 1, 2017

@ferventcoder Thanks for your input. I agree with all your suggestions and feel the best approach would be to scope the Boxstarter functions into it's own namespace. Since namespaces don't exist in PowerShell (not that I know of in a conventional sense anyway) I would suggest the best approach is to rename all Boxstarter functions to include Boxstarter in its name. It is conceivable that other function names in the Boxstarter module to collide with other setup or install operations that comes from outside of Boxstarer.

@mwrock What do you think? I guess rename every Boxstarter function is no easy task and I'm sure will break everyone's existing setup/scripts.

@mwrock Can you think of a way to change the way Boxstarter scopes functions so that downstream scripts/operations do not invoke functions that's defined in Boxstarter?

@mwrock

This comment has been minimized.

Copy link
Member

mwrock commented Dec 3, 2017

Yeah. Ideally if I were writing this over again or embarking on a major version bump, I'd rename all functions to include "Boxstarter" not to mention making Install-WindowsUpdate plural. Scoping is tricky. Choco's PowershellService imports the boxstarter modules. If it imports them after extensions, that would explain why boxstarter is superseding the extension.

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Dec 4, 2017

So is there a workaround or is the only option one of ferventcoder's suggestions (none of which are ideal and kind of defeats of motivation to use Boxstarter in the first place - unless I've missed something)?

@ferventcoder

This comment has been minimized.

Copy link
Member

ferventcoder commented Dec 9, 2017

Maybe look at the parameters and if it is not what was being looked for, look for another function with the same name.

To do this though, Boxstarter would need to inspect the functions already being imported and then just rename them if they conflict. That way it would be aware when it receives a function with things that don't look quite right. The trick is seeing them during import since they are all getting imported at the same time.

@jberezanski

This comment has been minimized.

Copy link
Member

jberezanski commented Dec 10, 2017

Why is choco importing the boxstarter modules anyway?

@ferventcoder

This comment has been minimized.

Copy link
Member

ferventcoder commented Dec 10, 2017

Boxstarter comes as Chocolatey packages - I'm guessing that is why. Design of Boxstarter

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Dec 11, 2017

I'm initiating the choco package install via Boxstarter, e.g. Install-BoxstarterPackage dotnet4.7. This means the Boxstarter modules are already loaded and the Boxstarter.Chocolatey package contains a cmdlet Install-WindowsUpdate, which collides with the function defined in the chocolatey-windowsupdate module.

@jberezanski The fix I proposed in your repo will explicitly import the chocolatey-windowsupdate module before invoking the Install-WindowsUpdate cmdlet; hence, overriding the cmdlet that's already imported by Boxstarter.

@jberezanski How do you feel about that pull-request?

@jberezanski

This comment has been minimized.

Copy link
Member

jberezanski commented Dec 11, 2017

@ferventcoder OK, but this does not by itself explain why Boxstarter commands are automatically available in Chocolatey. After all, posh-git, for example, is also installed as a Chocolatey package and does not get loaded in each PowerShell session unless imported explicitly.

@mwrock I feel I'm missing something regarding Boxstarter architecture. Does it, perhaps, somehow share a single PowerShell instance with Chocolatey? Or does it install its PowerShell modules systemwide, to Program Files? Does it have to do so?

Ideally if I were writing this over again or embarking on a major version bump, I'd rename all functions to include "Boxstarter"

I know exactly how you feel; I now regret letting myself be talked out of prefixing the extension's functions when I originally developed it.

@colin-sim I responded to the PR. TL;DR: not thrilled about your suggestion, but I mentioned an alternative I would be willing to consider.

@mwrock

This comment has been minimized.

Copy link
Member

mwrock commented Dec 12, 2017

Just to clear up a few things in regards to boxstarter module installation and loading. When one installs boxstarter, the boxstarter modules are added to the SYSTEM PSModulePath and thus accessible from any shell. From inside a chocolatey package being installed via Boxstarter, Boxstarter uses the choco api vis choco.sll and not choco.exe. Upon instantiating the choco services, Boxstarter adds its own modules to chocolatey's powershell service to ensure they are loaded. It does this for 2 key reasons:

  1. The package may be running on a remote machine where the modules might not exist in PSModulePath
  2. Its important that the modules are loaded after the chocolatey powershell modules in order to override some behavior that enables boxstarter to discover pending reboots and reboot and restart correctly.

Admittedly this architecture has grown quite tangled particularly after choco evolved to a C# program. This was fairly straightforward when everything was powershell. If I were to rewrite Boxstarter today, I would not drive the API but would rather just shell out to an installed choco.exe. However there are already products that do just that so I'm not personally motivated to spend large quantities of free time rewriting or refactoring boxstarter :)

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Dec 12, 2017

@mwrock I agree with your sentiment. However, it may mean Boxstarter will/may not work (or at least as well as it should) moving forward; particularly, with changes in the Chocolatey community.

You mentioned other products that do similar things as Boxstarter, are you able to share this with me please. I'm in the process of re-writting my slimmed down version of Boxstarter that just forks off a process to run Chocolatey (as you've already stated) - obviously my version wouldn't be as feature rich as Boxstarter.

@mwrock

This comment has been minimized.

Copy link
Member

mwrock commented Dec 12, 2017

Well one is also my employer :) Chef. It has a chocolatey cookbook and it has pending reboot detection and the ability to reboot. I'm sure puppet has the same capabilities but @ferventcoder would know more about that. Both products are open source and free.

@colin-sim

This comment has been minimized.

Copy link
Author

colin-sim commented Dec 12, 2017

Oh... I was hoping for something much simplier like Boxstarter :S

jberezanski added a commit to jberezanski/ChocolateyPackages that referenced this issue Oct 8, 2018

KB3035131: work around Boxstarter issue
Make sure to call the correct Install-WindowsUpdate function.

chocolatey/boxstarter#293

jberezanski added a commit to jberezanski/ChocolateyPackages that referenced this issue Oct 11, 2018

KBs: work around Boxstarter issue
Make sure to call the correct Install-WindowsUpdate function.

chocolatey/boxstarter#293

@catsburg catsburg referenced this issue Oct 19, 2018

Merged

KB* packages - Work around Boxstarter issue #1129

5 of 10 tasks complete
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.