Your browser was unable to load all of the resources. They may have been blocked by your firewall, proxy or browser configuration.
Press Ctrl+F5 or Ctrl+Shift+R to have your browser try again.

How to change the server workspace directory #1242

tardis4500 ·
I notice that when you follow the upgrade procedure, the server workspace directory does not get moved. Is there a way to set the server workspace directory to a location outside the installationdirectory?
  • replies 11
  • views 5771
  • stars 0
robinshen ADMIN ·
Yes, you can do this by configuring workspace setting of root configuration as:
/path/to/external/workspace/${configuration.pathName}
tardis4500 ·
Unfortunately, that changes the location on all the agents as well. I was able to solve the problem by using a symbolic link but I think having this configurable on a per agent/server basis would be helpful.
robinshen ADMIN ·
Below setting will enable QuickBuild to use external workspace on server, while use the default workspace on agents.
${node.isServer()?"/path/to/external/workspace/" + configuration.getPathName():current.getName()}
tardis4500 ·
I've decided that what I would actually like to do is to have every build default to it's own workspace. I tried the following:

${node.getAttribute("WORKSPACE_DIR")}/${configuration.pathName}/${build.Version}

but this fails with

2011-02-04 09:45:43,752 [Thread-1589] ERROR com.pmease.quickbuild.DefaultBuildEngine - Error processing build request.
com.pmease.quickbuild.QuickbuildException: Failed to evaluate below expression:
mvel:build.Version
at com.pmease.quickbuild.util.ExceptionUtils.wrapException(ExceptionUtils.java:90)
at com.pmease.quickbuild.DefaultScriptEngine.evaluate(DefaultScriptEngine.java:93)
at com.pmease.quickbuild.DefaultScriptEngine.interpolate(DefaultScriptEngine.java:105)
at com.pmease.quickbuild.model.Configuration.interpolate(Configuration.java:1046)
at com.pmease.quickbuild.model.Configuration.getWorkspaceDir(Configuration.java:1052)
at sun.reflect.GeneratedMethodAccessor281.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:599)
at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:157)
at com.pmease.quickbuild.model.Configuration$$EnhancerByCGLIB$$5f0d36cc.getWorkspaceDir(<generated>)
at com.pmease.quickbuild.DefaultBuildEngine.process(DefaultBuildEngine.java:259)
at com.pmease.quickbuild.DefaultBuildEngine.access$1(DefaultBuildEngine.java:240)
at com.pmease.quickbuild.DefaultBuildEngine$2.run(DefaultBuildEngine.java:757)
at java.lang.Thread.run(Thread.java:735)
Caused by: [Error: could not access: Version; in class: null]
[Near : {... Unknown ....}]
robinshen ADMIN ·
In QuickBuild, the workspace is per configuration instead of per build. For example, for the same configuration, 1.0.1 and 1.0.2 should use the same workspace. 1.0.2 will run after 1.0.1 finishes, and can build incrementally based on intermediate files generated by 1.0.1 (you can of course clean up the workspace before 1.0.2 starts). If workspaces are assigned per build, there might have many many workspaces in the system.
tardis4500 ·
I understand the default behavior but there are some business cases for which we need to have each build start in a fresh space. I wanted to get this behavior by setting the workspace to:

${node.getAttribute("WORKSPACE_DIR")}/${configuration.pathName}/${build.Version}

Why doesn't this work and can it be made to work?
robinshen ADMIN ·
You may try this:
${node.getAttribute("WORKSPACE_DIR")}/${configuration.pathName}/${build!=null?build.version:""}
drdt ·
I realize this is very out-of-date, but I was looking to solve this problem in QB 4.0, and the syntax does not work:

${node.isServer() ? "/opt/ws/" + configuration.getPathName() : current.getName()}

I am getting the expected results on the server, but on the agent I get "Error getting workspace directory. The node might be offline or invalid scripts are embedded in workspace setting of the configuration. Please check server log for details."

In the agent log (there are no errors in the server log), I have these errors:

2011-11-14 11:53:37,039 [549710183@qtp-1174710634-1] ERROR com.pmease.quickbuild.RemotingSerializerFactory - Error invoking hessian method.
java.lang.RuntimeException: Failed to evaluate below expression: mvel:vars.getValue( "local_workspaceRoot" )

Caused by: [Error: vars.getValue( "local_workspaceRoot" ): Failed to evaluate below expression:
mvel:node.isServer() ? "/opt/ws/" + configuration.getPathName() : current.getName()]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]

Caused by: com.pmease.quickbuild.QuickbuildException: Failed to evaluate below expression:
mvel:node.isServer() ? "/opt/ws/" + configuration.getPathName() : current.getName()

Caused by: [Error: unable to access property (null parent): getName]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]

