From e50779856a6e876dc32492e5d7d6d8ad012b7ef6 Mon Sep 17 00:00:00 2001 From: Jianghua Wang Date: Mon, 12 Dec 2016 13:18:29 +0800 Subject: [PATCH] Support Image caching Enable image caching and add the tool to clean cached images which are not used anymore. Change-Id: I533b55fd10121b8c461091c72eff01525b0455db Closes-Bugs: #1645290 --- .../compute_post_deployment.py | 28 ++++++- .../tools/destroy_cached_images.py | 74 +++++++++++++++++++ plugin_source/deployment_scripts/utils.py | 23 ++++++ 3 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 plugin_source/deployment_scripts/tools/destroy_cached_images.py diff --git a/plugin_source/deployment_scripts/compute_post_deployment.py b/plugin_source/deployment_scripts/compute_post_deployment.py index d05c553..c9f4f1c 100755 --- a/plugin_source/deployment_scripts/compute_post_deployment.py +++ b/plugin_source/deployment_scripts/compute_post_deployment.py @@ -5,7 +5,9 @@ from distutils.version import LooseVersion import netifaces import os import re +import shutil from socket import inet_ntoa +import stat from struct import pack import utils from utils import HIMN_IP @@ -71,7 +73,7 @@ def create_novacompute_conf(himn, username, password, public_ip, services_ssl): cf.set('xenserver', 'vif_driver', 'nova.virt.xenapi.vif.XenAPIOpenVswitchDriver') cf.set('xenserver', 'ovs_integration_bridge', INT_BRIDGE) - cf.set('xenserver', 'cache_images', 'none') + cf.set('xenserver', 'cache_images', 'all') with open(filename, 'w') as configfile: cf.write(configfile) except Exception: @@ -189,6 +191,28 @@ def install_logrotate_script(himn, username): CRONTAB''') +def install_image_cache_cleanup(): + tool_path = '/usr/bin/destroy_cached_images' + tool_conf = '/etc/nova/nova-compute.conf' + # install this tool. + try: + src_file = 'tools/destroy_cached_images.py' + target_file = tool_path + shutil.copy(src_file, target_file) + os.chown(target_file, 0, 0) + os.chmod(target_file, stat.S_IRWXU) + except Exception: + utils.reportError("Failed to install file %s" % target_file) + + # create a daily clean-up cron job + cron_entry = '5 3 * * * {} --config-file={} >/dev/null 2>&1'.format( + tool_path, + tool_conf) + user = 'root' + utils.add_cron_job(user, cron_entry) + LOG.info('Added crontab successfully: %s' % cron_entry) + + def modify_neutron_rootwrap_conf(himn, username, password): """Set xenapi configurations""" filename = '/etc/neutron/rootwrap.conf' @@ -440,3 +464,5 @@ if __name__ == '__main__': else: LOG.info('Skip ceilomter setup as this service is ' 'disabled.') + + install_image_cache_cleanup() diff --git a/plugin_source/deployment_scripts/tools/destroy_cached_images.py b/plugin_source/deployment_scripts/tools/destroy_cached_images.py new file mode 100644 index 0000000..e839101 --- /dev/null +++ b/plugin_source/deployment_scripts/tools/destroy_cached_images.py @@ -0,0 +1,74 @@ +#!/usr/bin/python + +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +destroy_cached_images.py + +This script is used to clean up Glance images that are cached in the SR. By +default, this script will only cleanup unused cached images. + +Options: + + --dry_run - Don't actually destroy the VDIs + --all_cached - Destroy all cached images instead of just unused cached + images. +""" +import eventlet +eventlet.monkey_patch() + +import sys + +from oslo_config import cfg + +import nova.conf +from nova import config +from nova import utils +from nova.virt.xenapi.client import session +from nova.virt.xenapi import vm_utils + +destroy_opts = [ + cfg.BoolOpt('all_cached', + default=False, + help='Destroy all cached images instead of just unused cached' + ' images.'), + cfg.BoolOpt('dry_run', + default=False, + help='Don\'t actually delete the VDIs.') +] + +CONF = nova.conf.CONF +CONF.register_cli_opts(destroy_opts) + + +def main(): + config.parse_args(sys.argv) + utils.monkey_patch() + + _session = session.XenAPISession(CONF.xenserver.connection_url, + CONF.xenserver.connection_username, + CONF.xenserver.connection_password) + + sr_ref = vm_utils.safe_find_sr(_session) + destroyed = vm_utils.destroy_cached_images( + _session, sr_ref, all_cached=CONF.all_cached, + dry_run=CONF.dry_run) + + if '--verbose' in sys.argv: + print('\n'.join(destroyed)) + + print("Destroyed %d cached VDIs" % len(destroyed)) + + +if __name__ == "__main__": + main() diff --git a/plugin_source/deployment_scripts/utils.py b/plugin_source/deployment_scripts/utils.py index 32c4389..2dacd9b 100644 --- a/plugin_source/deployment_scripts/utils.py +++ b/plugin_source/deployment_scripts/utils.py @@ -4,6 +4,7 @@ import logging import netifaces import os import subprocess +import tempfile import yaml XS_RSA = '/root/.ssh/xs_rsa' @@ -256,3 +257,25 @@ def init_eth(): LOG.info('himn_local: %s' % ip[0]['addr']) return eth, ip[0]['addr'] + + +def add_cron_job(user, job_entry): + crontab_cmd = 'crontab' + out = execute(crontab_cmd, '-l', '-u', user) + entries = [] + if out is not None: + entries = out.split('\n') + if job_entry not in entries: + # avoid duplicated entries + entries.append(job_entry) + else: + entries = [job_entry] + entries_str = '\n'.join(entries) + # the ending '\n' is mandatory for crontab. + entries_str += '\n' + temp_fd, temp_path = tempfile.mkstemp() + with open(temp_path, 'w') as tmp_file: + tmp_file.write(entries_str) + execute(crontab_cmd, '-u', user, temp_path) + os.close(temp_fd) + os.remove(temp_path)