Using Add-Type to load Octopus.Client type from nuget package errors!?

reliability
(Emil) #1

Hi Guys,

I am looking for best practice advice on how to use Octopus.Client nuget package as a dependency on my own powershell module and download it on demand (I can pin the version via packages.config including dependencies).

My question is what config I can have for Octopus.Client assembly to help it find it’s dependencies once all are downloaded? I use packages.config with following nuget command:
nuget install -ExcludeVersion -OutputDirectory .
to download Octopus.Client and it’s dependencies and they all end up in their individual package folders…

Thanks,
Emil

(Kartik Gupta) #5

Hi Emil

Thanks for reaching out.

You can use the Octopus.Client.dll as bundled with your Octopus Server. Have a look at the Using Powershell part of the documentation on Octopus Client. This way you don’t need to bundle the dependencies in your Powershell script.

You can also have a look at trying the Install-Package Octopus.Client as per the docs above.

Hope this helps!

Cheers,

Kartik

(Emil) #6

Hi Kartik,

I am aware of this, however I need to decouple the PowerShell module from the default server installlation path of the Octopus.Client to be able to run the module anywhere for example locally during development and on other target machines where tentacles exist…

If I depend on the default Octopus server installation path that means I can only run it in the context of the default worker pool that is running on the Octopus server.

In other words I want to use the Octopus.Client package but the problem I get are:

  • it’s dependencies - I solved this by using packages.config with following content to pull down the Octopus.Client and it’s dependancies:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
    <package id="System.ComponentModel.Annotations" version="4.5.0" />
    <package id="Newtonsoft.Json" version="11.0.1" />
    <package id="Octodiff" version="1.2.1" />
    <package id="Octopus.Client" version="7.0.0" />
    </packages>

  • second issue is how to tell Octopus.Client where to find it’s dependencies - I have partially solved this, but only for the net45 binary by using Octopus.Client.dll.config to define the probing paths for the dependencies like this:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="..\..\..\Newtonsoft.Json\lib\net45;..\..\..\Octodiff\lib\net40;..\..\..\System.ComponentModel.Annotations\lib\net461"/>
</assemblyBinding>
</runtime>
</configuration>

for the dotnet core build I have tried using both Octopus.Client.dll.deps.json and Octopus.Client.runtimeconfig.json to point to the deplendencies but i had no success and it will be great of anyone can point me in the right direction.

I am also open to other solutions that will make my PowerShell module portable and decoupled from the Octopus Server default installation path for the Octopus Client?

Thanks for your help!
Emil

(Kartik Gupta) #7

Hi Emil,

Thanks so much for getting back to us and apologies that the last response didn’t address your concern.
The Octopus.Client.dll shouldn’t really have any dependencies. We have raised this bug https://github.com/OctopusDeploy/OctopusClients/issues/453 and are hoping to have a fix out soon.

However, you can still use the current nupkg, the only dll that you would need to reference in your PowerShell is the Octopus.Client.dll. You can just ignore the other dependencies as noise.

As far as best practice is concerned, your approach sounds quite reasonable for the net45 version, though you shouldn’t need the changes to Octopus.Client.dll.config.

At this point it’s not commonly used with PowerShell Core though we can’t think of any reason why it shouldn’t work.

You shouldn’t see any issues after referencing just the Octopus.Client.dll. But if you do, please do not hesitate to reach out to us.

Hope this helps!

Cheers,
Kartik

(Emil) #8

Hi Kartik,

I am not sure if I have hit the loading bug, however I realised there is a simple rule of thumb that should be made clear in your documentation about using the packaged Octopus.Client:

  • When running PowerShell Core load from \lib\netstandard2.0\ and…
  • When running PowerShell prior version 6.0 load from \lib\net45\

I’ll backtrack the context of my issue, it all started because I wasn’t able to load the Octopus.Client from the v7.0.0 package as I was getting dependency load errors!

For example trying to load the client type from the package:

try{
     Add-Type -Path "C:\Temp\octopus.client.7.0.0.nupkg\lib\net45\Octopus.Client.dll"
}catch{
     $_.Exception.LoaderExceptions | %{Write-Error $_.Message}
} 

I was getting the following Loader Exceptions:

: Could not load file or assembly 'System.ComponentModel.Annotations, Version=4.2.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
+ CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

: Could not load file or assembly 'Newtonsoft.Json, Version=11.0.0.0, Culture=neutral,
PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The system cannot find the file specified.
+ CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

You pointed me to the bug-fix Pull Request, however in has the fix made it in the package on Nuget.org and in which version?
I have just tried latest 7.1.0, which was pushed about 8 hours ago, and it seems to work just fine

The steps I took to try the latest Octopus.Client 7.1.0:

  • In C:\Temp I pulled the package with the nuget command: nuget install -ExcludeVersion -OutputDirectory . and the packages.config in the folder has the follwing content:
<?xml version="1.0" encoding="utf-8"?>
<packages>
    <package id="Octopus.Client" version="7.1.0" />
</packages>
  • Tried to load the Octopus.Client when running PowerShell v5.x:
    Add-Type -Path 'C:\Temp\Octopus.Client\lib\net45\Octopus.Client.dll'
    It loads just fine without a problem :+1:

However, there is a little gotcha - loading the dotnetcore type from when NOT running PowerShell Core it will manifest the same load exception errors :smile:

I guess you could update the documentation on this page here:
Loading Octopus.Client

I hope that helps another poor soul and may save some hair pulling :smile:

Many Thanks,
Emil

(Matt Richardson) #9

Hi Emil

Thanks for the detailed reply - it definitely makes our life easier :slight_smile:. I’ve picked up this ticket from Kartik to keep the ball rolling.

We’ve got a docs update PR in progress, where I’ve tried to clear up the usage, and make it easier to get started. It’d be good to get your thoughts about whether I’ve succeeded in my goal there. (Equally, if you feel you’ve invested enough in this, I wont be offended if you say no.)

The dependency load issues that you faced should no longer be a problem - sorry you ran into them. As you’ve found, that is fixed in 7.1.0, which is up on nuget.

If you use Install-Package, you can avoid having to setup a packages.config, and (in theory) also avoid having to have nuget.exe handy.

One of the fun parts of this though is that nuget.exe doesn’t work xplat - it works on windows, but not on linux etc. Install-Package does though, so should be good.

Hope that helps!

Cheers,
Matt

(Emil) #12

Hi Matt,

You’ve done great job on updating the docs - this is exactly what it was missing I guess when I run into my issue. It also gives much needed info about the sync & async API usage of the Octopus.Client :+1:

I did try using Install-Package indeed but I ended up in a loop of errors due to having a number of password protected private repos and because I didn’t use source argument. This is when I switched to the nuget command line…

I do agree Install-Package is the right way as it offers the cross platform compatibility :+1: and now with docs updated to include the -source https://www.nuget.org/api/v2 anyone following the docs will not get into this kind of trouble :smile:

Great work - thanks for prompt docs update!
Emil

(Matt Richardson) #13

Hi Emil

Thanks for getting back to me on that - appreciate it.

Glad we got it all sorted. Happy deployments!

Cheers,
Matt