Skip to content

Commit

Permalink
#166: basic flow working
Browse files Browse the repository at this point in the history
  • Loading branch information
ypujante committed Oct 31, 2012
1 parent d784563 commit 213862d
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -240,15 +240,20 @@ class UrlMappings

// commands
"/commands/$id/stream"(controller: 'commands', action: 'stream') {
__nvbe = 'Commands'
__nvbe = 'Agents'
__role = UrlMappings.role('/commands/$id/stream')
}

"/commands/renderHistory"(controller: 'commands', action: 'renderHistory') {
__nvbe = 'Commands'
__nvbe = 'Agents'
__role = UrlMappings.role('/commands/renderHistory')
}

"/commands/renderCommand/$id"(controller: 'commands', action: 'renderCommand') {
__nvbe = 'Agents'
__role = UrlMappings.role('/commands/renderCommand')
}

// plan
"/plan/execute/$id"(controller: 'plan', action: 'execute') {
__nvbe = 'Plans'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -424,23 +424,27 @@ class AgentsController extends ControllerBase
* Commands view page
*/
def commands = {
def pageCommands = CommandExecution.findAllByFabricAndAgent(request.fabric.name,
params.id,
[sort: 'startTime', order: 'desc'])

def command = null
boolean isCommandRunning = false

if(params.commandId)
{
command = pageCommands.find { it.commandId == params.commandId}
command = commandsService.findCurrentCommandExecutions([params.commandId])[params.commandId]

if(!command)
command = CommandExecution.findByFabricAndAgentAndCommandId(request.fabric.name,
params.id,
params.commandId)
{
command = CommandExecution.findByCommandId(params.commandId)

// command = CommandExecution.findAllByFabricAndAgentAndCommandId(request.fabric.name,
// params.id,
// params.commandId)
isCommandRunning = false
}
else
isCommandRunning = true
}

[commands: pageCommands, command: command]
[command: command, isCommandRunning: isCommandRunning]
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,39 @@ public class CommandsController extends ControllerBase
* Render history according to criteria
*/
def renderHistory = {
println "renderHistory: ${params}"
def commands = CommandExecution.findAllByFabricAndAgent(request.fabric.name,
params.agentId,
[sort: 'startTime', order: 'desc'])
render(template: 'history', model: [commands: commands])
}

/**
* Renders a single command
*/
def renderCommand = {
def command = null
boolean isCommandRunning = false

if(params.id)
{
command = commandsService.findCurrentCommandExecutions([params.id])[params.id]

if(!command)
{
command = CommandExecution.findByCommandId(params.id)

isCommandRunning = false
}
else
isCommandRunning = true
}

if(command)
render(template: 'command', model: [command: command, isCommandRunning: isCommandRunning])
else
render "not found"
}

/**
* Writes the stream requested
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,8 @@
}
</style>
<g:render template="/commands/command_js"/>
<g:javascript>
function renderCommandStream(commandId, streamType, success)
{
%{--YP Implementation note: this is obviously hacky, but there does not seem to be a way to use g.remoteFunction + javascript variables in all places!

${g.remoteFunction(controller: 'commands', id: <javascript commandId>, action: 'stream', params: [streamType: <javascript streamType>], update:[success: '<javascript variable>'])}

--}%
jQuery.ajax({type:'GET',data:{'streamType': streamType}, url:'/console/commands/' + commandId + '/stream',success:function(data,textStatus){jQuery('#' + success).html(data);},error:function(XMLHttpRequest,textStatus,errorThrown){}});
}
function shouldRefresh()
{
return document.getElementById('autoRefresh').checked;
Expand Down Expand Up @@ -120,8 +112,8 @@ function showHide()
</div>
</div>

<g:if test="${command}">
<div id="shell-${command.commandId}" class="shell span16"><a class="close" href="#" onclick="toggleShowHide('#shell-${command.commandId}')">&times;</a><div class="cli"><span class="prompt">${command.username.encodeAsHTML()}@${command.agent.encodeAsHTML()}#</span>&nbsp;<span class="command">${command.command.encodeAsHTML()}</span> <g:if test="${command.redirectStderr}">2&gt;&amp;1 </g:if><span class="date">[<cl:formatDate time="${command.startTime}"/>]</span> <span class="exitValue">[${'$'}?=${command.exitValue?.encodeAsHTML()}]</span></div><g:each in="['stdin', 'stderr', 'stdout']" var="streamType"><g:if test="${command.getTotalBytesCount(streamType) > 0}"><div id="${command.commandId}-${streamType}" class="${streamType}"><cl:renderCommandBytes command="${command}" streamType="${streamType}" onclick="renderCommandStream('${command.commandId}', '${streamType}', '${command.commandId}-${streamType}')"/></div></g:if></g:each><div class="cli"><span class="prompt">${command.username.encodeAsHTML()}@${command.agent.encodeAsHTML()}#</span>&nbsp;<span class="date">[<cl:formatDate time="${command.endTime}"/>]</span></div></div>
<g:if test="${params.commandId}">
<div id="included-command"><g:include controller="commands" action="renderCommand" id="${params.commandId}"/></div>
</g:if>

<h3>History: Auto Refresh: <cl:checkBoxInitFromParams name="autoRefresh" id="autoRefresh" onclick="autoRefresh();"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
%{--
- Copyright (c) 2012 Yan Pujante
-
- Licensed under the Apache License, Version 2.0 (the "License"); you may not
- use this file except in compliance with the License. You may obtain a copy of
- the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- License for the specific language governing permissions and limitations under
- the License.
--}%

<g:if test="${command}">
<div id="shell-${command.commandId}"><div class="shell span16"><a class="close" href="#" onclick="toggleShowHide('#shell-${command.commandId}')">&times;</a><div class="cli"><span class="prompt">${command.username.encodeAsHTML()}@${command.agent.encodeAsHTML()}#</span>&nbsp;<span class="command">${command.command.encodeAsHTML()}</span> <g:if test="${command.redirectStderr}">2&gt;&amp;1 </g:if><span class="date">[<cl:formatDate time="${command.startTime}"/>]</span> <span class="exitValue">[${'$'}?=${command.exitValue?.encodeAsHTML()}]</span></div><g:if test="${!isCommandRunning}"><g:each in="['stdin', 'stderr', 'stdout']" var="streamType"><g:if test="${command.getTotalBytesCount(streamType) > 0}"><div id="${command.commandId}-${streamType}" class="${streamType}"><cl:renderCommandBytes command="${command}" streamType="${streamType}" onclick="renderCommandStream('${command.commandId}', '${streamType}', '${command.commandId}-${streamType}')"/></div></g:if></g:each><div class="cli"><span class="prompt">${command.username.encodeAsHTML()}@${command.agent.encodeAsHTML()}#</span>&nbsp;<span class="date">[<cl:formatDate time="${command.endTime}"/>]</span></div></g:if><g:else><img src="${resource(dir:'images',file:'spinner.gif')}" alt="Spinner" /></g:else></div><g:if test="${isCommandRunning}"><g:javascript>setTimeout("renderCommand('${command.commandId}', 'shell-${command.commandId}')", '${params.refreshRate ?: 2000}')</g:javascript></g:if></div>
</g:if>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
%{--
- Copyright (c) 2012 Yan Pujante
-
- Licensed under the Apache License, Version 2.0 (the "License"); you may not
- use this file except in compliance with the License. You may obtain a copy of
- the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- License for the specific language governing permissions and limitations under
- the License.
--}%
<g:javascript>
function renderCommandStream(commandId, streamType, success)
{
%{--YP Implementation note: this is obviously hacky, but there does not seem to be a way to use g.remoteFunction + javascript variables in all places!

${g.remoteFunction(controller: 'commands', id: <javascript commandId>, action: 'stream', params: [streamType: <javascript streamType>], update:[success: '<javascript variable>'])}

--}%
jQuery.ajax({type:'GET',data:{'streamType': streamType}, url:'/console/commands/' + commandId + '/stream',success:function(data,textStatus){jQuery('#' + success).html(data);},error:function(XMLHttpRequest,textStatus,errorThrown){}});
}
function renderCommand(commandId, success) {
if(!isHidden('#' + success))
{
jQuery.ajax({type:'GET',url:'/console/commands/renderCommand/' + commandId,success:function(data,textStatus){jQuery('#' + success).parent().html(data);},error:function(XMLHttpRequest,textStatus,errorThrown){}});
}
}
</g:javascript>
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,11 @@ function show(selector)
{
toggleClass(selector, false, 'hidden');
}

/**
* Returns a boolean if the object is visible
*/
function isHidden(selector)
{
return $(selector).hasClass('hidden')
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,9 @@ public interface CommandsService
*/
void writeStream(Fabric fabric, String commandId, StreamType streamType, Closure closure)
throws NoSuchCommandExecutionException

/**
* @return a map with all currently running commands
*/
Map<String, CommandExecution> findCurrentCommandExecutions(Collection<String> commandIds)
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import org.linkedin.glu.agent.rest.common.AgentRestUtils
import org.linkedin.groovy.util.config.Config
import java.util.concurrent.TimeoutException
import org.linkedin.glu.groovy.utils.concurrent.GluGroovyConcurrentUtils
import org.linkedin.glu.groovy.utils.collections.GluGroovyCollectionUtils

/**
* @author yan@pongasoft.com */
Expand Down Expand Up @@ -85,6 +86,15 @@ public class CommandsServiceImpl implements CommandsService
* The commands that are currently executing */
private final Map<String, CommandExecution> _currentCommandExecutions = [:]

@Override
Map<String, CommandExecution> findCurrentCommandExecutions(Collection<String> commandIds)
{
synchronized(_currentCommandExecutions)
{
GluGroovyCollectionUtils.subMap(_currentCommandExecutions, commandIds)
}
}

@Override
String executeShellCommand(Fabric fabric, String agentName, args)
{
Expand Down

0 comments on commit 213862d

Please sign in to comment.