diff --git a/doc/build/html/_modules/index.html b/doc/build/html/_modules/index.html index 4e1196b..8f4dc7f 100644 --- a/doc/build/html/_modules/index.html +++ b/doc/build/html/_modules/index.html @@ -6,7 +6,7 @@ - Overview: module code — kollacli 1.0.0.dev386 documentation + Overview: module code — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -108,7 +108,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • @@ -214,7 +214,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/client.html b/doc/build/html/_modules/kollacli/api/client.html index 6a0ca82..4590517 100644 --- a/doc/build/html/_modules/kollacli/api/client.html +++ b/doc/build/html/_modules/kollacli/api/client.html @@ -6,7 +6,7 @@ - kollacli.api.client — kollacli 1.0.0.dev386 documentation + kollacli.api.client — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -60,7 +60,13 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import kollacli.i18n as u + import logging +import os +import sys + +from logging.handlers import RotatingFileHandler from kollacli.api.async import AsyncApi from kollacli.api.deploy import DeployApi @@ -71,6 +77,9 @@ from kollacli.api.service import ServiceApi from kollacli.api.support import SupportApi +CONSOLE_MESSAGE_FORMAT = '%(message)s' +LOG_FILE_MESSAGE_FORMAT = \ + '[%(asctime)s] %(levelname)-8s %(name)s %(message)s' LOG = logging.getLogger(__name__) @@ -85,8 +94,70 @@ SupportApi, ): + def __init__(self): + self._configure_logging() +
    [docs] def base_call(self): - LOG.info('base call')
    + LOG.info('base call') + +
    [docs] def enable_console_logging(self, level, enable=True): + """enable/disable console logging for the api + + enable: True/False + level: logging.INFO, logging.DEBUG, logging.WARNING, + logging.CRITICAL... + """ + root_logger = logging.getLogger('') + console = logging.StreamHandler(sys.stderr) + if enable: + console.setLevel(level) + formatter = logging.Formatter(CONSOLE_MESSAGE_FORMAT) + console.setFormatter(formatter) + root_logger.addHandler(console) + else: + root_logger.removeHandler(console) +
    + def _configure_logging(self): + root_logger = logging.getLogger('') + root_logger.setLevel(logging.DEBUG) + + handler_found = False + handlers = root_logger.handlers + for handler in handlers: + if isinstance(handler, RotatingFileHandler): + handler_found = True + break + if not handler_found: + # logger has not been set up + try: + rotate_handler = RotatingFileHandler( + os.path.join(os.path.abspath(os.sep), + 'var', 'log', 'kolla', 'kolla.log'), + maxBytes=self._get_kolla_log_file_size(), + backupCount=4) + except IOError as e: + # most likely the caller is not part of the kolla group + raise IOError(u._('Permission denied to run the kolla client.' + '\nPlease add user to the kolla group and ' + 'then log out and back in. {error}') + .format(error=str(e))) + + formatter = logging.Formatter(LOG_FILE_MESSAGE_FORMAT) + rotate_handler.setFormatter(formatter) + rotate_handler.setLevel(logging.INFO) + root_logger.addHandler(rotate_handler) + + def _get_kolla_log_file_size(self): + envvar = 'KOLLA_LOG_FILE_SIZE' + size_str = os.environ.get(envvar, '500000') + try: + size = int(size_str) + except Exception: + LOG.error(('Environmental variable ({env_var}) is not an ' + 'integer ({log_size}).') + .format(env_var=envvar, log_size=size_str)) + size = 50000 + return size @@ -120,7 +191,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/deploy.html b/doc/build/html/_modules/kollacli/api/deploy.html index 4393855..7604751 100644 --- a/doc/build/html/_modules/kollacli/api/deploy.html +++ b/doc/build/html/_modules/kollacli/api/deploy.html @@ -6,7 +6,7 @@ - kollacli.api.deploy — kollacli 1.0.0.dev386 documentation + kollacli.api.deploy — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -119,7 +119,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/exceptions.html b/doc/build/html/_modules/kollacli/api/exceptions.html index 5dfd548..90d2bc5 100644 --- a/doc/build/html/_modules/kollacli/api/exceptions.html +++ b/doc/build/html/_modules/kollacli/api/exceptions.html @@ -6,7 +6,7 @@ - kollacli.api.exceptions — kollacli 1.0.0.dev386 documentation + kollacli.api.exceptions — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -160,7 +160,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/group.html b/doc/build/html/_modules/kollacli/api/group.html index f9c51cc..aac0958 100644 --- a/doc/build/html/_modules/kollacli/api/group.html +++ b/doc/build/html/_modules/kollacli/api/group.html @@ -6,7 +6,7 @@ - kollacli.api.group — kollacli 1.0.0.dev386 documentation + kollacli.api.group — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -274,7 +274,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/host.html b/doc/build/html/_modules/kollacli/api/host.html index c888ad6..148b1a5 100644 --- a/doc/build/html/_modules/kollacli/api/host.html +++ b/doc/build/html/_modules/kollacli/api/host.html @@ -6,7 +6,7 @@ - kollacli.api.host — kollacli 1.0.0.dev386 documentation + kollacli.api.host — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -228,7 +228,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/job.html b/doc/build/html/_modules/kollacli/api/job.html index c84701a..3a9e467 100644 --- a/doc/build/html/_modules/kollacli/api/job.html +++ b/doc/build/html/_modules/kollacli/api/job.html @@ -6,7 +6,7 @@ - kollacli.api.job — kollacli 1.0.0.dev386 documentation + kollacli.api.job — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -78,7 +78,10 @@
    [docs] def get_status(self): """Get status of job - :return: None if job still running, 0 if job succeeded, 1 if job failed + :return: None: job is still running + 0: job succeeded + 1: job failed + 2: job killed by user :rtype: int or None """ return self._ansible_job.get_status() @@ -97,7 +100,11 @@ :return: console output useful for debugging failed jobs. :rtype: string """ - return self._ansible_job.get_command_output()
    + return self._ansible_job.get_command_output() + +
    [docs] def kill(self): + """kill the job""" + self._ansible_job.kill()
    @@ -131,7 +138,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/password.html b/doc/build/html/_modules/kollacli/api/password.html index 7b92473..2669f23 100644 --- a/doc/build/html/_modules/kollacli/api/password.html +++ b/doc/build/html/_modules/kollacli/api/password.html @@ -6,7 +6,7 @@ - kollacli.api.password — kollacli 1.0.0.dev386 documentation + kollacli.api.password — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -130,7 +130,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/properties.html b/doc/build/html/_modules/kollacli/api/properties.html index 1dbdc2d..3e2333a 100644 --- a/doc/build/html/_modules/kollacli/api/properties.html +++ b/doc/build/html/_modules/kollacli/api/properties.html @@ -6,7 +6,7 @@ - kollacli.api.properties — kollacli 1.0.0.dev386 documentation + kollacli.api.properties — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -112,14 +112,12 @@ self.ovr_group = False self.ovr_host = False -
    [docs] def property_set(self, key, value, +
    [docs] def property_set(self, property_dict, property_type=GLOBAL_TYPE, change_set=None): """Set a property - :param key: property key - :type key: string - :param value: property value - :type value: string + :param property_dict: property dictionary containing key / values + :type property_dict: dictionary :param property_type: one of 'global', 'group' or 'host' :type property_type: string :param change_set: for group or host sets this is the list of groups @@ -127,10 +125,11 @@ :type change_set: list of strings """ - check_arg(key, u._('Property Key'), str) - key = safe_decode(key) - check_arg(value, u._('Property Value'), str) - value = safe_decode(value) + for key, value in property_dict.items(): + check_arg(key, u._('Property Key'), str) + check_arg(value, u._('Property Value'), str) + property_dict = safe_decode(property_dict) + self._check_type(property_type) if property_type is not GLOBAL_TYPE: check_arg(change_set, u._('Change Set'), list, none_ok=True) @@ -139,18 +138,18 @@ ansible_properties = AnsibleProperties() if property_type == GLOBAL_TYPE: - ansible_properties.set_property(key, value) + ansible_properties.set_property(property_dict) elif property_type == GROUP_TYPE: - ansible_properties.set_group_property(key, value, change_set) + ansible_properties.set_group_property(property_dict, change_set) else: - ansible_properties.set_host_property(key, value, change_set) + ansible_properties.set_host_property(property_dict, change_set)
    -
    [docs] def property_clear(self, key, property_type=GLOBAL_TYPE, +
    [docs] def property_clear(self, property_list, property_type=GLOBAL_TYPE, change_set=None): """Clear a property - :param key: property key - :type key: string + :param property_list: property list + :type property_list: list :param property_type: one of 'global', 'group' or 'host' :type property_type: string :param change_set: for group or host clears this is the list of @@ -158,8 +157,9 @@ :type change_set: list of strings """ - check_arg(key, u._('Property Key'), str) - key = safe_decode(key) + check_arg(property_list, u._('Property List'), list) + property_list = safe_decode(property_list) + self._check_type(property_type) if property_type is not GLOBAL_TYPE: check_arg(change_set, u._('Change Set'), list, none_ok=True) @@ -168,11 +168,11 @@ ansible_properties = AnsibleProperties() if property_type == GLOBAL_TYPE: - ansible_properties.clear_property(key) + ansible_properties.clear_property(property_list) elif property_type == GROUP_TYPE: - ansible_properties.clear_group_property(key, change_set) + ansible_properties.clear_group_property(property_list, change_set) else: - ansible_properties.clear_host_property(key, change_set) + ansible_properties.clear_host_property(property_list, change_set)
    [docs] def property_get(self, property_type=GLOBAL_TYPE, get_set=None): """Returns a list of Property objects @@ -245,7 +245,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/service.html b/doc/build/html/_modules/kollacli/api/service.html index 3451f6d..447dc85 100644 --- a/doc/build/html/_modules/kollacli/api/service.html +++ b/doc/build/html/_modules/kollacli/api/service.html @@ -6,7 +6,7 @@ - kollacli.api.service — kollacli 1.0.0.dev386 documentation + kollacli.api.service — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -204,7 +204,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/api/support.html b/doc/build/html/_modules/kollacli/api/support.html index f579773..1ff6c49 100644 --- a/doc/build/html/_modules/kollacli/api/support.html +++ b/doc/build/html/_modules/kollacli/api/support.html @@ -6,7 +6,7 @@ - kollacli.api.support — kollacli 1.0.0.dev386 documentation + kollacli.api.support — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -153,7 +153,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/deploy.html b/doc/build/html/_modules/kollacli/commands/deploy.html index 4956813..f63e5b4 100644 --- a/doc/build/html/_modules/kollacli/commands/deploy.html +++ b/doc/build/html/_modules/kollacli/commands/deploy.html @@ -6,7 +6,7 @@ - kollacli.commands.deploy — kollacli 1.0.0.dev386 documentation + kollacli.commands.deploy — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -193,7 +193,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/exceptions.html b/doc/build/html/_modules/kollacli/commands/exceptions.html index cafad62..3d0977f 100644 --- a/doc/build/html/_modules/kollacli/commands/exceptions.html +++ b/doc/build/html/_modules/kollacli/commands/exceptions.html @@ -6,7 +6,7 @@ - kollacli.commands.exceptions — kollacli 1.0.0.dev386 documentation + kollacli.commands.exceptions — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -104,7 +104,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/group.html b/doc/build/html/_modules/kollacli/commands/group.html index cd10be4..064f91f 100644 --- a/doc/build/html/_modules/kollacli/commands/group.html +++ b/doc/build/html/_modules/kollacli/commands/group.html @@ -6,7 +6,7 @@ - kollacli.commands.group — kollacli 1.0.0.dev386 documentation + kollacli.commands.group — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -280,7 +280,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/host.html b/doc/build/html/_modules/kollacli/commands/host.html index 854ddc6..119a37f 100644 --- a/doc/build/html/_modules/kollacli/commands/host.html +++ b/doc/build/html/_modules/kollacli/commands/host.html @@ -6,7 +6,7 @@ - kollacli.commands.host — kollacli 1.0.0.dev386 documentation + kollacli.commands.host — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -379,7 +379,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/password.html b/doc/build/html/_modules/kollacli/commands/password.html index 19afccb..0998321 100644 --- a/doc/build/html/_modules/kollacli/commands/password.html +++ b/doc/build/html/_modules/kollacli/commands/password.html @@ -6,7 +6,7 @@ - kollacli.commands.password — kollacli 1.0.0.dev386 documentation + kollacli.commands.password — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -168,7 +168,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/property.html b/doc/build/html/_modules/kollacli/commands/property.html index d873557..d4ccc35 100644 --- a/doc/build/html/_modules/kollacli/commands/property.html +++ b/doc/build/html/_modules/kollacli/commands/property.html @@ -6,7 +6,7 @@ - kollacli.commands.property — kollacli 1.0.0.dev386 documentation + kollacli.commands.property — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -103,6 +103,8 @@ try: property_name = parsed_args.propertyname.strip() property_value = parsed_args.propertyvalue.strip() + property_dict = {} + property_dict[property_name] = property_value if parsed_args.hosts: if parsed_args.groups: @@ -112,16 +114,16 @@ host_names = _get_names(parsed_args.hosts) - CLIENT.property_set(property_name, property_value, + CLIENT.property_set(property_dict, 'host', host_names) elif parsed_args.groups: group_names = _get_names(parsed_args.groups) - CLIENT.property_set(property_name, property_value, + CLIENT.property_set(property_dict, 'group', group_names) else: - CLIENT.property_set(property_name, property_value, + CLIENT.property_set(property_dict, 'global') except Exception: @@ -146,6 +148,8 @@
    [docs] def take_action(self, parsed_args): try: property_name = parsed_args.propertyname.strip() + property_list = [] + property_list.append(property_name) if parsed_args.hosts: if parsed_args.groups: @@ -155,15 +159,15 @@ host_names = _get_names(parsed_args.hosts) - CLIENT.property_clear(property_name, 'host', + CLIENT.property_clear(property_list, 'host', host_names) elif parsed_args.groups: group_names = _get_names(parsed_args.groups) - CLIENT.property_clear(property_name, 'group', + CLIENT.property_clear(property_list, 'group', group_names) else: - CLIENT.property_clear(property_name, 'global') + CLIENT.property_clear(property_list, 'global') except Exception: raise Exception(traceback.format_exc()) @@ -342,7 +346,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/service.html b/doc/build/html/_modules/kollacli/commands/service.html index 6196914..a8d4da5 100644 --- a/doc/build/html/_modules/kollacli/commands/service.html +++ b/doc/build/html/_modules/kollacli/commands/service.html @@ -6,7 +6,7 @@ - kollacli.commands.service — kollacli 1.0.0.dev386 documentation + kollacli.commands.service — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -209,7 +209,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/support.html b/doc/build/html/_modules/kollacli/commands/support.html index 4235064..098a9e7 100644 --- a/doc/build/html/_modules/kollacli/commands/support.html +++ b/doc/build/html/_modules/kollacli/commands/support.html @@ -6,7 +6,7 @@ - kollacli.commands.support — kollacli 1.0.0.dev386 documentation + kollacli.commands.support — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -119,7 +119,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/commands/upgrade.html b/doc/build/html/_modules/kollacli/commands/upgrade.html index 57e20e2..2320c2c 100644 --- a/doc/build/html/_modules/kollacli/commands/upgrade.html +++ b/doc/build/html/_modules/kollacli/commands/upgrade.html @@ -6,7 +6,7 @@ - kollacli.commands.upgrade — kollacli 1.0.0.dev386 documentation + kollacli.commands.upgrade — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -132,7 +132,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/ansible/actions.html b/doc/build/html/_modules/kollacli/common/ansible/actions.html index 1339e6f..048cebe 100644 --- a/doc/build/html/_modules/kollacli/common/ansible/actions.html +++ b/doc/build/html/_modules/kollacli/common/ansible/actions.html @@ -6,7 +6,7 @@ - kollacli.common.ansible.actions — kollacli 1.0.0.dev386 documentation + kollacli.common.ansible.actions — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -300,7 +300,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/ansible/job.html b/doc/build/html/_modules/kollacli/common/ansible/job.html index 6ae34e8..5b7d313 100644 --- a/doc/build/html/_modules/kollacli/common/ansible/job.html +++ b/doc/build/html/_modules/kollacli/common/ansible/job.html @@ -6,7 +6,7 @@ - kollacli.common.ansible.job — kollacli 1.0.0.dev386 documentation + kollacli.common.ansible.job — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -64,6 +64,7 @@ import json import logging import os +import pwd import subprocess # nosec import tempfile import time @@ -72,6 +73,12 @@ from kollacli.common.inventory import remove_temp_inventory from kollacli.common.utils import get_admin_uids +from kollacli.common.utils import get_admin_user +from kollacli.common.utils import get_ansible_lock_path +from kollacli.common.utils import get_kolla_actions_path +from kollacli.common.utils import Lock +from kollacli.common.utils import PidManager +from kollacli.common.utils import run_cmd from kollacli.common.utils import safe_decode LOG = logging.getLogger(__name__) @@ -106,9 +113,20 @@ self._process_std_err = None self._errors = [] self._cmd_output = '' + self._kill_uname = None + self._ansible_lock = Lock(get_ansible_lock_path(), 'ansible_job')
    [docs] def run(self): try: + locked = self._ansible_lock.wait_acquire() + if not locked: + raise Exception( + u._('unable to run ansible job {cmd} ' + 'as we couldn\'t get lock held by {owner}:{pid}.') + .format(cmd=self._command, + owner=self._ansible_lock.current_owner, + pid=self._ansible_lock.current_pid)) + # create and open named pipe, must be owned by kolla group os.mkfifo(self._fifo_path, 0o660) _, grp_id = get_admin_uids() @@ -122,6 +140,7 @@ stderr=subprocess.PIPE) # setup stdout to be read without blocking + LOG.debug('process pid: %s' % self._process.pid) flags = fcntl.fcntl(self._process.stdout, fcntl.F_GETFL) fcntl.fcntl(self._process.stdout, fcntl.F_SETFL, (flags | os.O_NONBLOCK)) @@ -148,6 +167,7 @@ - None: running - 0: done, success - 1: done, error + - 2: done, killed by user """ status = self._process.poll() self._read_from_callback() @@ -155,9 +175,15 @@ self._cmd_output = ''.join([self._cmd_output, out]) if status is not None: # job has completed - status = self._process.returncode - if status != 0: - status = 1 + if self._kill_uname: + status = 2 + msg = (u._('Job killed by user ({name})') + .format(name=self._kill_uname)) + self._errors = [msg] + else: + status = self._process.returncode + if status != 0: + status = 1 if not self._process_std_err: # read stderr from process std_err = self._read_stream(self._process.stderr) @@ -182,6 +208,31 @@ get final output text from command execution """ return self._cmd_output +
    +
    [docs] def kill(self): + """kill job in progress + + The process pid is owned by root, so + that is not killable. Need to kill all its children. + """ + # the kill must be run as the kolla user so the + # kolla_actions program must be used. + actions_path = get_kolla_actions_path() + kolla_user = get_admin_user() + cmd_prefix = ('/usr/bin/sudo -u %s %s job -t -p ' + % (kolla_user, actions_path)) + + # kill the children from largest to smallest pids. + child_pids = PidManager.get_child_pids(self._process.pid) + for child_pid in sorted(child_pids, reverse=True): + cmd = ''.join([cmd_prefix, child_pid]) + err_msg, output = run_cmd(cmd, print_output=False) + if err_msg: + LOG.debug('kill failed: %s %s' % (err_msg, output)) + + # record the name of user who killed the job + cur_uid = os.getuid() + self._kill_uname = pwd.getpwuid(cur_uid)[0]
    def _read_stream(self, stream): out = '' @@ -207,13 +258,18 @@ - close stdout and stderr - close and delete named pipe (fifo) """ + # try to clear the ansible lock + self._ansible_lock.release() + # delete temp inventory file remove_temp_inventory(self._temp_inv_path) # close the process's stdout and stderr streams - if self._process.stdout and not self._process.stdout.closed: + if (self._process and self._process.stdout and not + self._process.stdout.closed): self._process.stdout.close() - if self._process.stderr and not self._process.stderr.closed: + if (self._process and self._process.stderr and not + self._process.stderr.closed): self._process.stderr.close() # close and delete the named pipe (fifo) @@ -329,7 +385,7 @@ if sub_errs: err_msg = ''.join([err_msg, ' [', sub_errs, ']']) - if not err_msg: + if not err_msg or not err_msg.strip(): # sometimes the error message is in std_out # eg- "stdout": 'localhost | FAILED! => {"changed": false, # "failed": true, "msg": "...msg..."}' @@ -340,6 +396,12 @@ if not err_msg: err_msg = stdout + if not err_msg or not err_msg.strip(): + # if still no err_msg, provide entire result + try: + err_msg = json.dumps(results) + except Exception as e: + LOG.debug('unable to convert results to string' % str(e)) msg = ('Host: %s, Task: %s, Status: %s, Message: %s' % (host, taskname, status, err_msg)) return msg @@ -417,7 +479,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/ansible/playbook.html b/doc/build/html/_modules/kollacli/common/ansible/playbook.html index b0f27ee..25a4b58 100644 --- a/doc/build/html/_modules/kollacli/common/ansible/playbook.html +++ b/doc/build/html/_modules/kollacli/common/ansible/playbook.html @@ -6,7 +6,7 @@ - kollacli.common.ansible.playbook — kollacli 1.0.0.dev386 documentation + kollacli.common.ansible.playbook — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -91,11 +91,9 @@ deploy_id = None inventory = None - def __init__(self): - self.inventory = Inventory.load() -
    [docs] def run(self): try: + self.inventory = Inventory.load() inventory_path = self._make_temp_inventory() cmd = self._get_playbook_cmd(inventory_path) self._log_ansible_cmd(cmd, inventory_path) @@ -229,7 +227,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/inventory.html b/doc/build/html/_modules/kollacli/common/inventory.html index 4c56697..fe22e69 100644 --- a/doc/build/html/_modules/kollacli/common/inventory.html +++ b/doc/build/html/_modules/kollacli/common/inventory.html @@ -6,7 +6,7 @@ - kollacli.common.inventory — kollacli 1.0.0.dev386 documentation + kollacli.common.inventory — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -994,7 +994,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/passwords.html b/doc/build/html/_modules/kollacli/common/passwords.html index 0fe1d95..db1d5e3 100644 --- a/doc/build/html/_modules/kollacli/common/passwords.html +++ b/doc/build/html/_modules/kollacli/common/passwords.html @@ -6,7 +6,7 @@ - kollacli.common.passwords — kollacli 1.0.0.dev386 documentation + kollacli.common.passwords — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -68,7 +68,6 @@ from kollacli.common import utils PWDS_FILENAME = 'passwords.yml' -PWD_EDITOR_FILENAME = 'passwd_editor.py'
    [docs]def set_password(pwd_key, pwd_value): @@ -110,14 +109,12 @@
    def _get_cmd_prefix(): - editor_path = os.path.join(utils.get_kollacli_home(), - 'tools', - PWD_EDITOR_FILENAME) + actions_path = utils.get_kolla_actions_path() pwd_file_path = os.path.join(utils.get_kolla_etc(), PWDS_FILENAME) user = utils.get_admin_user() - prefix = '/usr/bin/sudo -u %s %s -p %s ' % (user, - editor_path, pwd_file_path) + prefix = ('/usr/bin/sudo -u %s %s password -p %s ' + % (user, actions_path, pwd_file_path)) return prefix @@ -152,7 +149,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/properties.html b/doc/build/html/_modules/kollacli/common/properties.html index bb73d38..77e1b0b 100644 --- a/doc/build/html/_modules/kollacli/common/properties.html +++ b/doc/build/html/_modules/kollacli/common/properties.html @@ -6,7 +6,7 @@ - kollacli.common.properties — kollacli 1.0.0.dev386 documentation + kollacli.common.properties — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -60,6 +60,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import copy import logging import os import six @@ -291,14 +292,14 @@ new_contents[key] = value return new_contents -
    [docs] def set_property(self, property_key, property_value): +
    [docs] def set_property(self, property_dict): try: - change_property(self.globals_path, property_key, - property_value, clear=False) + change_property(self.globals_path, property_dict, + clear=False) except Exception as e: raise e
    -
    [docs] def set_host_property(self, property_key, property_value, hosts): +
    [docs] def set_host_property(self, property_dict, hosts): # if hosts is None set the property on all hosts inventory = Inventory.load() host_list = [] @@ -313,12 +314,12 @@ try: for host in host_list: file_path = os.path.join(get_host_vars_dir(), host.name) - change_property(file_path, property_key, - property_value, clear=False) + change_property(file_path, property_dict, + clear=False) except Exception as e: raise e
    -
    [docs] def set_group_property(self, property_key, property_value, groups): +
    [docs] def set_group_property(self, property_dict, groups): # if groups is None set the property on all hosts inventory = Inventory.load() group_list = [] @@ -332,20 +333,22 @@ group_list.append(group) try: for group in group_list: + tmp_dict = copy.copy(property_dict) file_path = os.path.join(get_group_vars_dir(), group.name) - change_property(file_path, property_key, - property_value, clear=False) + change_property(file_path, tmp_dict, + clear=False) except Exception as e: raise e
    -
    [docs] def clear_property(self, property_key): +
    [docs] def clear_property(self, property_list): try: - change_property(self.globals_path, property_key, - None, clear=True) + change_property(self.globals_path, + self._list_to_dict(property_list), + clear=True) except Exception as e: raise e
    -
    [docs] def clear_host_property(self, property_key, hosts): +
    [docs] def clear_host_property(self, property_list, hosts): # if hosts is None set the property on all hosts inventory = Inventory.load() host_list = [] @@ -360,12 +363,12 @@ try: for host in host_list: file_path = os.path.join(get_host_vars_dir(), host.name) - change_property(file_path, property_key, - None, clear=True) + change_property(file_path, self._list_to_dict(property_list), + clear=True) except Exception as e: raise e
    -
    [docs] def clear_group_property(self, property_key, groups): +
    [docs] def clear_group_property(self, property_list, groups): # if hosts is None set the property on all hosts inventory = Inventory.load() group_list = [] @@ -380,12 +383,18 @@ try: for group in group_list: file_path = os.path.join(get_group_vars_dir(), group.name) - change_property(file_path, property_key, - None, clear=True) + change_property(file_path, self._list_to_dict(property_list), + clear=True) except Exception as e: raise e +
    + def _list_to_dict(self, property_list): + property_dict = {} + for key in property_list: + property_dict[key] = '' + return property_dict -
    +
    [docs]class AnsibleProperty(object): def __init__(self, name, value, file_name, overrides=False, @@ -438,7 +447,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/sshutils.html b/doc/build/html/_modules/kollacli/common/sshutils.html index c07b5e7..97b174d 100644 --- a/doc/build/html/_modules/kollacli/common/sshutils.html +++ b/doc/build/html/_modules/kollacli/common/sshutils.html @@ -6,7 +6,7 @@ - kollacli.common.sshutils — kollacli 1.0.0.dev386 documentation + kollacli.common.sshutils — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -176,7 +176,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/support.html b/doc/build/html/_modules/kollacli/common/support.html index 64d221b..b4f8f9a 100644 --- a/doc/build/html/_modules/kollacli/common/support.html +++ b/doc/build/html/_modules/kollacli/common/support.html @@ -6,7 +6,7 @@ - kollacli.common.support — kollacli 1.0.0.dev386 documentation + kollacli.common.support — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -315,7 +315,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/common/utils.html b/doc/build/html/_modules/kollacli/common/utils.html index a0eab90..75bef6f 100644 --- a/doc/build/html/_modules/kollacli/common/utils.html +++ b/doc/build/html/_modules/kollacli/common/utils.html @@ -6,7 +6,7 @@ - kollacli.common.utils — kollacli 1.0.0.dev386 documentation + kollacli.common.utils — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -60,6 +60,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import copy +import fcntl import grp import logging import os @@ -104,6 +106,14 @@
    [docs]def get_kolla_log_dir(): return '/var/log/kolla/' +
    +
    [docs]def get_ansible_lock_path(): + return os.path.join(get_kollacli_etc(), 'ansible/ansible.lock') + +
    +
    [docs]def get_kolla_actions_path(): + return os.path.join(get_kollacli_home(), 'tools', 'kolla_actions.py') +
    [docs]def get_admin_uids(): """get uid and gid of admin user""" @@ -216,12 +226,11 @@ return err, output
    -
    [docs]def change_property(file_path, property_key, property_value, clear=False): +
    [docs]def change_property(file_path, property_dict, clear=False): """change property with a file file_path: path to property file - property_key: property name - property value: property value + property_dict: dictionary of property names and values clear: flag to remove property If clear, and property exists, remove it from the property file. @@ -230,6 +239,7 @@ If not clear, and key is found, edit property in place. """ try: + cloned_dict = copy.copy(property_dict) group_info = grp.getgrnam('kolla') if not os.path.exists(file_path): with open(file_path, 'a'): @@ -239,8 +249,6 @@ new_contents = [] read_data = sync_read_file(file_path) lines = read_data.split('\n') - new_line = '%s: "%s"' % (property_key, property_value) - property_key_found = False last_line_empty = False for line in lines: line = line.rstrip() @@ -257,17 +265,21 @@ if len(split_line) > 1: split_key = split_line[0] split_key.rstrip() - if split_key == property_key: - property_key_found = True + if split_key in cloned_dict: if clear: # clear existing property continue # edit existing property - line = new_line + line = '%s: "%s"' % (split_key, cloned_dict[split_key]) + # clear out the key after we are done, all existing keys + # will be appended at the end (or for clear, ignored) + del cloned_dict[split_key] new_contents.append(line) - if not property_key_found and not clear: - # add new property to file - new_contents.append(new_line) + if not clear: + # add new properties to file + for key, value in cloned_dict.items(): + line = '%s: "%s"' % (key, value) + new_contents.append(line) write_data = '\n'.join(new_contents) sync_write_file(file_path, write_data) @@ -283,14 +295,13 @@ """ lock = None try: - lock = Lock(path + '.lock', 'sync_read') - locked = lock.wait_acquire(10) + lock = Lock(path, 'sync_read') + locked = lock.wait_acquire() if not locked: raise Exception( u._('unable to read file {path} ' - 'as it was locked by {owner}:{pid}.') - .format(path=path, owner=lock.current_owner, - pid=lock.current_pid)) + 'as it was locked.') + .format(path=path)) with open(path, mode) as data_file: data = data_file.read() except Exception as e: @@ -298,34 +309,44 @@ finally: if lock: lock.release() - return data + return safe_decode(data)
    [docs]def sync_write_file(path, data, mode='w'): """synchronously write file""" + ansible_lock = None lock = None try: - lock = Lock(path + '.lock', 'sync_write') - locked = lock.wait_acquire(10) + ansible_lock = Lock(get_ansible_lock_path(), 'sync_write') + locked = ansible_lock.wait_acquire() + if not locked: + raise Exception( + u._('unable to get ansible lock while writing to {path} ' + 'as it was locked.') + .format(path=path)) + + lock = Lock(path, 'sync_write') + locked = lock.wait_acquire() if not locked: raise Exception( u._('unable to write file {path} ' - 'as it was locked by {owner}:{pid}.') - .format(path=path, owner=lock.current_owner, - pid=lock.current_pid)) + 'as it was locked.') + .format(path=path)) with open(path, mode) as data_file: data_file.write(data) except Exception as e: raise e finally: + if ansible_lock: + ansible_lock.release() if lock: lock.release()
    [docs]def safe_decode(obj_to_decode): - """Convert bytes or string to unicode string + """Convert bytes or strings to unicode string - Convert either a string or list of strings to + Converts strings, lists, or dictionaries to unicode. """ if obj_to_decode is None: @@ -335,12 +356,15 @@ if isinstance(obj_to_decode, list): new_obj = [] for text in obj_to_decode: - try: - text = text.decode('utf-8') - except AttributeError: # nosec - # py3 will raise if text is already a string - pass + text = safe_decode(text) new_obj.append(text) + elif isinstance(obj_to_decode, dict): + new_obj = {} + for key, value in obj_to_decode.items(): + key = safe_decode(key) + value = safe_decode(value) + new_obj[key] = value + else: try: new_obj = obj_to_decode.decode('utf-8') @@ -381,29 +405,52 @@
    [docs]class Lock(object): + """Object which represents an exclusive resource lock - def __init__(self, lockpath, owner='unknown owner'): + flock usage is the default behavior but a separate pidfile mechanism + is also available. flock doesn't have the same orphaned lock issue + that pidfile usage does. both need to be tests on NFS. if flock + works then it seems better / less complicated for our needs. + """ + + def __init__(self, lockpath, owner='unknown owner', use_flock=True): self.lockpath = lockpath self.pid = str(os.getpid()) + self.fd = None self.owner = owner self.current_pid = -1 self.current_owner = '' + self.use_flock = use_flock
    [docs] def acquire(self): - if not self.is_owned_by_me(): try: - fd = os.open(self.lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR) - with os.fdopen(fd, 'a') as f: - f.write(self.pid + '\n' + self.owner) - return self.is_owned_by_me() + if self.use_flock: + return self._acquire_flock() + else: + return self._acquire_pidfile() except Exception as e: + if not os.path.exists(self.lockpath): + raise Exception('Lock file (%s) is missing' + % self.lockpath) + # it is ok to fail to acquire, we just return that we failed - LOG.debug('Exception in is_owned_by_me lock check ' + LOG.debug('Exception in acquire lock. ' 'path: %s pid: %s owner: %s error: %s' % (self.lockpath, self.pid, self.owner, str(e))) - return False
    -
    [docs] def wait_acquire(self, wait_duration, interval=0.1): + def _acquire_pidfile(self): + if not self.is_owned_by_me(): + fd = os.open(self.lockpath, os.O_CREAT | os.O_EXCL | os.O_RDWR) + with os.fdopen(fd, 'a') as f: + f.write(self.pid + '\n' + self.owner) + return self.is_owned_by_me() + + def _acquire_flock(self): + self.fd = os.open(self.lockpath, os.O_RDWR) + fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + return True + +
    [docs] def wait_acquire(self, wait_duration=3, interval=0.1): wait_time = 0 while (wait_time < wait_duration): if not self.acquire(): @@ -416,7 +463,14 @@
    [docs] def is_owned_by_me(self): """Returns True if we own the lock or False otherwise""" try: - fd = os.open(self.lockpath, os.O_RDWR) + if self.use_flock: + raise Exception(u._('Invalid use of is_owned_by_me while' + 'using flock')) + + if not os.path.exists(self.lockpath): + # lock doesn't exist, just return + return False + fd = os.open(self.lockpath, os.O_RDONLY) with os.fdopen(fd, 'r') as f: contents = f.read(2048).strip().split('\n') if len(contents) > 0: @@ -430,25 +484,61 @@ return False except Exception as e: # it is ok to fail to acquire, we just return that we failed - LOG.debug('Exception in is_owned_by_me lock check ' + LOG.debug('Exception in is_owned_by_me lock check. ' 'path: %s pid: %s owner: %s error: %s' % (self.lockpath, self.pid, self.owner, str(e))) return False
    [docs] def release(self): + try: + if self.use_flock: + self._release_flock() + else: + self._release_pidfile() + except Exception: + # this really shouldn't happen unless for some reason + # two areas in the same process try to release the lock + # at the same time and if that happens you want to see + # an error about it + LOG.error('Error releasing lock', exc_info=True) + return False +
    + def _release_pidfile(self): if self.is_owned_by_me(): - try: - os.remove(self.lockpath) - return True - except Exception: - # this really shouldn't happen unless for some reason - # two areas in the same process try to release the lock - # at the same time and if that happens you want to see - # an error about it - LOG.error('Error releasing lock', exc_info=True) - return False - else: - return False
    + os.remove(self.lockpath) + return True + + def _release_flock(self): + fcntl.flock(self.fd, fcntl.LOCK_UN) + os.close(self.fd) + return True + +
    +
    [docs]class PidManager(object): + @staticmethod +
    [docs] def get_child_pids(pid, child_pids=[]): + """get child pids of parent pid""" + # This ps command will return child pids of parent pid, separated by + # newlines. + err_msg, output = run_cmd('ps --ppid %s -o pid=""' % pid, + print_output=False) + + # err_msg is expected when pid has no children + if not err_msg: + output = output.strip() + + if '\n' in output: + ps_pids = output.split('\n') + else: + ps_pids = [output] + + if ps_pids: + child_pids.extend(ps_pids) + + # recurse through children to get all child pids + for ps_pid in ps_pids: + PidManager.get_child_pids(ps_pid, child_pids) + return child_pids
    @@ -482,7 +572,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/_modules/kollacli/shell.html b/doc/build/html/_modules/kollacli/shell.html index 3c744fd..5f9d66d 100644 --- a/doc/build/html/_modules/kollacli/shell.html +++ b/doc/build/html/_modules/kollacli/shell.html @@ -6,7 +6,7 @@ - kollacli.shell — kollacli 1.0.0.dev386 documentation + kollacli.shell — kollacli 1.0.0.dev396 documentation @@ -14,7 +14,7 @@ - + @@ -36,7 +36,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • @@ -70,10 +70,9 @@ import kollacli.i18n as u +from kollacli.api.client import ClientApi from kollacli.commands.exceptions import CommandError from kollacli.common.inventory import INVENTORY_PATH -from kollacli.common.utils import get_kolla_log_dir -from kollacli.common.utils import get_kolla_log_file_size from kollacli.common.utils import get_kollacli_etc LOG = logging.getLogger(__name__) @@ -96,43 +95,16 @@ 'recreate the file.').format(inventory=inventory_path) raise CommandError(err_string) - # check that current user can access the inventory file - inventory_file = None - try: - inventory_file = open(inventory_path, 'r+') - except Exception: - raise CommandError( - u._('Permission denied to run the kollacli.\n' - 'Please add user to the kolla group and ' - 'then log out and back in.')) - finally: - if inventory_file and inventory_file.close is False: - inventory_file.close() + # set up logging and test that user running shell is part + # of kolla group + ClientApi() # paramiko log is very chatty, tune it down logging.getLogger('paramiko').setLevel(logging.WARNING) - # set up logging - self.rotating_log_dir = get_kolla_log_dir() - self.max_bytes = get_kolla_log_file_size() - self.backup_count = 4 - self.dump_stack_trace = False - self.add_rotational_log() - -
    [docs] def add_rotational_log(self): - root_logger = logging.getLogger('') - rotate_handler = logging.handlers.RotatingFileHandler( - os.path.join(self.rotating_log_dir, 'kolla.log'), - maxBytes=self.max_bytes, - backupCount=self.backup_count) - formatter = logging.Formatter(self.LOG_FILE_MESSAGE_FORMAT) - rotate_handler.setFormatter(formatter) - rotate_handler.setLevel(logging.INFO) - root_logger.addHandler(rotate_handler) - -
    +
    [docs]def main(argv=sys.argv[1:]): shell = KollaCli() return shell.run(argv) @@ -172,7 +144,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • Module code »
  • diff --git a/doc/build/html/genindex.html b/doc/build/html/genindex.html index db01270..f45734d 100644 --- a/doc/build/html/genindex.html +++ b/doc/build/html/genindex.html @@ -7,7 +7,7 @@ - Index — kollacli 1.0.0.dev386 documentation + Index — kollacli 1.0.0.dev396 documentation @@ -15,7 +15,7 @@ - + @@ -113,10 +113,6 @@ -
    add_rotational_log() (kollacli.shell.KollaCli method) -
    - -
    add_service() (kollacli.api.group.GroupApi.Group method)
    @@ -313,6 +309,12 @@ + + -
    +
    enable_console_logging() (kollacli.api.client.ClientApi method) +
    + +
    +
    extra_vars (kollacli.common.ansible.playbook.AnsiblePlaybook attribute)
    @@ -375,6 +377,14 @@ +
    get_ansible_lock_path() (in module kollacli.common.utils) +
    + + +
    get_child_pids() (kollacli.common.utils.PidManager static method) +
    + +
    get_children() (kollacli.api.service.ServiceApi.Service method)
    @@ -481,6 +491,10 @@
    +
    get_kolla_actions_path() (in module kollacli.common.utils) +
    + +
    get_kolla_etc() (in module kollacli.common.utils)
    @@ -504,6 +518,8 @@
    get_kollacli_home() (in module kollacli.common.utils)
    +
    get_log() (kollacli.common.support.HostLogs method)
    @@ -512,8 +528,6 @@
    get_logs() (in module kollacli.common.support)
    -
    get_name() (kollacli.api.group.GroupApi.Group method)
    @@ -901,6 +915,16 @@ + - - + @@ -646,6 +658,12 @@ The uname entry is optional.

    +
    kill() (kollacli.api.job.Job method) +
    + +
    + +
    (kollacli.common.ansible.job.AnsibleJob method) +
    + +
    +
    KollaCli (class in kollacli.shell)
    @@ -972,12 +996,12 @@
    kollacli.commands.group (module)
    +
    kollacli.commands.host (module)
    -
    kollacli.commands.password (module)
    @@ -1141,6 +1165,10 @@ +
    PidManager (class in kollacli.common.utils) +
    + +
    playbook_path (kollacli.common.ansible.playbook.AnsiblePlaybook attribute)
    @@ -1669,7 +1697,7 @@
  • modules |
  • -
  • kollacli 1.0.0.dev386 documentation »
  • +
  • kollacli 1.0.0.dev396 documentation »
  • +
    +
    +enable_console_logging(level, enable=True)[source]
    +

    enable/disable console logging for the api

    +

    enable: True/False +level: logging.INFO, logging.DEBUG, logging.WARNING, +logging.CRITICAL...

    +
    + @@ -638,7 +647,10 @@ The uname entry is optional.

    Returns:None if job still running, 0 if job succeeded, 1 if job failed
    Returns:None: job is still running +0: job succeeded +1: job failed +2: job killed by user
    Return type:int or None
    +
    +
    +kill()[source]
    +

    kill the job

    +
    +
    wait()[source]
    @@ -753,14 +771,14 @@ The uname entry is optional.

    -PropertyApi.property_clear(key, property_type='global', change_set=None)[source]
    +PropertyApi.property_clear(property_list, property_type='global', change_set=None)[source]

    Clear a property

    Parameters:
      -
    • key (string) – property key
    • +
    • property_list (list) – property list
    • property_type (string) – one of ‘global’, ‘group’ or ‘host’
    • change_set (list of strings) – for group or host clears this is the list of groups or hosts to clear the property for
    • @@ -798,15 +816,14 @@ getting group or host related property lists
      -PropertyApi.property_set(key, value, property_type='global', change_set=None)[source]
      +PropertyApi.property_set(property_dict, property_type='global', change_set=None)[source]

      Set a property

      Parameters:
        -
      • key (string) – property key
      • -
      • value (string) – property value
      • +
      • property_dict (dictionary) – property dictionary containing key / values
      • property_type (string) – one of ‘global’, ‘group’ or ‘host’
      • change_set (list of strings) – for group or host sets this is the list of groups or hosts to set the property for
      • @@ -1081,7 +1098,7 @@ names for each log will be servicename_id.log.

      • modules |
      • -
      • kollacli 1.0.0.dev386 documentation »
      • +
      • kollacli 1.0.0.dev396 documentation »
      @@ -273,7 +273,7 @@
    • modules |
    • -
    • kollacli 1.0.0.dev386 documentation »
    • +
    • kollacli 1.0.0.dev396 documentation »
    • @@ -94,7 +94,7 @@
    • modules |
    • -
    • kollacli 1.0.0.dev386 documentation »
    • +
    • kollacli 1.0.0.dev396 documentation »