Can't run psql from an ant target running in NetBeans 8.0.2 - postgresql

I'm running PostgreSQL 9.2 on Windows 7. I'm trying to run an Ant target using an apply tag with the executable property set to psql from a NetBeans 8.0.2 build file. I have created a pgpass.conf file in the right place with the correct password for the postgres user and I can run psql at a command prompt without having to enter a password. But when I run the Ant target, I get an error message in the output file saying the target failed because no password was supplied. What am I doing wrong? The target looks like this:
<filelist id="create-dbfiles" dir="${root}" files="createdb.sql"/>
<target name="create-db">
<apply executable="psql" addsourcefile="false" output="output.txt">
<arg value="-U postgres" />
<arg value="-w" />
<filelist refid="create-dbfiles"/>
<redirector>
<inputmapper type="glob" from="*" to="${root}\*" />
</redirector>
</apply>
</target>

a_horse_with_no_name got me thinking about the exec tag but trying to run psql directly via an exec tag or an apply tag still threw up errors about a password not being supplied. Then I realised that psql ran smoothly from the cmd prompt. I started playing around with calling cmd.exe and passing a command to the command line, and found a solution:
<filelist id="clean-dbfiles" dir="${root}" files="cleandb.sql"/>
<target name="clean-db">
<apply executable="cmd.exe" addsourcefile="true" >
<filelist refid="clean-dbfiles"/>
<env key="PGPASSWORD" value="rootpassword"></env>
<arg value="/c"></arg>
<arg value="psql -w -U postgres -f " />
<srcfile />
</apply>
</target>
<filelist id="create-dbfiles" dir="${root}" files="createdb.sql"/>
<target name="create-db">
<apply executable="cmd.exe" addsourcefile="true" >
<filelist refid="create-dbfiles"/>
<env key="PGPASSWORD" value="rootpassword"></env>
<arg value="/c"></arg>
<arg value="psql -w -U postgres -f "/>
<srcfile />
</apply>
</target>
Here are the two key targets for creating a build script for a postgres database. Note the following points:
Run cmd.exe not psql directly
Set addsourcefile to true because I want to call neat little self-contained SQL files for each target.
Use apply with a filelist because for my createtables or populate targets I may have a directory of separate SQL files
Give up on hoping to invoke the pgpass.conf file. For some reason Ant in NetBeans can't access it. Resort to the PGPASSWORD environment key and set it to the desired password. This is running locally for development purposes so security isn't an issue.
You need to pass the /c switch to cmd.exe so that you can then pass a command line. I didn't separate the psql command line into separate arguments because I think the complete line is being passed to cmd.exe as a single argument.
addsourcefile is set to true so each file in the filelist is appended to the psql command line just after the -f switch and everything works a treat.
Voilà! What a fuss! I had no similar difficulty with MySql because you can pass the password to the command line directly.

Related

How to force Phing task to respect verbose exec command?

In other words how to display output of currently executed phing task?
<target name="backup_db">
<mkdir dir="${dir.sql}"/>
<exec command="mysqldump -v -h ${db.host} -u ${db.username} -p${db.password} ${db.name} > ${dir.sql}/${dump.basename}"/>
</target>
This pulls a database dump, as you see I specified -v flag to get verbose output. Command runs successfully however with no output during the dump.
Foo > backup_db:
BUILD FINISHED
Total time: 1 minute 40.81 seconds
The same command called directly in terminal will list each table one by one that's currently being dumped. How to achieve that in phing?
Adding passthru="true" to the exec solved the problem. Now I get the output in real time.

Nant run exec task under different user

It is possible to run Exec task with different domain and user ?
I need to restart iis on 10 load balancers , can this be achieved with Nant exe task ?
For now I have script like
<exec programm='iisreset'>
<arg line='${balancer}'/>
<arg line='/restart' />
</exec>
This is working on Integration environment (Since the same domain) , and on test it fails with Acces Denied..
Thanks
You could use the command runas in you exec call and use the the /netonly argument for remote access to your balancers.
I guess this could look something like this:
<exec program="runas">
<arg line="/netonly" />
<arg line="${'/user:' + domain + '\' + username}" />
<arg line="${'"iisreset ' + balancer + ' /restart"'}" />
</exec>
This could work for you but I am not sure how you are going to give him the password automatically. You could run runas with /savecred in your cmd once though. But be careful about saving your passwords...
Note that I could not test this as I don't have the required environment to do so.
Source: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/runas.mspx?mfr=true

Run ant exec task from different folder

I want to run my "exec grails" task into my grails project. I set grail path in exec task like
<exec executable="${grails}"
How can I say , that exec should start from my project folder?
From the exec Ant task documentation:
Attribute Description
dir the directory in which the command should be executed.
<exec executable="${grails}" dir="${my.project.dir}">

Exception running powershell script from MSBuild Exec Task

