Edgewall Software
Modify

Opened 14 years ago

Closed 14 years ago

#9416 closed defect (fixed)

environment_created in plugins never be called on initenv using --inherit option

Reported by: Jun Omae Owned by: Remy Blank
Priority: normal Milestone: 0.12.1
Component: admin/console Version: 0.12dev
Severity: normal Keywords:
Cc: Branch:
Release Notes:
API Changes:
Internal Changes:

Description

I created the plugin that uses IEnvironmentSetupParticipant.environment_created, and created a project using $ENV initenv --inherit=$HOME/var/trac-inherit.ini. The plugin is enabled in trac-inherit.ini.

I expect that environment_created in the plugin is called. However, the method isn't called with 0.12rc1 (r9839).

The method is called with 0.11-stable (r9726), and I expect it!

$HOME/var/trac-inherit.ini:

[components]
tracenvsetup.* = enabled

[logging]
log_file = trac.log
log_level = DEBUG
log_type = file

plugin source - tracenvsetup/__init__.py

from trac.core import implements, Component
from trac.env import IEnvironmentSetupParticipant

class SampleEnvironmentSetupParticipant(Component):

    implements(IEnvironmentSetupParticipant)

    # IEnvironmentSetupParticipant methods

    def environment_created(self):
        # if raise the exception, call it via initenv
        raise ValueError("call environment_created")

    def environment_needs_upgrade(self, db):
        self.log.debug("the existing environment requires an upgrade for sample plugin.")
        return True

    def upgrade_environment(self, db):
        self.log.debug("upgrading existing environment for sample plugin.")
        pass

In 0.11-stable:

$HOME/bin/trac-admin $HOME/var/trac/0.11-stable-envsetup initenv --inherit=$HOME/var/trac-inherit.ini

Creating and Initializing Project
Initenv for '/Users/jun66j5/var/trac/0.11-stable-envsetup' failed.
 Failed to create environment.
call environment_created
Traceback (most recent call last):
  File "/Users/jun66j5/lib/python2.6/site-packages/Trac-0.11.7.1dev_r9726-py2.6.egg/trac/admin/console.py", line 583, in do_initenv
    options=options)
  File "/Users/jun66j5/lib/python2.6/site-packages/Trac-0.11.7.1dev_r9726-py2.6.egg/trac/env.py", line 213, in __init__
    setup_participant.environment_created()
  File "/Users/jun66j5/lib/python2.6/site-packages/TracEnvSetupSample-0.1-py2.6.egg/tracenvsetup/__init__.py", line 13, in environment_created
    raise ValueError("call environment_created")
ValueError: call environment_created

Attachments (1)

9416-environment-creation-r9848.patch (5.3 KB ) - added by Remy Blank 14 years ago.
Refactored environment creation.

Download all attachments as: .zip

Change History (15)

comment:1 by Remy Blank, 14 years ago

There's something weird in Environment.__init__(): plugins are loaded before the environment (and config file and all) is created, so env.shared_plugins_dir is always empty at that point (I assume this should allow creating database backend plugins, and ensure that they are loaded before creating the database). Is your plugin installed globally or in a shared plugin folder? How is it packaged (egg, extracted)? Then again, this code hasn't changed from 0.11 to 0.12, so I don't see how this could be the cause.

Other than that, I don't see what could cause the difference. I would need to step through the creation process with a debugger to find out what happens.

in reply to:  1 comment:2 by Jun Omae, 14 years ago

Replying to rblank:

Is your plugin installed globally or in a shared plugin folder?

The directory that my plugin installed is on PYTHONPATH.

export PYTHONPATH=$HOME/lib/python2.6/site-packages
python setup.py install --prefix=$HOME
...

Trac is installed on the same directory.

How is it packaged (egg, extracted)?

extracted.

Other than that, I don't see what could cause the difference. I would need to step through the creation process with a debugger to find out what happens.

Ok, I'll try it.

comment:3 by Jun Omae, 14 years ago

I created the patch.

The comoponents settings are cached when calling Environment.setup_config (trac/env.py:207). At this time the inherit file isn't used.

When setup_participants is called (trac/env.py:226) the cache is used and the components settings in inherit file are ignored.

  • trac/env.py

     
    402402            self.config.set(section, name, value)
    403403        self.config.save()
    404404        # Full reload to get 'inherit' working
     405        delattr(self, '_rules')
    405406        self.config.parse_if_needed(force=True)
    406407
    407408        # Create the database

Stacktrace on calling Environment.setup_config

Breakpoint 2 at /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py:269
(Pdb) c
> /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py(269)_component_rules()
-> return self._rules
(Pdb) w
  /opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/bdb.py(368)run()
