Supervisor / supervisor

Supervisor process control system for Unix (supervisord)
http://supervisord.org
Other
8.53k stars 1.25k forks source link

Is the `UnhosedConfigParser` class deprecated? #1659

Closed hzbd closed 2 months ago

hzbd commented 2 months ago

The project is excellent and has been very helpful to my project's development progress. Thank you.

I have a question regarding something I don't understand. From the source code, it seems that it is no longer possible to directly create a process instance via the RPC interface, and the code related to the UnhosedConfigParser class seems to be deprecated. I would like to know why the [addProgramToGroup](https://github.com/doubaokun/supervisor_twiddler/blob/master/supervisor_twiddler/rpcinterface.py#L76) interface is no longer available?

class UnhosedConfigParser(ConfigParser.RawConfigParser):
    mysection = 'supervisord'

    def __init__(self, *args, **kwargs):
        # inline_comment_prefixes and strict were added in Python 3 but their
        # defaults make RawConfigParser behave differently than it did on
        # Python 2.  We make it work like 2 by default for backwards compat.
        if not PY2:
            if 'inline_comment_prefixes' not in kwargs:
                kwargs['inline_comment_prefixes'] = (';', '#')

            if 'strict' not in kwargs:
                kwargs['strict'] = False

        ConfigParser.RawConfigParser.__init__(self, *args, **kwargs)

        self.section_to_file = {}
        self.expansions = {}

    def read_string(self, string, source='<string>'):
        '''Parse configuration data from a string.  This is intended
        to be used in tests only.  We add this method for Py 2/3 compat.'''
        try:
            return ConfigParser.RawConfigParser.read_string(
                self, string, source) # Python 3.2 or later
        except AttributeError:
            return self.readfp(StringIO(string))

    def read(self, filenames, **kwargs):
        '''Attempt to read and parse a list of filenames, returning a list
        of filenames which were successfully parsed.  This is a method of
        RawConfigParser that is overridden to build self.section_to_file,
        which is a mapping of section names to the files they came from.
        '''
        if isinstance(filenames, basestring):  # RawConfigParser compat
            filenames = [filenames]

        ok_filenames = []
        for filename in filenames:
            sections_orig = self._sections.copy()

            ok_filenames.extend(
                ConfigParser.RawConfigParser.read(self, [filename], **kwargs))

            diff = frozenset(self._sections) - frozenset(sections_orig)
            for section in diff:
                self.section_to_file[section] = filename
        return ok_filenames

    def saneget(self, section, option, default=_marker, do_expand=True,
                expansions={}):
        try:
            optval = self.get(section, option)
        except ConfigParser.NoOptionError:
            if default is _marker:
                raise
            else:
                optval = default

        if do_expand and isinstance(optval, basestring):
            combined_expansions = dict(
                list(self.expansions.items()) + list(expansions.items()))

            optval = expand(optval, combined_expansions,
                           "%s.%s" % (section, option))

        return optval

    def getdefault(self, option, default=_marker, expansions={}, **kwargs):
        return self.saneget(self.mysection, option, default=default,
                            expansions=expansions, **kwargs)

    def expand_here(self, here):
        HERE_FORMAT = '%(here)s'
        for section in self.sections():
            for key, value in self.items(section):
                if HERE_FORMAT in value:
                    assert here is not None, "here has not been set to a path"
                    value = value.replace(HERE_FORMAT, here)
                    self.set(section, key, value)
hzbd commented 2 months ago

Did the previous extension(https://github.com/doubaokun/supervisor_twiddler) allow process configurations to be created or updated via an RPC interface? Was this feature deprecated due to security considerations?

mnaberez commented 2 months ago

I have a question regarding something I don't understand. From the source code, it seems that it is no longer possible to directly create a process instance via the RPC interface

It's never been possible in Supervisor itself. New programs must be added to the configuration file, then the configuration file reloaded. Back around 2008 or so, I wanted to directly a create process using the RPC interface, so I made the supervisor_twiddler plugin.

, and the code related to the UnhosedConfigParser class seems to be deprecated.

I found no mention of deprecations related to that class. That said, it's not a public API and may have changed since supervisor_twiddler was written.

I would like to know why the addProgramToGroup interface is no longer available?

The RPC method addProgramToGroup() is not part of Supervisor, it's part of the supervisor_twiddler plugin. If it no longer works, please ask on the supervisor_twiddler issue tracker.

The classes in supervisor.options were never intended to be a public API but the supervisor_twiddler plugin reaches in there since there's no other way to do it. If the plugin no longer works, it's the plugin that should be fixed.

Did the previous extension [...] allow process configurations to be created or updated via an RPC interface? Was this feature deprecated due to security considerations?

It did when I last used it around 2014. I found no mention of supervisor_twiddler being deprecated at this time.