Add command-line option for the daemon to restrict some config keys to being read-only.

This only affects the core.set_config() RPC method which will drop items if the key
is listed as read-only.
This commit is contained in:
Andrew Resch 2016-02-02 19:25:46 -08:00
parent d13fca251e
commit d91e5d894f
4 changed files with 31 additions and 5 deletions

View file

@ -41,10 +41,15 @@ log = logging.getLogger(__name__)
class Core(component.Component):
def __init__(self, listen_interface=None):
def __init__(self, listen_interface=None, read_only_config_keys=None):
log.debug("Core init...")
component.Component.__init__(self, "Core")
# These keys will be dropped from the set_config() RPC and are
# configurable from the command-line.
self.read_only_config_keys = read_only_config_keys
log.debug("read_only_config_keys: %s", read_only_config_keys)
# Create the client fingerprint
client_id = "DE"
client_version = deluge.common.VersionSplit(deluge.common.get_version()).version
@ -524,6 +529,8 @@ class Core(component.Component):
"""Set the config with values from dictionary"""
# Load all the values into the configuration
for key in config.keys():
if self.read_only_config_keys and key in self.read_only_config_keys:
continue
if isinstance(config[key], basestring):
config[key] = config[key].encode("utf8")
self.config[key] = config[key]

View file

@ -71,7 +71,8 @@ def check_running_daemon(pid_file):
class Daemon(object):
"""The Deluge Daemon class"""
def __init__(self, listen_interface=None, interface=None, port=None, classic=False):
def __init__(self, listen_interface=None, interface=None, port=None, classic=False,
read_only_config_keys=None):
"""
Args:
listen_interface (str, optional): The IP address to listen to bittorrent connections on.
@ -79,7 +80,8 @@ class Daemon(object):
port (int, optional): The port the daemon will listen for UI connections on.
classic (bool, optional): If True the client is in Classic (Standalone) mode otherwise, if
False, start the daemon as separate process.
read_only_config_keys (list of str, optional): A list of config keys that will not be
altered by core.set_config() RPC method.
"""
log.info("Deluge daemon %s", get_version())
@ -100,7 +102,8 @@ class Daemon(object):
SetConsoleCtrlHandler(win_handler)
# Start the core as a thread and join it until it's done
self.core = Core(listen_interface=listen_interface)
self.core = Core(listen_interface=listen_interface,
read_only_config_keys=read_only_config_keys)
if port is None:
port = self.core.config["daemon_port"]

View file

@ -153,6 +153,10 @@ def start_daemon():
help="Sets the log level to 'none', this is the same as `-L none`")
parser.add_option("-r", "--rotate-logs", help="Rotate logfiles.", action="store_true", default=False)
parser.add_option("--profile", dest="profile", action="store_true", default=False, help="Profiles the daemon")
parser.add_option("--read-only-config-keys", dest="read_only_config_keys",
help="List of comma-separated config keys that will not be modified by \
set_config RPC.",
action="store", type="str", default="")
# Get the options and args from the OptionParser
(options, args) = parser.parse_args()
@ -228,7 +232,8 @@ def start_daemon():
try:
Daemon(listen_interface=options.listen_interface,
interface=options.ui_interface,
port=options.port)
port=options.port,
read_only_config_keys=options.read_only_config_keys.split(","))
except Exception as ex:
log.exception(ex)
sys.exit(1)

View file

@ -263,3 +263,14 @@ class CoreTestCase(BaseTestCase):
self.core.set_config({"abc": "def", "foo": 10, "foobar": "barfoo"})
self.assertEquals(self.core.get_config_values(["foo", "abc"]), {"foo": 10, "abc": "def"})
self.assertEquals(self.core.get_config_value("foobar"), "barfoo")
def test_read_only_config_keys(self):
key = 'max_upload_speed'
self.core.read_only_config_keys = [key]
old_value = self.core.get_config_value(key)
self.core.set_config({key: old_value + 10})
new_value = self.core.get_config_value(key)
self.assertEquals(old_value, new_value)
self.core.read_only_config_keys = None