i´m having a problem with MSBuild and Powershell. There is a PS-script that i want to execute within the MSBuild exec-Task.
The Problem: Running the Script direct from CMD works, but running the script within MSBuild I get an error.
Here the MSBuild script:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\4.0\MSBuild.ExtensionPack.tasks"/>
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
<PathToSvnClient>C:\Program Files (x86)\CollabNet\Subversion Client</PathToSvnClient>
</PropertyGroup>
<ItemGroup>
<!-- set Folder to Svn Repository for svn info command-->
<SvnFolder Include="$(MSBuildProjectDirectory)\.."/>
</ItemGroup>
<Target Name="SvnInfo">
<!-- get SVN Revision and Repository Path -->
<SvnInfo LocalPath="%(SvnFolder.FullPath)" ToolPath="$(PathToSvnClient)">
<Output TaskParameter="Revision" PropertyName="Revision" />
<Output TaskParameter="RepositoryPath" PropertyName="RepositoryPath" />
</SvnInfo>
</Target>
<Target Name="SetProductVersion" DependsOnTargets="SvnInfo">
<Exec Command="powershell -file "Scripts\SetSth.ps1" -PARAM "$(PathToSth)" -SVNID $(Revision) -SVNFOLDER "$(RepositoryPath)"" LogStandardErrorAsError="true" ContinueOnError="false"/>
</Target>
The Command is executed exactly the same way as on CMD, but i get an exception from the Powershell Script for the SVNFOLDER param.
The Command that is executed looks like this:
powershell -file "Scripts\SetSth.ps1" -PARAM "C:\abc\cde" -SVNID 1234
-SVNFOLDER "https://domain/svn/rep/branches/xy%20(Build%2012)"
So from CMD it works, from within MSBuild not. I have no idea why. I hope you got an idea.
What about this approach playing with double and singles quotes:
<Target Name="SetProductVersion" DependsOnTargets="SvnInfo">
<Exec Command="powershell -command "& {Scripts\SetSth.ps1 -PARAM '$(PathToSth)' -SVNID '$(Revision)' -SVNFOLDER '$(RepositoryPath)'}"" LogStandardErrorAsError="true" ContinueOnError="false"/>
</Target>
Double check your paths.
Remember, powershell invoked in this way runs as Msbuild.exe under whatever user is executing the build. To msbuild.exe, a straight call to cmd.exe is going to start in the working directory where msbuild lives.
Assume -file "Scripts\SetSth.ps1" references C:\users\yourusername\Scripts\SetSth.ps1
So for you, calling cmd.exe and running that may work just fine, b/c your working directory is going to match C:\users\yourusername
For msbuild.exe, its likely unable to find that file, as its starting in something like *C:\Windows\Microsoft.NET\Framework\v4.0*
So it's looking for C:\Windows\Microsoft.NET\Framework\v4.0\Scripts\SetSth.ps1
I would try making that file path fully qualified. If that still doesn't work, have cmd.exe dump its results into a property and have msbuild log it. Then you can review the paths.

What's a good way to consume a PowerShell Cmdlet in a NAnt build system?

We use NAnt extensively for our build system. Recently, I've written a couple PowerShell Cmdlets to perform a few database related things. At first, the intent of these Cmdlets was not to necessarily run within our build process. However, this has recently become a need and we would like to run a few of these Cmdlets from our NAnt based build process.
These Cmdlets are written in C# and we have a SnapIn for them (if that matters at all).
A few ideas:
Use the exec task to call PowerShell? (not sure how this would work though)
Write a custom NAnt task that references and uses the Cmdlet?
What might be a good way to do this?
You can use the below exec task in your nant script to call your ps cmdlets.
<exec program="powershell" workingdir="${BuildManagementDir}" verbose="true">
<arg value="-noprofile"/>
<arg value="-nologo"/>
<arg value="-noninteractive"/>
<arg value="-command"/>
<arg value=".\xyz.ps1"/>
</exec>
You could certainly use the exec task, setting the program attribute to powershell.exe and passing in the command line something like "-Command { }".
Alternatively, you could create a custom NAnt task that internally uses the powershell hosting APIs to execute your cmdlets or scripts. There's a simple example of this (using the PS v1 APIs) here.
Based on JiBe's answer its the other way around, here is the working solution. When running powershell that takes arguments you need to run the powershell script then the arguments.
PS yourscript.ps1 -arg1 value1 -arg2 value2
In NAnt:
<exec program="powershell" workingdir="${powershell_dir}" verbose="true">
<arg value=".\yourscript.ps1"/>
<arg value="-arg1 ${value1}"/>
<arg value="-arg2 ${value2}"/>
</exec>
The best way I think is to define the arguments in PS for NAnt is like
$value1=$args[0]
$value2=$args[1]
So in command line you will use:
PS yourscript.ps1 some_value1 some_value2
Then this translates in NAnt like:
<property name="Value1" value="some_Value1" />
<property name="Value2" value="some_Value2" />
<exec program="powershell" workingdir="${powershell_dir}" verbose="true">
<arg value=".\yourscript.ps1"/>
<arg value="${value1}"/>
<arg value="${value2}"/>
</exec>
The best way is to use similar methods as one would use in task scheduler. That means run powershell with the -command argument and begin the command with &.
For example:
<exec program="powershell" workingdir="${ifscriptrequires}" verbose="true">
<arg line="-Command" />
<arg line="$amp; C:\scripts\somescript.ps1 -SwitchParam -someargument 'somevalue' 'somepositionalparameter'" />
</exec>