/// <summary>
 /// Creates a new PlanetLab manager node event arguments instance.
 /// </summary>
 /// <param name="state">The manager state.</param>
 /// <param name="node">The PlanetLab node.</param>
 /// <param name="command">The PlanetLab command.</param>
 /// <param name="set">The PlanetLab command parameter set.</param>
 /// <param name="subcommand">The PlanetLab subcommand state.</param>
 public PlManagerSubcommandEventArgs(PlManagerState state, PlNode node, PlCommand command, int set, PlManagerSubcommandState subcommand)
 {
     this.State = state;
     this.Node = node;
     this.Command = command;
     this.Set = set;
     this.Subcommand = subcommand;
 }
        /// <summary>
        /// Creates a new subcommand history from the specified subcommand state.
        /// </summary>
        /// <param name="state">The subcommand state.</param>
        public PlManagerHistorySubcommand(PlManagerSubcommandState state)
        {
            // Validate the argument.
            if (null == state) throw new ArgumentNullException("state");

            // Set the properties.
            this.Command = state.Command;
            this.Exception = state.Exception != null ? state.Exception.Message : null;
            this.Timeout = state.Timeout;
            this.ExitStatus = state.ExitStatus;
            this.Result = state.Result;
            this.Error = state.Error;
            this.Duration = state.Duration;
            this.Retries = state.Retries;
        }
Exemplo n.º 3
0
        /// <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));
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Adds a subcommand result to the results list.
        /// </summary>
        /// <param name="subcommand">The subcommand.</param>
        private void OnAddResult(PlManagerSubcommandState subcommand)
        {
            // Create a new result item.
            ListViewItem item = new ListViewItem(new string[] {
                subcommand.Command,
                subcommand.ExitStatus.ToString(),
                subcommand.Duration.ToString()
            });

            item.Tag = new PlManagerHistorySubcommand(subcommand);
            item.ImageKey = subcommand.Exception == null ? subcommand.ExitStatus == 0 ?
                "Success" : "Warning" : "Error";

            // Add the result item.
            this.listViewResults.Items.Add(item);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Sends the subcommand to the connected tools.
        /// </summary>
        /// <param name="subcommand">The subcommand.</param>
        private void OnSendResultTools(PlManagerSubcommandState subcommand)
        {
            // For all the connected tool methods.
            foreach (ToolMethodInfo info in this.controlMethods.Methods.Where(inf => inf.Trigger == ControlSliceRun.toolTriggerCommand))
            {
                lock (this.toolSync)
                {
                    try
                    {
                        // Call the tool method asynchronously.
                        ToolMethodState asyncState = info.Method.BeginCall((IAsyncResult result) =>
                            {
                                try
                                {
                                    // End the call.
                                    if ((bool)info.Method.EndCall(result))
                                    {
                                        // Log an event.
                                        this.controlLog.Add(this.config.Log.Add(
                                            LogEventLevel.Verbose,
                                            LogEventType.Success,
                                            ControlSliceRun.logSource.FormatWith(this.slice.Id),
                                            @"The result of the command {0} on PlanetLab node {1} was sent to method '{2}' of tool '{3}' and processed successfully.",
                                            new object[] { subcommand.Command, subcommand.Node.Node.Hostname, info.Method.Name, info.Method.Tool.Info.Name }));
                                    }
                                    else
                                    {
                                        // Log an event.
                                        this.controlLog.Add(this.config.Log.Add(
                                            LogEventLevel.Normal,
                                            LogEventType.Warning,
                                            ControlSliceRun.logSource.FormatWith(this.slice.Id),
                                            @"The result of the command {0} on PlanetLab node {1} was sent to method '{2}' of tool '{3}' but the processing failed.",
                                            new object[] { subcommand.Command, subcommand.Node.Node.Hostname, info.Method.Name, info.Method.Tool.Info.Name }));
                                    }
                                }
                                catch (Exception exception)
                                {
                                    // Log an event.
                                    this.controlLog.Add(this.config.Log.Add(
                                        LogEventLevel.Important,
                                        LogEventType.Error,
                                        ControlSliceRun.logSource.FormatWith(this.slice.Id),
                                        @"The result of the command {0} on PlanetLab node {1} was sent to method '{2}' of tool '{3}' and failed. {4}",
                                        new object[] { subcommand.Command, subcommand.Node.Node.Hostname, info.Method.Name, info.Method.Tool.Info.Name, exception.Message },
                                        exception));
                                }
                                finally
                                {
                                    lock (this.toolSync)
                                    {
                                        // Remove the method state from the list of tool method states.
                                        this.toolStates.Remove(result as ToolMethodState);
                                        // If the list of tool states is empty.
                                        if (this.toolStates.Count == 0)
                                        {
                                            // Set the wait handle.
                                            this.toolWait.Set();
                                        }
                                    }
                                }
                            }, subcommand, this.sessionId, subcommand.Node.Node.Hostname, subcommand.Result);

                        // If the list of tool states is empty.
                        if (this.toolStates.Count == 0)
                        {
                            // Reset the wait handle.
                            this.toolWait.Reset();
                        }
                        // Add the state to the list of tool method states.
                        this.toolStates.Add(asyncState);
                    }
                    catch (Exception exception)
                    {
                        // Log an event.
                        this.controlLog.Add(this.config.Log.Add(
                            LogEventLevel.Important,
                            LogEventType.Error,
                            ControlSliceRun.logSource.FormatWith(this.slice.Id),
                            @"The result of the command {0} on PlanetLab node {1} was sent to method '{2}' of tool '{3}' and failed. {4}",
                            new object[] { subcommand.Command, subcommand.Node.Node.Hostname, info.Method.Name, info.Method.Tool.Info.Name, exception.Message },
                            exception));
                    }
                }
            }
        }