Source code for mcvirt.config_file

"""Provide base class for configuration files"""

# Copyright (c) 2014 - I.T. Dev Ltd
#
# This file is part of MCVirt.
#
# MCVirt 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 2 of the License, or
# (at your option) any later version.
#
# MCVirt 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 MCVirt.  If not, see <http://www.gnu.org/licenses/>

import json
import os
import stat
import pwd

from mcvirt.utils import get_hostname
from mcvirt.system import System
from mcvirt.constants import DirectoryLocation


[docs]class ConfigFile(object): """Provides operations to obtain and set the MCVirt configuration for a VM""" CURRENT_VERSION = 4 GIT = '/usr/bin/git' def __init__(self): """Set member variables and obtains libvirt domain object""" raise NotImplementedError @staticmethod
[docs] def get_config_path(vm_name): """Provide the path of the VM-specific configuration file""" raise NotImplementedError
[docs] def get_config(self): """Load the VM configuration from disk and returns the parsed JSON.""" config_file = open(self.config_file, 'r') config = json.loads(config_file.read()) config_file.close() return config
[docs] def update_config(self, callback_function, reason=''): """Write a provided configuration back to the configuration file.""" config = self.get_config() callback_function(config) ConfigFile._writeJSON(config, self.config_file) self.config = config self.gitAdd(reason) self.setConfigPermissions()
[docs] def getPermissionConfig(self): config = self.get_config() return config['permissions']
@staticmethod def _writeJSON(data, file_name): """Parses and writes the JSON VM config file""" json_data = json.dumps(data, indent=2, separators=(',', ': ')) # Open the config file and write to contents config_file = open(file_name, 'w') config_file.write(json_data) config_file.close() # Check file permissions, only giving read/write access to root os.chmod(file_name, stat.S_IWUSR | stat.S_IRUSR) os.chown(file_name, 0, 0) @staticmethod
[docs] def create(self): """Creates a basic VM configuration for new VMs""" raise NotImplementedError
[docs] def setConfigPermissions(self): """Sets file permissions for config directories""" def setPermission(path, directory=True, owner=0): permission_mode = stat.S_IRUSR if directory: permission_mode = permission_mode | stat.S_IWUSR | stat.S_IXUSR if (directory and os.path.isdir(path) or not directory and os.path.exists(path)): os.chown(path, owner, 0) os.chmod(path, permission_mode) # Set permissions on git directory for directory in os.listdir(DirectoryLocation.BASE_STORAGE_DIR): path = os.path.join(DirectoryLocation.BASE_STORAGE_DIR, directory) if (os.path.isdir(path)): if (directory == '.git'): setPermission(path, directory=True) else: setPermission(os.path.join(path, 'vm'), directory=True) setPermission(os.path.join(path, 'config.json'), directory=False) # Set permission for base directory, node directory and ISO directory for directory in [DirectoryLocation.BASE_STORAGE_DIR, DirectoryLocation.NODE_STORAGE_DIR, DirectoryLocation.ISO_STORAGE_DIR]: setPermission(directory, directory=True, owner=pwd.getpwnam('libvirt-qemu').pw_uid)
def _upgrade(self, config): """Updates the configuration file""" raise NotImplementedError
[docs] def upgrade(self): """Performs an upgrade of the config file""" # Check the version of the configuration file current_version = self._getVersion() if (current_version < self.CURRENT_VERSION): def upgradeConfig(config): # Perform the configuration sub-class specific upgrade # tasks self._upgrade(config) # Update the version number of the configuration file to # the current version config['version'] = self.CURRENT_VERSION self.update_config( upgradeConfig, 'Updated configuration file \'%s\' from version \'%s\' to \'%s\'' % (self.config_file, current_version, self.CURRENT_VERSION))
def _getVersion(self): """Returns the version number of the configuration file""" config = self.get_config() if ('version' in config.keys()): return config['version'] else: return 0
[docs] def gitAdd(self, message=''): """Commits changes to an added or modified configuration file""" from auth.session import Session if (self._checkGitRepo()): message += "\nUser: %s\nNode: %s" % ( Session.get_current_user_object().get_username(), get_hostname()) try: System.runCommand([self.GIT, 'add', self.config_file], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'commit', '-m', message, self.config_file], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'push'], raise_exception_on_failure=False, cwd=DirectoryLocation.BASE_STORAGE_DIR) except: pass
[docs] def gitRemove(self, message=''): """Removes and commits a configuration file""" from auth.session import Session if self._checkGitRepo(): message += "\nUser: %s\nNode: %s" % (Session.get_current_user_object().get_username(), get_hostname()) try: System.runCommand([self.GIT, 'rm', '--cached', self.config_file], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'commit', '-m', message], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'push'], raise_exception_on_failure=False, cwd=DirectoryLocation.BASE_STORAGE_DIR) except: pass
def _checkGitRepo(self): """Clones the configuration repo, if necessary, and updates the repo""" from mcvirt_config import MCVirtConfig # Only attempt to create a git repository if the git # URL has been set in the MCVirt configuration mcvirt_config = MCVirtConfig().get_config() if mcvirt_config['git']['repo_domain'] == '': return False # Attempt to create git object, if it does not already exist if not os.path.isdir(DirectoryLocation.BASE_STORAGE_DIR + '/.git'): # Initialise git repository System.runCommand([self.GIT, 'init'], cwd=DirectoryLocation.BASE_STORAGE_DIR) # Set git name and email address System.runCommand([self.GIT, 'config', '--file=%s' % DirectoryLocation.BASE_STORAGE_DIR + '/.git/config', 'user.name', mcvirt_config['git']['commit_name']]) System.runCommand([self.GIT, 'config', '--file=%s' % DirectoryLocation.BASE_STORAGE_DIR + '/.git/config', 'user.email', mcvirt_config['git']['commit_email']]) # Create git-credentials store System.runCommand([self.GIT, 'config', '--file=%s' % DirectoryLocation.BASE_STORAGE_DIR + '/.git/config', 'credential.helper', 'store --file /root/.git-credentials']) git_credentials = '%s://%s:%s@%s' % (mcvirt_config['git']['repo_protocol'], mcvirt_config['git']['username'], mcvirt_config['git']['password'], mcvirt_config['git']['repo_domain']) fh = open('/root/.git-credentials', 'w') fh.write(git_credentials) fh.close() # Add the git remote System.runCommand( [ self.GIT, 'remote', 'add', 'origin', mcvirt_config['git']['repo_protocol'] + '://' + mcvirt_config['git']['repo_domain'] + '/' + mcvirt_config['git']['repo_path']], cwd=DirectoryLocation.BASE_STORAGE_DIR) # Update the repo System.runCommand([self.GIT, 'fetch'], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'checkout', 'master'], cwd=DirectoryLocation.BASE_STORAGE_DIR) System.runCommand([self.GIT, 'branch', '--set-upstream-to', 'origin/master', 'master'], cwd=DirectoryLocation.BASE_STORAGE_DIR) # Perform an initial commit of the configuration file self.gitAdd('Initial commit of configuration file.') else: # Update repository System.runCommand([self.GIT, 'pull'], raise_exception_on_failure=False, cwd=DirectoryLocation.BASE_STORAGE_DIR) return True