/// <summary> /// Creates a new command state instance. /// </summary> /// <param name="node">The PlanetLab node state.</param> /// <param name="command">The secure shell command.</param> /// <param name="exception">The subcommand exception.</param> public PlManagerSubcommandState(PlManagerNodeState node, SshCommand command, Exception exception) { this.Node = node; this.Command = command.CommandText; this.Timeout = command.CommandTimeout; this.ExitStatus = command.ExitStatus; this.Result = command.Result; this.Error = command.Error; this.Exception = exception; }
/// <summary> /// Creates a new command state instance. /// </summary> /// <param name="node">The PlanetLab node state.</param> /// <param name="command">The secure shell command.</param> /// <param name="duration">The subcommand duration.</param> /// <param name="retries">The number of retries for this command.</param> public PlManagerSubcommandState(PlManagerNodeState node, SshCommand command, TimeSpan duration, int retries) { this.Node = node; this.Command = command.CommandText; this.Timeout = command.CommandTimeout; this.ExitStatus = command.ExitStatus; this.Result = command.Result; this.Error = command.Error; this.Duration = duration; this.Retries = retries; }
/// <summary> /// Creates a new node history from the specified node state. /// </summary> /// <param name="state">The node state.</param> public PlManagerHistoryNode(PlManagerNodeState state) { // Validate the argument. if (null == state) throw new ArgumentNullException("state"); // Set the properties. this.Id = state.Node.Id.Value; this.Hostname = state.Node.Hostname; this.Success = state.SuccessCount; this.Warning = state.WarningCount; this.Fail = state.FailureCount; // Create the node history commands. this.subcommands.AddRange(from subcommand in state.Subcommands select new PlManagerHistorySubcommand(subcommand)); }
/// <summary> /// Runs a command on the specified PlanetLab node. /// </summary> /// <param name="state">The manager state.</param> /// <param name="node">The PlanetLab node state.</param> /// <param name="command">The PlanetLab command.</param> /// <param name="set">The command parameter set.</param> /// <param name="sshClient">The SSH client.</param> private void OnRunCommand(PlManagerState state, PlManagerNodeState node, PlCommand command, int set, SshClient sshClient) { // Raise the command started event. if (null != this.CommandStarted) this.CommandStarted(this, new PlManagerCommandEventArgs(state, node.Node, command, set)); try { // Compute the command text. string commandText = set >= 0 ? command.GetCommand(set) : command.Command; // The number of subcommands. int success = 0; int fail = 0; // Divide the command into subcommands. string[] subcommands = commandText.Split(PlManager.subcommandSeparators, StringSplitOptions.RemoveEmptyEntries); // For all subcommands. foreach (string subcommand in subcommands) { // If the operation has been paused, wait for resume. if (state.IsPaused) { state.WaitPause(); } // If the operation has been canceled, return. if (state.IsStopped) { // Raise the canceled event. if (null != this.CommandCanceled) this.CommandCanceled(this, new PlManagerCommandEventArgs(state, node.Node, command, set)); // Return. return; } // If the subcommand is empty, continue to the next subcommand. if (string.IsNullOrWhiteSpace(subcommand)) continue; // Create a new SSH command. using (SshCommand sshCommand = sshClient.CreateCommand(subcommand)) { try { // The command duration. TimeSpan duration; // The retry count. int retry = 0; do { // The start time. DateTime startTime = DateTime.Now; // Execute the command. sshCommand.Execute(); // Compute the command duration. duration = DateTime.Now - startTime; } while ((retry++ < state.Slice.CommandRetries) && (sshCommand.ExitStatus != 0)); // Create a new command state. PlManagerSubcommandState subcommandState = new PlManagerSubcommandState(node, sshCommand, duration, retry - 1); // Increment the number of successful subcommands. success++; // Add the subcommand. node.AddSubcommand(subcommandState); // Raise a subcommand success event. if (null != this.SubcommandSuccess) this.SubcommandSuccess(this, new PlManagerSubcommandEventArgs(state, node.Node, command, set, subcommandState)); } catch (Exception exception) { // Create a new subcommand state. PlManagerSubcommandState subcommandState = new PlManagerSubcommandState(node, sshCommand, exception); // Increment the number of failed subcommands. fail++; // Add the subcommand. node.AddSubcommand(subcommandState); // Raise a subcommand fail event. if (null != this.SubcommandFail) this.SubcommandFail(this, new PlManagerSubcommandEventArgs(state, node.Node, command, set, exception)); } } } // Raise a command completed event. if (null != this.CommandFinishedSuccess) this.CommandFinishedSuccess(this, new PlManagerCommandEventArgs(state, node.Node, command, set, success, fail)); } catch (Exception exception) { // Raise a command completed event. if (null != this.CommandFinishedFail) this.CommandFinishedFail(this, new PlManagerCommandEventArgs(state, node.Node, command, set, exception)); } }
/// <summary> /// Adds the specified PlanetLab node to the pending state. /// </summary> /// <param name="node">The PlanetLab node.</param> internal void AddNode(PlNode node) { lock (this.sync) { // Create a new state for this node. PlManagerNodeState nodeState = new PlManagerNodeState(node); // Add the node to the nodes state list. this.nodeStates.Add(nodeState); // Add the state index to the list of pending nodes. this.pendingNodes.Add(this.nodeStates.Count - 1); } }