Deploy Topshelf Service fails when Octopus environment name contains spaces #1

Closed
danbarua opened this Issue Mar 8, 2013 · 22 comments

Comments

Projects
None yet
2 participants

danbarua commented Mar 8, 2013

As above.
I'm having a crack at it now but I'm new to Powershell...

danbarua commented Mar 8, 2013

It seems that if you call "service.exe install -servicename=My-Service-Name$My-Environment" then TopShelf ignores everything after the $ and ends up with a service name of "My-Service-Name"

Owner

jonnii commented Mar 8, 2013

What's the name of your environment?

danbarua commented Mar 8, 2013

"DatacentreName Staging" and "DataCentreName Production"
On Mar 8, 2013 3:00 PM, "Jonathan Goldman" notifications@github.com wrote:

What's the name of your environment?


Reply to this email directly or view it on GitHubhttps://github.com/jonnii/BuildDeploySupport/issues/1#issuecomment-14624394
.

Owner

jonnii commented Mar 8, 2013

Ah. You could do something like:

$OctopusEnvironmentName = 'DataCentreName Production'
$SafeName = $OctopusEnvironmentName -replace " ", ""
write-host $SafeName

Owner

jonnii commented Mar 8, 2013

If you try this and let me know if it works I'll add it to the topshelf script.

danbarua commented Mar 8, 2013

Yeah I did something like that, then i found that TopShelf was ignoring the "$" in ServiceName, so I replaced it with "_" to become "ServiceName_Envrionment"

Owner

jonnii commented Mar 8, 2013

My parameters look like this:

InstallTopshelfService $OctopusOriginalPackageDirectoryPath `
    $OctopusEnvironmentName `
    $OctopusPackageVersion `
    'My.Application.exe' `
    'My.Application'

When installed the service list shows the following:

ServiceName: My.Application$Staging
Display name: My.Application (Instance: Staging)
Description: My.Application Staging / 1.16.2.3088

Are you seeing something similar?

danbarua commented Mar 8, 2013

The script as is works on the assumption that the service description and the environment name do not contain spaces, but both of those are valid inputs.

2013-03-08 14:04:59 DEBUG  Looking for PowerShell scripts named Deploy.ps1
2013-03-08 14:04:59 INFO   Calling PowerShell script: 'E:\Octopus\Applications\PR Staging\Application.ReadModel.Projections.Host\1.0.0.87\Deploy.ps1'
2013-03-08 14:04:59 INFO     Installing Application Projections Host$PR Staging
2013-03-08 14:04:59 INFO     ERROR: Invoke-Expression : The term 'E:\Octopus\Applications\PR' is not recognized as
2013-03-08 14:04:59 INFO     ERROR: the name of a cmdlet, function, script file, or operable program. Check the spe
2013-03-08 14:04:59 INFO     ERROR: lling of the name, or if a path was included, verify that the path is correct a
2013-03-08 14:04:59 INFO     ERROR: nd try again.
2013-03-08 14:04:59 INFO     ERROR: At E:\Octopus\Applications\PR Staging\Application.ReadModel.Projections.Host
2013-03-08 14:04:59 INFO     ERROR: \1.0.0.87\DeployService.ps1:51 char:6
2013-03-08 14:04:59 INFO     ERROR: +         iex <<<<  "$path\$executable install --environment=$environment"
2013-03-08 14:04:59 INFO     ERROR:     + CategoryInfo          : ObjectNotFound: (E:\Octopus\Applications\PR:Stri
2013-03-08 14:04:59 INFO     ERROR:    ng) [Invoke-Expression], CommandNotFoundException
2013-03-08 14:04:59 INFO     ERROR:     + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Co
2013-03-08 14:04:59 INFO     ERROR:    mmands.InvokeExpressionCommand
2013-03-08 14:04:59 INFO     ERROR:
2013-03-08 14:04:59 DEBUG  Script 'E:\Octopus\Applications\PR Staging\Application.ReadModel.Projections.Host\1.0.0.87\Deploy.ps1' completed with return code -12.
Owner

jonnii commented Mar 8, 2013

can you paste your InstallTopShelf call? Do you have commas in there? It's a powershell function, so there should be no commas between the arguments. Also, your service name can't have spaces in it, so you'll need to remove them or replace them with periods or underscores.

This might also be because your path has spaces in it and invoke-expression is blowing up.

Can you pastie your call to InstallTopshelfService and also the arguments you're passing in (the values, not the octopus variables names).

Owner

jonnii commented Mar 8, 2013

I published a prerelease package with a fix, can you try it? Just run:

update-package BuildDeploySupport -pre

danbarua commented Mar 8, 2013

yeah something like that works with escaping the path. here's what i've got:
http://pastebin.com/jU7dyZdC

There are some quirks - i'm not sure what the --environment:$environment flag is meant to do. I've noticed that if you put in any command line flags that topshelf does not understand or expect, it silently exits and it does not give an error code. So I changed that to -instance: instead as I guessed that was the original intent?

I've got it working installing my services but now I can't uninstall them at all.

Owner

jonnii commented Mar 8, 2013

I think to get the service name to uninstall you'll need to supply the same flags as you passed in when you installed the service. We are setting all the flags in the HostFactory so that wasn't necessary. I'm going to add another parameter to the InstallTopshelfService for additional command line arguments.

The --environment flag is something we use in our app, I figured it'd be a useful thing to have as a convention, but if it causes topshelf to fall over then that's... less useful. Give me a few minutes and I'll build another package with your changes.

danbarua commented Mar 8, 2013

Hold tight - I think messing around with the registry is messing up TopShelf - have you tried to do an uninstall yet?

TopShelf reports that the service was uninstalled but this is not the case.

2013-03-08 16:37:29.1021|Topshelf.HostFactory.New|Info|Configuration Result:
[Success] Name ApplicationProjections
[Success] DisplayName ApplicationProjections (Instance: PR-Staging)
[Success] Description Application Projections Host
[Success] InstanceName PR-Staging
[Success] ServiceName CallCraftProjections$PR-Staging||Program.Main => HostFactory.Run => HostFactory.New

I think a better approach would be this:

  • Check if the service exists
  • If it does, maybe look up the image path in the registry and call the original topshelf executable with -uninstall flag
  • Then install the new exe using TopShelf
Owner

jonnii commented Mar 8, 2013

The problem with that is it's really slow =(

danbarua commented Mar 8, 2013

Ouch - I think it might be the only way to go. I've now got two copies of my windows Service on my staging server that I can't remove now!

Owner

jonnii commented Mar 8, 2013

use sc.exe delete <service name> that should get rid of them.

danbarua commented Mar 8, 2013

Yep tried that - The specified service does not exist as an installed service.

One of them isn't in HKLM:\System\CurrentControlSet\services\ either so i can't delete it that way either. To be fair I think it's linked to my experiments with the install script.

Owner

jonnii commented Mar 8, 2013

Do you have gchat?

Owner

jonnii commented Mar 8, 2013

Ok. I've got this all working for myself now. The services install clean and update correctly. Can you give it a try? I'm going to cut a new package.

Looks good - will do some further testing to be sure everything's ok.

Owner

jonnii commented Mar 11, 2013

fixed.

@jonnii jonnii closed this Mar 11, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment