diff --git a/build-site.py b/build-site.py index 25c5d22807e..6e134c2abd4 100755 --- a/build-site.py +++ b/build-site.py @@ -71,6 +71,8 @@ class SphinxBuilder(object): print >> sys.stderr, "are required to make documentation:" print >> sys.stderr, "\tsphinx.application.Sphinx" print >> sys.stderr, "This is usually available from the python-sphinx package" + print >> sys.stderr, "=== Error message received while attempting to build===" + print >> sys.stderr, ie except Exception, ex: print >> sys.stderr, "FAIL! exiting ... (%s)" % ex @@ -80,4 +82,8 @@ class SphinxBuilder(object): if __name__ == '__main__': docgen = SphinxBuilder() -# docgen.build_docs() + + if "view" in sys.argv: + import webbrowser + if not webbrowser.open('html/index.html'): + print >> sys.stderr, "Could not open on your webbrowser." diff --git a/css/screen.css b/css/screen.css deleted file mode 100644 index 4574ea79c5c..00000000000 --- a/css/screen.css +++ /dev/null @@ -1,197 +0,0 @@ -/*****************************************************************************/ -/* -/* Common -/* -/*****************************************************************************/ - -/* Global Reset */ - -* { - margin: 0; - padding: 0; -} - -html, body { - height: 100%; -} - -body { - background-color: white; - font: 13.34px helvetica, arial, clean, sans-serif; - *font-size: small; - text-align: center; -} - -h1, h2, h3, h4, h5, h6 { - font-size: 100%; -} - -h1 { - margin-bottom: 1em; -} - -p { - margin: 1em 0; -} - -a { - color: #00a; -} - -a:hover { - color: black; -} - -a:visited { - color: #a0a; -} - -table { - font-size: inherit; - font: 100%; -} - -/*****************************************************************************/ -/* -/* Home -/* -/*****************************************************************************/ - -ul.posts { - list-style-type: none; - margin-bottom: 2em; -} - - ul.posts li { - line-height: 1.75em; - } - - ul.posts span { - color: #aaa; - font-family: Monaco, "Courier New", monospace; - font-size: 80%; - } - -/*****************************************************************************/ -/* -/* Site -/* -/*****************************************************************************/ - -.site { - font-size: 110%; - text-align: justify; - width: 40em; - margin: 3em auto 2em auto; - line-height: 1.5em; -} - -.title { - color: #a00; - font-weight: bold; - margin-bottom: 2em; -} - - .site .title a { - color: #a00; - text-decoration: none; - } - - .site .title a:hover { - color: black; - } - - .site .title a.extra { - color: #aaa; - text-decoration: none; - margin-left: 1em; - } - - .site .title a.extra:hover { - color: black; - } - - .site .meta { - color: #aaa; - } - - .site .footer { - font-size: 80%; - color: #666; - border-top: 4px solid #eee; - margin-top: 2em; - overflow: hidden; - } - - .site .footer .contact { - float: left; - margin-right: 3em; - } - - .site .footer .contact a { - color: #8085C1; - } - - .site .footer .rss { - margin-top: 1.1em; - margin-right: -.2em; - float: right; - } - - .site .footer .rss img { - border: 0; - } - -/*****************************************************************************/ -/* -/* Posts -/* -/*****************************************************************************/ - -#post { - -} - - /* standard */ - - #post pre { - border: 1px solid #ddd; - background-color: #eef; - padding: 0 .4em; - } - - #post ul, - #post ol { - margin-left: 1.35em; - } - - #post code { - border: 1px solid #ddd; - background-color: #eef; - font-size: 85%; - padding: 0 .2em; - } - - #post pre code { - border: none; - } - - /* terminal */ - - #post pre.terminal { - border: 1px solid black; - background-color: #333; - color: white; - } - - #post pre.terminal code { - background-color: #333; - } - -#related { - margin-top: 2em; -} - - #related h2 { - margin-bottom: 1em; - } diff --git a/css/syntax.css b/css/syntax.css deleted file mode 100644 index e98afc152f9..00000000000 --- a/css/syntax.css +++ /dev/null @@ -1,61 +0,0 @@ -.highlight { background: #ffffff; } -.highlight .c { color: #999988; font-style: italic } /* Comment */ -.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.highlight .k { font-weight: bold } /* Keyword */ -.highlight .o { font-weight: bold } /* Operator */ -.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ -.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ -.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ -.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ -.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ -.highlight .ge { font-style: italic } /* Generic.Emph */ -.highlight .gr { color: #aa0000 } /* Generic.Error */ -.highlight .gh { color: #999999 } /* Generic.Heading */ -.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ -.highlight .go { color: #888888 } /* Generic.Output */ -.highlight .gp { color: #555555 } /* Generic.Prompt */ -.highlight .gs { font-weight: bold } /* Generic.Strong */ -.highlight .gu { color: #aaaaaa } /* Generic.Subheading */ -.highlight .gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc { font-weight: bold } /* Keyword.Constant */ -.highlight .kd { font-weight: bold } /* Keyword.Declaration */ -.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ -.highlight .kr { font-weight: bold } /* Keyword.Reserved */ -.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ -.highlight .m { color: #009999 } /* Literal.Number */ -.highlight .s { color: #d14 } /* Literal.String */ -.highlight .na { color: #008080 } /* Name.Attribute */ -.highlight .nb { color: #0086B3 } /* Name.Builtin */ -.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ -.highlight .no { color: #008080 } /* Name.Constant */ -.highlight .ni { color: #800080 } /* Name.Entity */ -.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ -.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ -.highlight .nn { color: #555555 } /* Name.Namespace */ -.highlight .nt { color: #000080 } /* Name.Tag */ -.highlight .nv { color: #008080 } /* Name.Variable */ -.highlight .ow { font-weight: bold } /* Operator.Word */ -.highlight .w { color: #bbbbbb } /* Text.Whitespace */ -.highlight .mf { color: #009999 } /* Literal.Number.Float */ -.highlight .mh { color: #009999 } /* Literal.Number.Hex */ -.highlight .mi { color: #009999 } /* Literal.Number.Integer */ -.highlight .mo { color: #009999 } /* Literal.Number.Oct */ -.highlight .sb { color: #d14 } /* Literal.String.Backtick */ -.highlight .sc { color: #d14 } /* Literal.String.Char */ -.highlight .sd { color: #d14 } /* Literal.String.Doc */ -.highlight .s2 { color: #d14 } /* Literal.String.Double */ -.highlight .se { color: #d14 } /* Literal.String.Escape */ -.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ -.highlight .si { color: #d14 } /* Literal.String.Interpol */ -.highlight .sx { color: #d14 } /* Literal.String.Other */ -.highlight .sr { color: #009926 } /* Literal.String.Regex */ -.highlight .s1 { color: #d14 } /* Literal.String.Single */ -.highlight .ss { color: #990073 } /* Literal.String.Symbol */ -.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ -.highlight .vc { color: #008080 } /* Name.Variable.Class */ -.highlight .vg { color: #008080 } /* Name.Variable.Global */ -.highlight .vi { color: #008080 } /* Name.Variable.Instance */ -.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ - diff --git a/html/_modules/index.html b/html/_modules/index.html deleted file mode 100644 index b75db85e085..00000000000 --- a/html/_modules/index.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - -
- - -
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009,2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks.puppet import PuppetTaskResult
-from taboot.tasks.rpm import RPMTaskResult
-import re
-
-
-class _FileLikeOutputObject(object):
- """
- A file-like parent class.
- """
-
- import exceptions
- import time as _time
- defaults = None
- starttime = None
-
- def __init__(self, *args, **kwargs):
- """
- Creates an instance of a file-like object.
-
- :Parameters:
- - `args`: all non-keyword arguments.
- - `kwargs`: all keyword arguments.
- """
- import ConfigParser
- import os.path
-
- if _FileLikeOutputObject.defaults is None:
- if os.path.expanduser("~/.taboot.conf"):
- _FileLikeOutputObject.defaults = ConfigParser.ConfigParser()
- _FileLikeOutputObject.defaults.read(
- os.path.expanduser("~/.taboot.conf"))
-
- # Only set the start time once, not for each logger instance
- if _FileLikeOutputObject.starttime is None:
- import datetime
- _FileLikeOutputObject.starttime = datetime.datetime.today()
-
- self._pos = 0L
- self._closed = False
- self._setup(*args, **kwargs)
-
- def _setup(self, *args, **kwargs):
- """
- Implementation specific setup.
-
- :Parameters:
- - `args`: all non-keyword arguments.
- - `kwargs`: all keyword arguments.
- """
- pass
-
- def flush(self):
- """
- We are not buffering so we always just return None.
- """
- return None
-
- def read(self, *args, **kwargs):
- """
- We are an output only file-like object. Raise exception.
-
- :Parameters:
- - `args`: all non-keyword arguments.
- - `kwargs`: all keyword arguments.
- """
- raise self.exceptions.NotImplementedError('Object for output only.')
-
- def tell(self):
- """
- Returns the position of the file-like object.
- """
- return self._pos
-
- def truncate(self, size):
- """
- We are an output only file-like object. Raise exception.
-
- :Parameters:
- - `size`: size to truncate to.
- """
- raise self.exceptions.NotImplementedError(
- 'This does not support truncate.')
-
- def writelines(self, sequence):
- """
- Writes a sequence of lines.
-
- :Parameters:
- - `sequence`: iterable sequence of data to write.
- """
- for item in sequence:
- self.write(item)
-
- def write(self, item):
- """
- Writer wrapper (not rapper, beav). Simply calls _write which is
- implementation specific and updates the position.
-
- :Parameters:
- - `item`: the item to write.
- """
- self._write(item)
- self._pos += 1
-
- def _write(self, item):
- """
- Implementation of writing data.
-
- :Parameters:
- - `item`: the item to write.
- """
- raise self.exceptions.NotImplementedError(
- '_write must be overriden.')
-
- def close(self):
- """
- Close wrapper (again, not rapper, beav). Simply calls _close which
- is implementation specific and updates the closed property.
- """
- self._close()
- self._closed = True
-
- def _close(self):
- """
- Implementation of closing the file-like object.
- By default nothing occurs.
- """
- pass
-
- # Read aliases
- readline = read
- readlines = read
- xreadlines = read
- seek = read
-
- # Read-only Properties
- closed = property(lambda self: self._closed)
- timestamp = property(lambda self: self._time.strftime(
- "%Y-%m-%d %H:%M:%S", self._time.localtime()))
-
-
-[docs]class CLIOutput(_FileLikeOutputObject):
- """
- Output a :class:`taboot.tasks.TaskResult` to the command line
- with pretty formatting and colors.
- """
-
- def _setup(self, host, task):
- """
- Implementation specific setup for outputting to the CLI.
-
- :Parameters:
- - `host`: name of the host
- - `task`: name of the task
- """
- import Colors
- import sys
- self._c = Colors.Colors()
- self._sys = sys
- self._sys.stdout.write('%s:\n' % (
- self._c.format_string(host, 'blue')))
- self._sys.stdout.write('%s Starting Task[%s]\n' % (
- self.timestamp, self._c.format_string(task, 'white')))
-
- def _write(self, result):
- """
- Implementation of writing to the CLI.
-
- :Parameters:
- - `result`: result object to inspect and write
- """
- import types
-
- # Set output color
- output_color = 'red'
- if result.success:
- output_color = 'green'
-
- self._sys.stdout.write("%s:\n" % (
- self._c.format_string(result.host, 'blue')))
- self._sys.stdout.write("%s Finished Task[%s]:\n" % (
- self.timestamp, self._c.format_string(
- result.task, output_color)))
-
- if isinstance(result, PuppetTaskResult):
- # If result is an instance of PuppetTaskResult,
- # colorize the puppet output
- lines = result.output.splitlines()
- for line in lines:
- if re.match('info:', line):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'green'))
- elif re.match('notice:', line):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'blue'))
- elif re.match('warning:', line):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'yellow'))
- elif re.match('err:', line):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'red'))
- else:
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'normal'))
- elif isinstance(result, RPMTaskResult):
- # If result is an instance of RPMTaskResult,
- # colorize the rpm.PostManifest output
- lines = result.output.splitlines()
- for line in lines:
- if line.startswith('-'):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'red'))
- elif line.startswith('+'):
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'green'))
- else:
- self._sys.stdout.write("%s\n" % self._c.format_string(
- line.strip(), 'normal'))
- else:
- # Use standard pass/fall coloring for output
- if isinstance(result.output, types.ListType):
- for r in result.output:
- self._sys.stdout.write("%s\n" % self._c.format_string(
- r.strip(), output_color))
- else:
- self._sys.stdout.write("%s\n" % self._c.format_string(
- result.output.strip(), output_color))
-
-
-[docs]class LogOutput(_FileLikeOutputObject):
- """
- Output a :class:`taboot.tasks.TaskResult` to a logfile.
- """
-
- def _setup(self, host, task, logfile='taboot.log'):
- """
- Implementation specific setup for outputting to a log.
-
- :Parameters:
- - `logfile`: name of the logfile to write to.
- """
- self._logfile = logfile
- if self._logfile in ('-', 'stdout', '1'):
- import sys
- self._log_fd = sys.stdout
- else:
- self._log_fd = open(logfile, 'a')
- self._log_fd.write('%s:\n%s Starting Task[%s]\n\n' % (
- host, self.timestamp, task))
-
- def _write(self, result):
- """
- Implementation of writing to a log.
-
- :Parameters:
- - `result`: result object to inspect and write
- """
- import types
-
- if result.success:
- success_str = 'OK'
- else:
- success_str = 'FAIL'
-
- self._log_fd.write("%s:\n%s Finished Task[%s]: %s\n" % (
- result.host, self.timestamp, result.task, success_str))
-
- if isinstance(result.output, types.ListType):
- for r in result.output:
- self._log_fd.write("%s\n\n" % r.strip())
- else:
- self._log_fd.write("%s\n\n" % result.output.strip())
-
-
-[docs]class EmailOutput(_FileLikeOutputObject):
- """
- Output a :class:`taboot.tasks.TaskResult` to a logfile.
- """
-
- def _setup(self, to_addr, from_addr='taboot@redhat.com'):
- """
- Implementation specific setup for outputting to a log.
-
- :Parameters:
- - `to_addr`: who to send the email to.
- - `from_addr`: who the email is from.
- """
- try:
- import cStringIO as StringIO
- except ImportError, ie:
- import StringIO
- self._to_addr = to_addr
- self._from_addr = from_addr
- self._buffer = StringIO.StringIO()
-
- def _write(self, result):
- """
- Implementation of writing out to an email.
-
- :Parameters:
- - `result`: result object to inspect and write
- """
- if result.success:
- success_str = 'OK'
- else:
- success_str = 'FAIL'
-
- self._buffer.write("%s: %s" % (task_result.task, success_str))
-
-[docs] def flush(self):
- """
- Flushing sends the email with the buffer.
- """
- import smtplib
- from email.mime.text import MIMEText
-
- self._buffer.flush()
- msg = self.MIMEText(self._buffer.read())
- msg['Subject'] = task_result.host
- msg['From'] = self._from_addr
- msg['To'] = self._to_addr
-
- smtp = self.smtplib.SMTP()
- smtp.connect()
- smtp.sendmail(self._from_addr, [self._to_addr], msg.as_string())
- smtp.close()
-
- def __del__(self):
- """
- If the buffer is not empty before destroying, flush.
- """
- if self._buffer.pos < self._buffer.len:
- self.flush()
-
-
-[docs]class HTMLOutput(_FileLikeOutputObject):
- """
- Output a :class:`taboot.tasks.TaskResult` to the command line
- with pretty formatting and colors.
-
- .. document private functions
- .. automethod:: _write
- """
-
- logfile_path = None
-
- def _expand_starttime(self, param):
- """
- Expand any instances of "%s" in `param`
- """
- if '%s' in param:
- p = param % HTMLOutput.starttime
- return p.replace(" ", "-")
- else:
- return param
-
- def _setup(self, host, task, logfile="taboot-%s.html", destdir="."):
- """
- Implementation specific setup for outputting to an HTML file.
-
- :Parameters:
- - `host`: name of the host
- - `task`: name of the task
- - `logfile`: name of the file to log to, '%s' is substituted
- with a datestamp
- - `destdir`: directory in which to save the log file to
- """
- import Colors
- import sys
- import os.path
- import os
-
- _default_logfile = "taboot-%s.html"
- _default_destdir = "."
-
- # Pick if the parameter is changed
- # Pick if above is false and logfile is set in defaults
- # Else, use parameter
- if not logfile == _default_logfile:
- _logfile = logfile
- elif HTMLOutput.defaults is not None and \
- HTMLOutput.defaults.has_option("HTMLOutput", "logfile"):
- _logfile = HTMLOutput.defaults.get("HTMLOutput", "logfile")
- else:
- _logfile = logfile
-
- # Expand %s into a time stamp if necessary
- _logfile = self._expand_starttime(_logfile)
-
- if not destdir == _default_destdir:
- _destdir = destdir
- elif HTMLOutput.defaults is not None and \
- HTMLOutput.defaults.has_option("HTMLOutput", "destdir"):
- _destdir = HTMLOutput.defaults.get("HTMLOutput", "destdir")
- else:
- _destdir = destdir
-
- # Figured it all out, now we join them together!
- self._logfile_path = os.path.join(_destdir, _logfile)
- if not os.path.exists(_destdir):
- os.makedirs(_destdir, 0755)
-
- self._c = Colors.HTMLColors()
- self._log_fd = open(self._logfile_path, 'a')
-
- # Lets only print this when it is set or changed
- if HTMLOutput.logfile_path is None or \
- not HTMLOutput.logfile_path == self._logfile_path:
- sys.stderr.write("Logging HTML Output to %s\n" % \
- self._logfile_path)
- HTMLOutput.logfile_path = self._logfile_path
- sys.stderr.flush()
-
- # Log the start of this task
- name = self._fmt_anchor(self._fmt_hostname(host))
- start_msg = """<p><tt>%s:</tt></p>
-<p><tt>%s Starting Task[%s]\n</tt>""" % (name, self.timestamp, task)
- self._log_fd.write(start_msg)
- self._log_fd.flush()
-
- def _fmt_anchor(self, text):
- """
- Format an #anchor and a clickable link to it
- """
- h = hash(self.timestamp)
- anchor_str = "<a name='%s' href='#%s'>%s</a>" % (h, h, text)
- return anchor_str
-
- def _fmt_hostname(self, n):
- """
- Standardize the hostname formatting
- """
- return "<b>%s</b>" % self._c.format_string(n, 'blue')
-
-[docs] def _write(self, result):
- """
- Write a tasks `result` out to HTML. Handles enhanced stylizing
- for task results that support such as:
-
- - :py:mod:`taboot.tasks.puppet.PuppetTaskResult`
- - :py:mod:`taboot.tasks.rpm.RPMTaskResult`
- """
- import types
- import sys
- import cgi
-
- name = self._fmt_hostname(result.host)
-
- # escape any html in result.output
- result.output = cgi.escape(result.output)
-
- if result.success:
- success_str = self._c.format_string('<b>OK</b>', 'green')
- else:
- success_str = self._c.format_string('<b>FAIL</b>', 'red')
-
- self._log_fd.write("<p><tt>%s:\n</tt></p>\n<p><tt>%s "\
- "Finished Task[%s]: %s</tt></p>\n" %
- (name, self.timestamp, result.task, success_str))
-
- if isinstance(result, PuppetTaskResult):
- # If result is an instance of PuppetTaskResult,
- # colorize the puppet output
- lines = result.output.splitlines()
- for line in lines:
- if re.match('info:', line):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'green'))
- elif re.match('notice:', line):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'blue'))
- elif re.match('warning:', line):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'yellow'))
- elif re.match('err:', line):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'red'))
- else:
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'normal'))
- self._log_fd.write("<br /><br />\n")
- elif isinstance(result, RPMTaskResult):
- # If result is an instance of RPMTaskResult,
- # colorize the rpm.PostManifest output
- lines = result.output.splitlines()
- for line in lines:
- if line.startswith('-'):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'red'))
- elif line.startswith('+'):
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'green'))
- else:
- self._log_fd.write("%s<br />\n" %
- self._c.format_string(line.strip(),
- 'normal'))
- self._log_fd.write("<br /><br />\n")
- else:
- # Use standard pass/fall coloring for output
- if isinstance(result.output, types.ListType):
- for r in result.output:
- self._log_fd.write("<pre>%s</pre>\n<br /><br />\n" %
- r.strip())
- else:
- self._log_fd.write("<pre>%s</pre>\n<br /><br />\n" %
- result.output.strip())
-
- self._log_fd.flush()
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009-2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-import threading
-from taboot.util import instantiator
-from log import *
-
-
-[docs]class Runner(object):
- """
- The Runner, responsible for running a taboot job.
- """
-
- import threading
- import taboot.output
-
- def __init__(self, script, config, expand_globs=True):
- """
- :Parameters:
- - `script`: an instance of tabootScript
-
- - `expand_globs`: whether to expand the globs or just leave
- them as is.
- """
- self._config = config
- self._hosts = script.getHosts()
- self._tasks = script.getTaskTypes()
- self._output = script.getOutputTypes()
- self._task_q = []
- self._fail_event = self.threading.Event()
-
- if expand_globs:
- self._hosts = self._expand_globs()
- log_debug("Will operate on %s host(s).", len(self._hosts))
-
- # Prefight threading
- self._preflight_tasks = script.getPreflightTypes()
- self._preflight_semaphore = self.threading.Semaphore(
- len(self._hosts))
- self._preflight_tasks_q = []
-
- # Main task-body threading
- if script.getConcurrency() == "all":
- self._concurrency = len(self._hosts)
- else:
- self._concurrency = int(script.getConcurrency())
- log_debug("Setting task-body concurrency to %s.",
- self._concurrency)
- self._semaphore = self.threading.Semaphore(self._concurrency)
-
- def _run_preflight(self):
- """
- Run the jobs in a prefilght section.
- """
- import signal
-
- rdy_msg = "\nPre-Flight complete, press enter to continue: "
-
- for host in self._hosts:
- t = TaskRunner(host, self._preflight_tasks,
- self._preflight_semaphore,
- self._output, self._fail_event)
- t.start()
- self._preflight_tasks_q.append(t)
-
- signal.signal(signal.SIGINT, self.__sighandler)
-
- for task in self._task_q:
- while task.isAlive():
- task.join(0.1)
-
- while len(self.threading.enumerate()) > 1:
- # Even though all the threads may have been joined we
- # should still wait for them to terminate. If we don't
- # wait for that we will likely see the 'continue?' prompt
- # before the preflight output gets a chance to print.
- pass
-
- if not self._config["onlypreflight"]:
- ready = raw_input(rdy_msg)
-
- if self._fail_event.isSet():
- return False
- return True
-
- def _run_tasks(self):
- """
- Run a task body.
- """
- import signal
-
- for host in self._hosts:
- t = TaskRunner(host, self._tasks, self._semaphore, self._output,
- self._fail_event)
- t.start()
- self._task_q.append(t)
-
- signal.signal(signal.SIGINT, self.__sighandler)
-
- for task in self._task_q:
- while task.isAlive():
- task.join(0.1)
-
- if self._fail_event.isSet():
- return False
- return True
-
-[docs] def run(self):
- """
- Run the preflight/tasks-body
- """
-
- if len(self._preflight_tasks) > 0:
- if not self._run_preflight():
- return False
-
- if self._config["onlypreflight"]:
- return True
- else:
- return self._run_tasks()
-
- def _expand_globs(self):
- """
- Returns the hosts that expand out from globs.
-
- This is kind of a dirty hack around how Func returns minions
- in an arbitrary order.
- """
-
- import func.overlord.client as fc
-
- if not self._hosts:
- return []
- if isinstance(self._hosts, basestring):
- glob = self._hosts
- c = fc.Client(glob)
- return c.list_minions()
- else:
- # Iterate over each given item, expand it, and then push
- # it onto our list. But only if it doesn't exist already!
- found_hosts = []
- for h in self._hosts:
- c = fc.Client(h)
- new_hosts = filter(lambda h: h not in found_hosts,
- c.list_minions())
- found_hosts.extend(new_hosts)
- # for found_host in c.list_minions():
- # h = filter
- # if not found_host in found_hosts:
- # found_hosts.append(found_host)
- return found_hosts
-
- def __sighandler(self, signal, frame):
- """
- If we get SIGINT on the CLI, we need to quit all the threads
- in our process group
- """
- import os
- import signal
-
- os.killpg(os.getpgid(0), signal.SIGQUIT)
-
-
-[docs]class TaskRunner(threading.Thread):
- """
- TaskRunner is responsible for executing a set of tasks for a
- single host in it's own thread.
- """
-
- from taboot.tasks import TaskResult as _TaskResult
-
- def __init__(self, host, tasks, semaphore, output, fail_event):
- """
- :Parameters:
- - `host`: The host to operate on.
- - `tasks`: A list of tasks to perform (see :class:`Runner`)
- - `semaphore`: The :class:`Runner` semaphore to acquire before
- executing
- - `output`: A list of outputters to use. (see :class:`Runner`)
- - `fail_event`: The :class:`Runner` failure event to check before
- executing. If this event is set when the TaskRunner acquires the
- semaphore, then the TaskRunner is effectively a no-op.
- """
-
- threading.Thread.__init__(self)
- self._host = host
- self._tasks = tasks
- self._semaphore = semaphore
- self._output = output
- self._fail_event = fail_event
- self._state = {}
-
- def __getitem__(self, key):
- return self._state[key]
-
- def __setitem__(self, key, value):
- self._state[key] = value
-
-[docs] def run(self):
- """
- Run the task(s) for the given host. If the fail_event passed
- from the invoking :class:`Runner` is set, do nothing.
- """
-
- self._semaphore.acquire()
-
- if self._fail_event.isSet():
- # some other host has bombed
- self._semaphore.release()
- return
-
- try:
- host_success = True
- for task in self._tasks:
- result = self.run_task(task)
- if not result.success and not result.ignore_errors:
- host_success = False
- break
- except:
- self._bail_failure()
- raise
-
- if not host_success:
- self._bail_failure()
- else:
- self._semaphore.release()
- return host_success
-
- def _bail_failure(self):
- """
- Die nicely :)
- """
-
- self._fail_event.set()
- self._semaphore.release()
-
-[docs] def run_task(self, task):
- """
- Run a single task. Sets task.host and then invokes the run
- method for the task.
-
- :Parameters:
- - `task`: The task to run
- """
-
- ignore_errors = False
- if 'ignore_errors' in task:
- if task['ignore_errors'] in ('True', 'true', 1):
- ignore_errors = True
-
- task = instantiator(task, 'taboot.tasks', host=self._host)
-
- outputters = []
- for o in self._output:
- instance = instantiator(o, 'taboot.output',
- host=self._host,
- task=task)
- outputters.append(instance)
-
- try:
- result = task.run(self)
- except Exception, e:
- result = self._TaskResult(task, output=repr(e))
-
- for o in outputters:
- o.write(result)
-
- result.ignore_errors = ignore_errors
- return result
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009-2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-[docs]class BaseTask(object):
- """
- Base Task. All tasks should inherit from this. It does the
- pretty string representation of a task and allows setting of the
- host attribute.
- """
-
- def __init__(self, *args, **kwargs):
- self._name = str(type(self))
- next = self._name.index("'") + 1
- self._name = self._name[next:self._name.rindex("'")]
- self._args = args
- self.host = kwargs['host']
- self.concurrentFriendly = True
-
- def __repr__(self):
- return "%s%s" % (self._name, self._args)
-
- def _sethost(self, host):
- self._host = host
-
- def _gethost(self):
- if hasattr(self, '_host'):
- return self._host
- else:
- return None
-
- host = property(_gethost, _sethost)
-
-
-[docs]class FuncTask(BaseTask):
- """
- A Func-based task. All tasks that utilize Func should inherit
- from this.
- """
-
- import func.jobthing
- from taboot.errors import FuncException as _FuncException
-
- def _func_run(self, func_command, *args):
- """
- Execute a command via Func.
-
- :Paramaters:
- - `func_command` String representing func command to run
- (e.g. 'command.run')
- - `*args` Argument(s) to be used when invoking the func command
- """
-
- import time
- import func.overlord.client
- try:
- client = func.overlord.client.Client(self._host, async=True)
- job_id = reduce(lambda x, y: getattr(x, y),
- func_command.split('.'),
- client)(*args)
- # poll until the job completes
- (status, result) = (None, None)
- while status != self.func.jobthing.JOB_ID_FINISHED:
- (status, result) = client.job_status(job_id)
- time.sleep(1)
- result = result[self._host]
- if result[0] == 'REMOTE_ERROR':
- raise self._FuncException(result[1:])
- return (True, result)
- except Exception, ex:
- return (False, repr(ex))
-
-[docs] def run(self, runner):
- """
- Run the FuncTask.
-
- :Parameters:
- - `runner` A :class:`taboot.runner.TaskRunner` instance
- """
-
- if not hasattr(self, '_command'):
- raise Exception("You MUST set self._command when instantiating " +
- "a subclass of FuncTask!")
-
- result = self._func_run(self._command, *(self._args))
-
- if result[0]:
- # command executed successfully as far as "func success"
- return self._process_result(result[1])
- else:
- return TaskResult(self, success=False, output=result[1])
-
-
-[docs]class FuncErrorTask(FuncTask):
- """
- Explicitly cause a func remote error by calling a bad command.
- Used to verify func exception handling works as expected
- """
-
- def __init__(self, *args, **kwargs):
- super(FuncErrorTask, self).__init__(*args, **kwargs)
- self._command = 'thiscommand.DoesntExist'
-
-
-[docs]class TaskResult(object):
- """
- An encapsulation of the results of a task. This is passed to one
- or more instances of output classes (derived from BaseOutput) in
- order to display to the user.
- """
-
- def __init__(self, task, success=False, output='', ignore_errors=False):
- """
- :Parameters:
- - `task`: The task object represented by this result
- - `success`: Whether the task completed successfully or not
- - `output`: Any text output produced by the task
- """
-
- if hasattr(task, 'host'):
- self._host = task.host
- self._task = repr(task)
- self._taskObj = task
- self._success = success
- self._output = output
- self._ignore_errors = ignore_errors
-
- def _gettask(self):
- return self._task
-
- def _gettaskObj(self):
- return self._taskObj
-
- def _settask(self, t):
- self._task = repr(t)
-
- def _getsuccess(self):
- return self._success
-
- def _setsuccess(self, success):
- self._success = success
-
- def _getoutput(self):
- return self._output
-
- def _setoutput(self, output):
- self._output = output
-
- def _getignore_errors(self):
- return self._ignore_errors
-
- def _setignore_errors(self, ignore_errors):
- self._ignore_errors = ignore_errors
-
- def _gethost(self):
- return self._host
-
- task = property(_gettask, _settask)
- success = property(_getsuccess, _setsuccess)
- output = property(_getoutput, _setoutput)
- ignore_errors = property(_getignore_errors, _setignore_errors)
- host = property(_gethost)
- taskObj = property(_gettaskObj)
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009,2010, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import FuncTask, TaskResult
-
-
-[docs]class Run(FuncTask):
- """
- Run arbitrary commands via Func. The arguments passed to __init__
- are used to execute func.overlord.Client.command.run(args).
-
- :Parameters:
- - `command`: Command to run on the remote host
- """
-
- def __init__(self, command, **kwargs):
- super(Run, self).__init__(command, **kwargs)
- self._command = 'command.run'
-
- def _process_result(self, result):
- t = TaskResult(self)
- if result[0] == 0:
- t.success = True
- else:
- t.success = False
- t.output = result[1]
- return t
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009-2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import BaseTask, FuncTask, TaskResult
-
-JK_ENABLE = 0
-JK_DISABLE = 1
-JK_STOP = 2
-
-
-class ToggleHost(FuncTask):
- def __init__(self, action, proxyhost, **kwargs):
- super(ToggleHost, self).__init__(proxyhost, **kwargs)
- self._action = action
- if action == JK_ENABLE:
- self._command = 'taboot.modjk.enable_host'
- elif action == JK_DISABLE:
- self._command = 'taboot.modjk.disable_host'
- elif action == JK_STOP:
- self._command = 'taboot.modjk.stop_host'
- else:
- raise Exception("Undefined toggle action")
-
- def _process_result(self, result):
- t = TaskResult(self)
- if len(result) > 0:
- t.success = True
- if self._action == JK_ENABLE:
- verb = 'Enabled'
- elif self._action == JK_DISABLE:
- verb = 'Disabled'
- elif self._action == JK_STOP:
- verb = 'Stopped'
-
- t.output = "%s AJP on the following balancer/worker " \
- "pairs:\n" % verb
- for balancer, worker in result:
- t.output += "%s: %s\n" % (balancer, worker)
- else:
- t.success = False
- t.output = "Failed to find worker host"
- return t
-
-
-class JKBaseTask(BaseTask):
- def __init__(self, proxies, action, **kwargs):
- super(JKBaseTask, self).__init__(**kwargs)
- from sys import modules
- self.proxies = proxies
- self.jkaction = getattr(modules[self.__module__], "JK_%s" %
- action.upper())
-
- def run(self, runner):
- output = ""
- success = True
- for proxy in self.proxies:
- toggler = ToggleHost(self.jkaction, self._host, host=proxy)
- result = toggler.run(runner)
- output += "%s:\n" % proxy
- output += "%s\n" % result.output
- if result.success == False:
- success = False
- break
- return TaskResult(self, success=success, output=output)
-
-
-[docs]class OutOfRotation(JKBaseTask):
- """
- Remove an AJP node from rotation on a proxy via modjkapi access on
- the proxy with func.
-
- :Parameters:
- - `proxies`: A list of URLs to AJP jkmanage interfaces
- """
- def __init__(self, proxies, action="stop", **kwargs):
- super(OutOfRotation, self).__init__(proxies, action, **kwargs)
-
-
-[docs]class InRotation(JKBaseTask):
- """
- Put an AJP node in rotation on a proxy via modjkapi access on
- the proxy with func.
-
- :Parameters:
- - `proxies`: A list of URLs to AJP jkmanage interfaces
- """
- def __init__(self, proxies, action="enable", **kwargs):
- super(InRotation, self).__init__(proxies, action, **kwargs)
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009-2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import BaseTask, TaskResult, FuncTask
-import taboot.errors
-import sys
-
-
-[docs]class NagiosBase(FuncTask):
- """
- All subsequent Nagios tasks are subclasses of this.
-
- Code note: Because a `FuncTask` expects to make connections to
- `self.host` we need to switch `nagios_url` with `self.host` and
- pass the original `self.host` as an argument.
-
- .. versionchanged:: 0.2.14
-
- The previous version specified the `nagios_url` parameter as a
- URL. To facilitate transitions we automatically correct URLs
- into hostnames.
-
- Previously the `service` key was defined as a scalar, like
- "HTTP" or "JBOSS". This version accepts that key as a scalar OR
- as a list and "does the right thing" in each case.
- """
-
- def _fix_nagios_url(self, nagios_url):
- """
- For backwards compatability we accept a Nagios URL that
- identifies an HTTP resource.
-
- This method will take a string like http://foo.com/nagios/cmd.cgi
- and return just the hostname component ("foo.com").
- """
- import re
- return re.sub(r'(https?://)([^/]+)(.*)', r'\2', nagios_url)
-
- def _process_result(self, result):
- t = TaskResult(self)
-
- if result.startswith("Fail: "):
- t.success = False
- else:
- t.sucess = True
- t.success = True
- t.output = result
- return t
-
-
-[docs]class DisableAlerts(NagiosBase):
- """
- Disable alerts for a host on a nagios instance
- """
-
- def __init__(self, nagios_url, **kwargs):
- """
- :Parameters:
- - `nagios_url`: Hostname of the Nagios server.
- """
- target_host = kwargs['host']
- kwargs['host'] = self._fix_nagios_url(nagios_url)
- super(DisableAlerts, self).__init__(target_host, **kwargs)
- self._command = 'nagios.disable_host_notifications'
-
-
-[docs]class EnableAlerts(NagiosBase):
- """
- Enable alerts for a host on a nagios instance
- """
-
- def __init__(self, nagios_url, **kwargs):
- """
- :Parameters:
- - `nagios_url`: Hostname of the Nagios server.
- """
- target_host = kwargs['host']
- kwargs['host'] = self._fix_nagios_url(nagios_url)
- super(EnableAlerts, self).__init__(target_host, **kwargs)
- self._command = 'nagios.enable_host_notifications'
-
-
-[docs]class ScheduleDowntime(NagiosBase):
- """
- Schedule downtime for services on a host in Nagios
- """
-
- def __init__(self, nagios_url, service='HOST', minutes=30, **kwargs):
- """
- :Parameters:
- - `nagios_url`: Hostname of the Nagios server.
- - `service`: Service or list of services to schedule down for.
- - `minutes`: The number of minutes to schedule downtime
- for. Default is 30.
- """
- import types
- target_host = kwargs['host']
- kwargs['host'] = self._fix_nagios_url(nagios_url)
-
- if isinstance(service, types.StringTypes):
- service = [service]
-
- if not isinstance(minutes, types.IntType):
- if isinstance(minutes, types.FloatType):
- minutes = int(minutes)
- else:
- raise TypeError("Invalid data given for minutes.",
- "Expecting int type.",
- "Got '%s'." % minutes)
-
- super(ScheduleDowntime, self).__init__(target_host, service,
- minutes, **kwargs)
-
- if service == 'HOST':
- self._command = "nagios.schedule_host_downtime"
- else:
- self._command = 'nagios.schedule_svc_downtime'
-
- def _process_result(self, result):
- t = TaskResult(self)
- t.success = True
- for r in result:
- if r.startswith("Fail: "):
- t.success = t.success & False
- else:
- t.sucess = t.success & True
- t.output = result
- return t
-
-
-[docs]class SilenceHost(NagiosBase):
- """
- Silence all notifications for a given host
- """
-
- def __init__(self, nagios_url, **kwargs):
- """
- :Parameters:
- - `nagios_url`: Hostname of the Nagios server.
- """
- target_host = kwargs['host']
- kwargs['host'] = self._fix_nagios_url(nagios_url)
- super(SilenceHost, self).__init__(target_host, **kwargs)
- self._command = 'nagios.silence_host'
-
- def _process_result(self, result):
- t = TaskResult(self)
- t.success = True
- for r in result:
- if r.startswith("Fail: "):
- t.success = t.success & False
- else:
- t.sucess = t.success & True
- t.output = result
- return t
-
-
-[docs]class UnsilenceHost(NagiosBase):
- """
- Unsilence all notifications for a given host
- """
-
- def __init__(self, nagios_url, **kwargs):
- """
- :Parameters:
- - `nagios_url`: Hostname of the Nagios server.
- """
- target_host = kwargs['host']
- kwargs['host'] = self._fix_nagios_url(nagios_url)
- super(UnsilenceHost, self).__init__(target_host, **kwargs)
- self._command = 'nagios.unsilence_host'
-
- def _process_result(self, result):
- t = TaskResult(self)
- t.success = True
- for r in result:
- if r.startswith("Fail: "):
- t.success = t.success & False
- else:
- t.sucess = t.success & True
- t.output = result
- return t
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import BaseTask
-from taboot.tasks import TaskResult
-import time
-
-
-[docs]class PollTask(BaseTask):
- """
- PollTask. A task that will poll a particular task until the task
- succeeds or until max_attempts is reached.
-
- :Parameters:
- - `task` The task to poll.
- - `sleep_interval` The number of seconds to wait before trying
- the task again.
- - `max_attempts` The maximum number of attempts that the task
- should be run.
- - `fail_task` The task to run when max_attempts has been exhausted.
- If no fail_task is provided, then a simple TaskResult
- indicating failure is returned.
- """
-
- def __init__(self, task, sleep_interval=5, max_attempts=6,
- fail_task=None, **kwargs):
- super(PollTask, self).__init__(**kwargs)
- self._task = task
- self._sleep_interval = sleep_interval
- self._max_attempts = max_attempts
- self._fail_task = fail_task
-
- def run(self, runner):
- for x in range(self._max_attempts):
- result = runner.run_task(self._task)
- if result.success:
- return result
- time.sleep(self._sleep_interval)
-
- # exhausted max_attempts
- if self._fail_task != None:
- return runner.run_task(self._fail_task)
- else:
- # return a "failed" TaskResult, stop executing further tasks
- return TaskResult(self, success=False,
- output="Max attempts of %s reached running %s" %
- (self._max_attempts, repr(self._task)))
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009-2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import command, TaskResult
-import puppet
-
-
-[docs]class PuppetBase(command.Run):
- """
- Base class for puppet commands
- """
-
- def __init__(self, pcmd, **kwargs):
- super(PuppetBase, self).__init__(pcmd, **kwargs)
-
-
-[docs]class Run(PuppetBase):
- """
- Run 'puppetd --test || true'
-
- :Optional Parameters:
- - `server`: Puppetmaster to run against
- - `noop`: If this should be a noop run (Boolean)
- - `safe`: Abort if puppet errors (Boolean)
-
- See also: :py:meth:`taboot.tasks.Puppet.SafeRun`
- """
-
- def __init__(self, server="", noop=False, safe=False, **kwargs):
- pcmd = "puppetd --test --color=false"
- if server != "":
- pcmd += " --server=%s" % server
- if noop == True:
- pcmd += " --noop"
- if safe == False:
- # If safe is False, ignore the return code of the puppet run
- pcmd += " || true"
- super(Run, self).__init__(pcmd, **kwargs)
-
- def run(self, runner):
- result = super(Run, self).run(runner)
- return PuppetTaskResult(result.taskObj, result.success,
- result.output, result.ignore_errors)
-
-
-[docs]class SafeRun(puppet.Run):
- """
- Run 'puppetd --test'.
-
- How is this different from Run? Simple, it will abort everything
- if puppet returns with a non-zero exit status.
- """
-
- def __init__(self, server="", **kwargs):
- super(SafeRun, self).__init__(server, safe=True, **kwargs)
-
-
-[docs]class Enable(PuppetBase):
- """
- Run 'puppetd --enable'.
- """
-
- def __init__(self, **kwargs):
- super(Enable, self).__init__('puppetd --enable', **kwargs)
-
-
-[docs]class Disable(PuppetBase):
- """
- Run 'puppetd --disable'.
- """
-
- def __init__(self, **kwargs):
- super(Disable, self).__init__('puppetd --disable', **kwargs)
-
-
-[docs]class DeleteLockfile(PuppetBase):
- """
- Remove the puppet lock file.
- """
-
- def __init__(self, **kwargs):
- PUPPET_LOCKFILE = "/var/lib/puppet/state/puppetdlock"
- super(DeleteLockfile, self).__init__("rm -f %s" % PUPPET_LOCKFILE,
- **kwargs)
-
-
-[docs]class PuppetTaskResult(TaskResult):
- """
- Wrapper around TaskResult to be able to differentiate in output class
- """
-
- def __init__(self, task, success=False, output='', ignore_errors=False):
- super(PuppetTaskResult, self).__init__(task, success, output,
- ignore_errors)
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009,2010, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import command, TaskResult
-
-
-[docs]class RPMBase(command.Run):
- """
- Base class for rpm commands
- """
-
- def __init__(self, pcmd, **kwargs):
- super(RPMBase, self).__init__(pcmd, **kwargs)
-
-
-[docs]class PreManifest(command.Run):
- """
- Gather list of installed RPMs. A later invocation of :class:`PostManifest`
- is then used to output the RPMs changed during intermediate tasks.
- """
-
- def __init__(self, **kwargs):
- super(PreManifest, self).__init__('rpm -qa | sort', **kwargs)
-
-[docs] def run(self, runner):
- """
- Override the default :class:`command.Run` to strip the output
- from the result because we're really not interested in the
- contents of the pre-manifest; we just want to collect it to
- compare later on with PostManifest.
- """
-
- result = super(PreManifest, self).run(runner)
- runner['rpm.PreManifest'] = result.output
- result.output = ''
- return result
-
-
-[docs]class PostManifest(command.Run):
- """
- Gather list of installed RPMs and compare against a previously
- taken :class:`PreManifest`
- """
-
- from difflib import Differ as _Differ
-
- def __init__(self, **kwargs):
- super(PostManifest, self).__init__('rpm -qa | sort', **kwargs)
-
-[docs] def run(self, runner):
- """
- The runner that gets passed in contains state that can be
- access via dict-like access. PreManifest uses this to write
- to the rpm.Premanifest field. So we'll check to make sure the
- pre-manifest is there by looking for that state.
- """
- try:
- pre_manifest = runner['rpm.PreManifest']
- except:
- return TaskResult(self, success=False,
- output="You must use PreManifest before PostManifest")
-
- # ok, so now we have something to compare against so we get
- # new state...
- result = super(command.Run, self).run(runner)
-
- old_list = pre_manifest.splitlines(1)
- new_list = result.output.splitlines(1)
-
- differ = self._Differ()
- diff_output = list(differ.compare(old_list, new_list))
- diff_output = [line for line in diff_output if line[0] in ('+', '-')]
-
- result.output = ''.join(diff_output)
-
- return RPMTaskResult(result.taskObj, result.success,
- result.output, result.ignore_errors)
-
-
-[docs]class RPMTaskResult(TaskResult):
- """
- Wrapper around TaskResult to be able to differentiate in output class
- """
-
- def __init__(self, task, success=False, output='', ignore_errors=False):
- super(RPMTaskResult, self).__init__(task, success, output,
- ignore_errors)
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009,2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import command
-
-
-
-[docs]class Start(ServiceBase):
- """
- Start a service.
-
- Arguments:
- - ``service`` - The service to start.
- """
-
- def __init__(self, service, **kwargs):
- super(Start, self).__init__('service %s start' % service, **kwargs)
-
-
-[docs]class Stop(ServiceBase):
- """
- Stop a service.
-
- Arguments:
- - ``service`` - The service to stop.
- """
-
- def __init__(self, service, **kwargs):
- super(Stop, self).__init__('service %s stop' % service, **kwargs)
-
-
-[docs]class Restart(ServiceBase):
- """
- Restart a service.
-
- Arguments:
- - ``service`` - The service to restart.
- """
-
- def __init__(self, service, **kwargs):
- super(Restart, self).__init__('service %s restart' % service, **kwargs)
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2011, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import BaseTask, TaskResult
-from termios import tcflush, TCIFLUSH
-import sys
-
-
-[docs]class SleepBase(BaseTask):
- """
- Base class for task-queue pausing classes.
- """
-
- def __init__(self, **kwargs):
- super(SleepBase, self).__init__(**kwargs)
-
-
-[docs]class Seconds(SleepBase):
- """
- Halt task processing on a node for a certain number of seconds.
-
- :Parameters:
- - `seconds`: Number of seconds to halt execution for.
- """
-
- def __init__(self, seconds=60, **kwargs):
- super(Seconds, self).__init__(**kwargs)
- self._seconds = seconds
-
- def run(self, runner):
- import time
- time.sleep(self._seconds)
- return TaskResult(self, success=True,
- output="Paused for %s seconds" %
- self._seconds)
-
-
-[docs]class Minutes(SleepBase):
- """
- Halt task processing on a node for a certain number of minutes.
-
- :Parameters:
- - `minutes`: Number of minutes to halt execution for.
- """
-
- def __init__(self, minutes=1, **kwargs):
- super(Minutes, self).__init__(**kwargs)
- self._minutes = minutes
- self._seconds = minutes * 60
-
- def run(self, runner):
- import time
- time.sleep(self._seconds)
- return TaskResult(self, success=True,
- output="Paused for %s minutes" %
- self._minutes)
-
-
-[docs]class WaitOnInput(SleepBase):
- """
- Halt task processing on a node until the user presses enter.
-
- :Parameters:
- - `message`: The message to prompt on the CLI.
- """
-
- def __init__(self, message="Press enter to continue\n", **kwargs):
- super(WaitOnInput, self).__init__(**kwargs)
- self._message = message
- self.concurrentFriendly = False
-
- def run(self, runner):
- import time
- start = time.time()
- tcflush(sys.stdin, TCIFLUSH)
- raw_input(self._message)
- return TaskResult(self, success=True,
- output="Paused for %s seconds" %
- (time.time() - start))
-
-# -*- coding: utf-8 -*-
-# Taboot - Client utility for performing deployments with Func.
-# Copyright © 2009, Red Hat, Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-from taboot.tasks import command, BaseTask
-
-
-[docs]class YumBase(BaseTask):
- """
- Base class for all Yum-related tasks.
- """
-
- def __init__(self, packages):
- if isinstance(packages, list):
- self._packages = packages
- self._packages_str = ' '.join(packages)
- else:
- self._packages = [packages]
- self._packages_str = packages
-
-
-[docs]class Install(YumBase, command.Run):
- """
- Install one or more packages.
- """
-
- def __init__(self, packages, **kwargs):
- """
- :Parameters:
- - `packages`: A list of packages to install
- """
- YumBase.__init__(self, packages)
- command.Run.__init__(self, 'yum install -y %s' % self._packages_str,
- **kwargs)
-
-
-[docs]class Update(YumBase, command.Run):
- """
- Update one or more packages.
- """
-
- def __init__(self, packages=[], **kwargs):
- """
- :Parameters:
- - `packages`: A list of packages to update. If `packages` is empty,
- update all packages on the system.
- """
- YumBase.__init__(self, packages)
- command.Run.__init__(self, 'yum update -y %s' % self._packages_str,
- **kwargs)
-
-
-[docs]class Remove(YumBase, command.Run):
- """
- Remove one or more packages.
- """
-
- def __init__(self, packages, **kwargs):
- """
- :Parameters:
- - `packages`: A list of packages to remove.
- """
- YumBase.__init__(self, packages)
- command.Run.__init__(self, 'yum remove -y %s' % self._packages_str,
- **kwargs)
-