How to add an additional startup task to service definition?

Nov 27, 2011 at 12:17 PM
Edited Nov 27, 2011 at 12:18 PM

Hey guys,

 

After scaffolding but before creating the package, if you look into the ServiceDefinition.csdef, you will notice a couple of Startup tasks there, which run after the WebRole has been loaded.

 

<Startup>

	<Task commandLine="add-environment-variables.cmd" executionContext="elevated" taskType="simple" />     
	<Task commandLine="install-php.cmd" executionContext="elevated" taskType="simple">

</Startup>

 

 

I would like to add another task to them and added this line:

 

<Task commandLine="startup.cmd" executionContext="elevated" taskType="simple"/>

 

The startup.cmd task contains only this two lines:

 

D:\Windows\SysWOW64\inetsrv\appcmd add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
D:\Windows\SysWOW64\inetsrv\appcmd.exe set app "WebRole_IN_0_VC/" /applicationPool:"VCPool"

 

and I have placed it in the same folder as the other commands:

\build\WordPress\WebRole\bin

After creating the package and uploading it to the cloud, I keep getting an error and it keeps retrying to start the Webrole.

Is there anything else I need to pay attention to when doing this? The powershell script runs fine on the Remote Desktop on the cloud. So the syntax is correct. 

 

Thanks,

Houman

Nov 27, 2011 at 3:25 PM

Update:

I was able to get a step further.

For some reason it doesnt like an additional Task like described above.  I don't understand why. 

I ended up editing install-php-impl.cmd file in the same path \build\WordPress\WebRole\bin.

I have added this line at the end

%WINDIR%\system32\inetsrv\appcmd.exe add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"

And in fact, once deployed, it actually does that. :) It creates a new AppPool, which is fantastic.

Now I would like to change my second <Site> to this new created AppPool, but adding another line right after, doesn't help.

%WINDIR%\system32\inetsrv\appcmd.exe set app "WebRole_IN_0_VC/" /applicationPool:"VCPool"

It seems the second site is somehow not yet generated. 

 

Is there a way to delay this execution by 30 seconds to make sure the second site is up and can be changed?

Editor
Nov 27, 2011 at 3:31 PM

Houman,

The first way did not work because you tried to execute a powershell script inside a batch shell script. Pull it out as a .ps as the other startup scripts do and it should work.

For delaying execution you may want to look at the sleep cmdlet if you do it inside a shell script. Note that this will cause your role startup to be delayed also.

http://technet.microsoft.com/en-us/library/ee177002.aspx

Ben

Nov 28, 2011 at 7:04 AM

Hi Ben,

 

Ahh I understand how you have done it. I am now investigating how to do it in powershell script.

In the meanwhile, I was just wondering, if I am making it unnecessarily too complicated.  Check out this screnshot of the app pool.

Do you see those two marked ones? These are generated after deploying the wordpress package. The reason you see two is because I am using two sites inside the <sites> tag.

The first one is the wordpress and the second one is my silverlight app. Since my silverlight app is written in .NET 4.0, its app pool needs also to target .NET 4.0 as well however its set to .NET 2.0 by default.

Is that something I could set in the settings and being spared from the adventures of startup tasks all together? ;o)

 

Nov 30, 2011 at 8:54 AM
Edited Nov 30, 2011 at 8:55 AM

Hi Ben,



Finally I have found a solution.

%WINDIR%\system32\inetsrv\appcmd.exe add apppool /name:"VCPool" /managedRuntimeVersion:"v4.0" /managedPipelineMode:"Integrated"
powershell -command "Set-ExecutionPolicy Unrestricted" 2>> err.out 
powershell .\sleep.ps1 2>> err.out
%WINDIR%\system32\inetsrv\appcmd.exe set app "WebRole_IN_0_VC/" /applicationPool:"VCPool"

 

 

The powershell script does 

 

 Start-Sleep -s 90

 

 

The task is run as a background type.  Unfortunately this is more of a workaround than real solution. Waiting 90 seconds is to make sure the SITES are up and running is not great.

Without the delay of 90 seconds, the log files say that the second SITE has not been found.


The tasks are executed before the SITES are even generated.

And that bad news. I have been in touch with Microsoft if there is a better way to solve this than to wait a certain amount of time. They are investigating.

There is one other solution I came across.


In Visual Studio if a class that derives from RoleEntryPoint class is implemented in the web project. It can override OnStart() method. In there then you can run 

System.Diagnostics.Process.Start("OnStart.cmd")

Which may contains the script above.
OnStart() runs exactly when the Sites are created and the Role has started. This would have been the perfect spot for executing our script.
But since PHPAzure is working outside VS and doesn't have the required Cloud Azure project, I haven't found a way to do this.
Back in the pre 1.3 SDK days when we still had a CGI WebRole to add in Visual studio to host WordPress, this solution would have been possible.  Doing this now outside Visual Studio as its done now takes away that flexibility I am afraid.

Maybe this is something to improve in the later versions of the Scaffoldings.

If I find any better solution to this I will report it here.
Thanks,Houman

Editor
Nov 30, 2011 at 3:34 PM

Houman,

This is an issue with the platform, not with the Windows Azure SDK for PHP. The issue exists for any non-.NET app. You can still build and run a PHP application using Visual Studio but the process is no longer documented or recommended by the Interoperability team. You may be able to find it online somewhere still. Also, this article may help you tweak with PHP in Visual Studio http://blogs.msdn.com/b/silverlining/archive/2011/11/23/packaging-a-custom-php-installation-for-windows-azure.aspx

Note that if you do go the route of Visual Studio I will not be able to help you. Maybe someone else will be able to chime in.

Cheers,
Ben