It looks like the 'current' value is not being populated with the current configuration. I will attach the full stack dump as a comment.
drdt ·
2011-11-14 11:53:37,039 [549710183@qtp-1174710634-1] ERROR com.pmease.quickbuild.RemotingSerializerFactory - Error invoking hessian method.
java.lang.RuntimeException: Failed to evaluate below expression:
mvel:vars.getValue( "local_workspaceRoot" )
at com.pmease.quickbuild.util.ExceptionUtils.wrapException(ExceptionUtils.java:87)
at com.pmease.quickbuild.DefaultScriptEngine.evaluate(DefaultScriptEngine.java:93)
at com.pmease.quickbuild.DefaultScriptEngine.interpolate(DefaultScriptEngine.java:104)
at com.pmease.quickbuild.model.Configuration.interpolate(Configuration.java:1050)
at com.pmease.quickbuild.model.Configuration.getWorkspaceDir(Configuration.java:1056)
at com.pmease.quickbuild.grid.NodeServiceImpl.getWorkspaceDir(NodeServiceImpl.java:72)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:306)
at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:202)
at com.caucho.hessian.server.HessianServlet.invoke(HessianServlet.java:389)
at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:369)
at com.pmease.quickbuild.grid.GridServlet.service(GridServlet.java:32)
at com.pmease.quickbuild.web.HttpServiceProvider$1$1.service(HttpServiceProvider.java:87)
at org.eclipse.equinox.http.servlet.internal.ServletRegistration.service(ServletRegistration.java:61)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:126)
at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:60)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.equinox.http.jetty.internal.HttpServerManager$InternalHttpServiceServlet.service(HttpServerManager.java:317)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:939)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: [Error: vars.getValue( "local_workspaceRoot" ): Failed to evaluate below expression:
mvel:node.isServer() ? "/opt/ws/" + configuration.getPathName() : current.getName()]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:388)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:135)
at org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeAccessor(DynamicOptimizer.java:66)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:139)
at org.mvel2.compiler.ExecutableAccessor.getValue(ExecutableAccessor.java:42)
at org.mvel2.MVEL.executeExpression(MVEL.java:1057)
at com.pmease.quickbuild.plugin.basis.BasisPlugin$16.evaluate(BasisPlugin.java:192)
at com.pmease.quickbuild.DefaultScriptEngine.evaluate(DefaultScriptEngine.java:87)
... 32 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:987)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:326)
... 39 more
Caused by: com.pmease.quickbuild.QuickbuildException: Failed to evaluate below expression:
mvel:node.isServer() ? "/opt/ws/" + configuration.getPathName() : current.getName()
at com.pmease.quickbuild.util.ExceptionUtils.wrapException(ExceptionUtils.java:89)
at com.pmease.quickbuild.DefaultScriptEngine.evaluate(DefaultScriptEngine.java:93)
at com.pmease.quickbuild.DefaultScriptEngine.interpolate(DefaultScriptEngine.java:104)
at com.pmease.quickbuild.variable.VariableWrapper.getValue(VariableWrapper.java:67)
at com.pmease.quickbuild.variable.VariableAccessor.getValue(VariableAccessor.java:57)
... 45 more
Caused by: [Error: unable to access property (null parent): getName]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getMethod(ReflectiveAccessorOptimizer.java:917)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:326)
at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.optimizeAccessor(ReflectiveAccessorOptimizer.java:135)
at org.mvel2.optimizers.dynamic.DynamicOptimizer.optimizeAccessor(DynamicOptimizer.java:66)
at org.mvel2.ast.ASTNode.getReducedValueAccelerated(ASTNode.java:139)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:128)
at org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:118)
at org.mvel2.MVEL.executeExpression(MVEL.java:1057)
at com.pmease.quickbuild.plugin.basis.BasisPlugin$16.evaluate(BasisPlugin.java:192)
at com.pmease.quickbuild.DefaultScriptEngine.evaluate(DefaultScriptEngine.java:87)
... 48 more
robinshen ADMIN ·
Since you are putting the script into a variable, and "current" only refer to the object defining the script, and will no longer be the configuration. To solve the issue, please write the script like below in the variable value:
${(node.isServer() ? "/opt/ws":system.workspaceDir.absolutePath) + "/" + configuration.getPathName()}

The "system.workspaceDir.absolutePath" returns default workspace root.
drdt ·
Got it, I see what is going on. For those who are interested, here is my final script:

${groovy:
int buildsDir = configuration.getPathName().indexOf( "builds", 0 )
int pathStart = configuration.getPathName().indexOf( "/", buildsDir )

if ((buildsDir >= 0) && (pathStart >= 0) && node.hasAttribute( "BUILDDRIVE" )) {
node.getAttribute( "BUILDDRIVE" ) + "/" + configuration.getPathName().substring( pathStart )
\} else {
system.getWorkspaceDir().getAbsolutePath() + "/" + configuration.getPathName()
\}
}

For systems which have the variable 'BUILDDRIVE' defined, it sets the workspace of all configurations under the 'builds' tree under BUILDDRIVE. For example, assuming a configuration of /root/builds/Product/Branch/nightly, the builds end up as follows:
Server: /opt/quickbuild-4.0.13/workspace/root/builds/Product/Branch/nightly
Windows build slave (BUILDDRIVE="D:"): D:\Product\Branch\nightly
Windows build slave (no BUILDDRIVE): C:\QuickBuild\buildagent\workspace\root\Product\Branch\nightly
Mac build slave (BUILDDRIVE="/Volumes/Build"): /Volumes/Build/Product/Branch/nightly
~maintenance configuration tree is unaffected. This enables me to customize each system where I want the workspaces stored.