-> exec cmd in globals, locals
  <string>(1)<module>()
  /Users/jun66j5/bin/trac-admin(9)<module>()
-> load_entry_point('Trac==0.12rc1', 'console_scripts', 'trac-admin')()
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/admin/console.py(543)run()
-> return admin.onecmd(command)
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/admin/console.py(107)onecmd()
-> rv = cmd.Cmd.onecmd(self, line) or 0
  /opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/cmd.py(219)onecmd()
-> return func(arg)
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/admin/console.py(413)do_initenv()
-> options=options)
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py(207)__init__()
-> self.setup_config(load_defaults=create)
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py(435)setup_config()
-> for section, default_options in self.config.defaults(self).items():
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/config.py(157)defaults()
-> for (section, key), option in Option.get_registry(compmgr).items():
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/config.py(519)get_registry()
-> return dict(each for each in Option.registry.items()
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/config.py(521)<genexpr>()
-> or compmgr.is_enabled(components[each[1]]))
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/core.py(222)is_enabled()
-> self.enabled[cls] = self.is_component_enabled(cls)
  /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py(302)is_component_enabled()
-> rules = self._component_rules
> /Users/jun66j5/lib/python2.6/site-packages/Trac-0.12rc1-py2.6.egg/trac/env.py(269)_component_rules()
-> return self._rules

comment:4 by Remy Blank, 14 years ago

Owner: set to Remy Blank

Excellent detective work! I'll apply the patch tonight.

comment:5 by Christian Boos, 14 years ago

Ok, the delattr(self, '_rules') looks a bit scary, but create is not supposed to be called in a multi-threaded setup, only from initenv so I suppose this is safe.

comment:6 by Mikael Relbe, 14 years ago

Thank you for finding this, which explains TH:ticket:7203#comment:3 (I thought I was in deep water there… :)

comment:7 by Remy Blank, 14 years ago

I have applied jomae's patch in [9847] as a temporary workaround, as it fixes the issue. However, the way environment creation is implemented could use some refactoring. I'm working on it, and it also fixes this issue, but we should probably delay this until 0.12.1. Patch following shortly.

by Remy Blank, 14 years ago

Refactored environment creation.

comment:8 by Remy Blank, 14 years ago

In the current state, a "preliminary" configuration is loaded first, which doesn't take the [inherit] file option into account. Then, logging is setup, plugins are loaded, and only then is the environment created and the final configuration loaded. As a consequence, logging uses the default configuration, instead of an inherited configuration. Also, plugins located in a shared plugins folder set in an inherited configuration are not loaded.

The patch above refactors the creation of the environment, with the following advantages:

  • The configuration doesn't need to be reloaded, and the cache for the [components] section doesn't need to be cleared. So it fixes this issue.
  • Logging is set up correctly from the start.
  • Plugins located in a shared plugins folder that is configured in a shared configuration are loaded.

All tests pass, and environment creation with and without --inherit= works.

Thoughts?

comment:9 by Christian Boos, 14 years ago

Looks good, but comment:8 is not that clear about "plugins located in a shared plugins folder set in an inherited configuration": are they loaded or not? Point 3. seem to say they are, contradicting the first sentence, unless "shared configuration" means something different than "inherited configuration". /me confused…

In any case, I'd very much prefer to postpone this change to 0.12.1.

comment:10 by Remy Blank, 14 years ago

Let me try again ;)

  • Shared plugins folder: folder defined with the [inherit] plugins_dir option.
  • Inherited configuration: file defined with the [inherit] file option.

In the current state, plugins located in a shared plugins folder that is defined in an inherited configuration are not loaded during creation, and hence, their IEnvironmentSetupParticipants are not called. With the patch, they are. Plugins installed globally already work as expected.

common.ini:

[inherit]
plugins_dir = /path/to/shared/plugins

Environment creation:

trac-admin env initenv --inherit=/path/to/common.ini

in reply to:  10 ; comment:11 by Christian Boos, 14 years ago

Replying to rblank:

Let me try again ;)

We should put that in the docs. TracEnvironment? That way, we can also clearly document the current limitation and, after the fix, document the behavior change.

comment:12 by Remy Blank, 14 years ago

Milestone: 0.120.12.1

Ok, moving over to 0.12.1.

in reply to:  11 comment:13 by Christian Boos, 14 years ago

It was not obvious to add the bit of information from comment:10 somewhere, without several other clarifications in various places, but I think it's OK now, with TracEnvironment@42.

comment:14 by Remy Blank, 14 years ago

Resolution: fixed
Status: newclosed

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Remy Blank.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Remy Blank to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.