Mini Shell
# -*- coding: utf-8 -*-
# lvectl.py - module for interfacing with cagefsctl utility for get/set CageFs user's status
#
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENCE.TXT
#
import logging
import os.path
from cllimits.lib import exec_utility
from clcommon.clexception import FormattedException
from clcommon.utils import run_command, ExternalProgramFailed
class CageFsException(FormattedException):
pass
class CageFs:
_UTILITY_PATH = '/usr/sbin/cagefsctl'
def __init__(self, logger=None):
# List of enabled users in Cagefs
self._cagefs_enabled_users = None
self._is_cagefs_error = False
self._logger = logger or self._create_dummy_logger()
@staticmethod
def _create_dummy_logger():
logger = logging.getLogger(__name__)
# in order to write messages only to this logger, not global
logger.propagate = False
logger.addHandler(logging.NullHandler())
return logger
def is_cagefs_present(self):
"""
Get CageFS presence flag
:return: True/False - Cagefs present/absent
"""
return os.path.isfile(self._UTILITY_PATH)
# WARNING: result is cached, TODO: rework caching
def get_user_status(self, username):
"""
Get User status in CageFs
:param username: User name
:return: True/False - user enabled/disabled in CageFs
"""
# Load Cagefs data if need
self._load_info()
return username in self._cagefs_enabled_users
def set_user_status(self, username, status, ignore_cache=False):
"""
Set user status in CageFs
:param str username: User name
:param bool status: new user status - True/False --> enable/disable
:param bool ignore_cache: ignore data caching
:return: None
"""
# Load Cagefs data if need
if not ignore_cache:
self._load_info()
if status and self.get_user_status(username):
# Enable user: user already in cagefs - do nothing
return
if not status and not self.get_user_status(username):
# Disable user: user already not in cagefs - do nothing
return
if status:
cagefsctl_arg = "--enable"
else:
cagefsctl_arg = "--disable"
self._get_cagefsctl_out([cagefsctl_arg, username])
def _load_info(self):
"""
Loads users info from Cagefs
:return: None
"""
# Exit if CageFS data already loaded
if self._cagefs_enabled_users is not None:
return
# Exit if CageFS not present or Cagefs error
if not self.is_cagefs_present() or self._is_cagefs_error:
raise CageFsException({'message': "%(util)s is disabled",
'context': {'util': 'CageFS'}})
self._cagefs_enabled_users = []
s_cagefs_out = self._get_cagefsctl_out(['--list-enabled'])
# Parse result
s_enabled_users_parts = s_cagefs_out.split('\n')
for line in s_enabled_users_parts:
if "enabled user" in line:
continue
self._cagefs_enabled_users.append(line.strip())
def initialize_cagefs(self):
"""
Just initialize cagefs
"""
out = self._get_cagefsctl_out(['--init'])
return out
def set_enabled_mode(self):
# We use run_command because it uses close_fds=True during subprocess opening
# in case of --enable-all there are problems with lock on cl6
# so we use close_fds=True to close file descriptor and makes locking works properly
try:
cmd = ['cagefsctl', '--enable-all']
out = run_command(cmd)
return out
except ExternalProgramFailed as err:
raise CageFsException(str(err)) from err
def get_user_mode(self):
out = self._get_cagefsctl_out(['--display-user-mode'])
# Mode: Disable All
mode = out.split(':')[1].strip()
return mode
def toggle_user_mode(self):
self._get_cagefsctl_out(['--toggle-mode'])
def enable_cagefs(self):
# We use run_command because it uses close_fds=True during subprocess opening
# in case of --enable-cagefs there are problems with lock on cl6
# so we use close_fds=True to close file descriptor and makes locking works properly
try:
cmd = ['cagefsctl', '--enable-cagefs']
self._logger.info('Running "%s"', ' '.join(cmd))
out = run_command(cmd)
return out
except ExternalProgramFailed as err:
self._logger.info('cagefsctl exited with error "%s"', str(err))
raise CageFsException(str(err)) from err
def _get_cagefsctl_out(self, cmd):
self._logger.info('Running "cagefsctl %s"', ' '.join(cmd))
if not self.is_cagefs_present():
raise CageFsException({'message': "%(util)s is not installed",
'context': {'util': 'CageFS'}})
ret_code, s_stdout, s_stderr = exec_utility(self._UTILITY_PATH, cmd, stderr=True)
s_cagefs_out = s_stdout or s_stderr
if ret_code != 0 or 'Error:' in s_cagefs_out:
self._logger.info('Cagefs exited with exit code "%s" and output "%s"', (ret_code, s_cagefs_out))
self._is_cagefs_error = True
raise CageFsException(s_cagefs_out)
return s_cagefs_out
def rebuild_alt_php_ini(self):
out = self._get_cagefsctl_out(['--rebuild-alt-php-ini'])
return out
Zerion Mini Shell 1.0