Merge lp:~jbaudoux/anybox.recipe.openerp/20130908_relative_paths into lp:anybox.recipe.openerp
- 20130908_relative_paths
- Merge into trunk
Status: | Needs review |
---|---|
Proposed branch: | lp:~jbaudoux/anybox.recipe.openerp/20130908_relative_paths |
Merge into: | lp:anybox.recipe.openerp |
Diff against target: |
140 lines (+51/-13) 2 files modified
anybox/recipe/openerp/base.py (+9/-0) anybox/recipe/openerp/server.py (+42/-13) |
To merge this branch: | bzr merge lp:~jbaudoux/anybox.recipe.openerp/20130908_relative_paths |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Anybox | Pending | ||
Review via email: mp+184473@code.launchpad.net |
Commit message
Description of the change
Improvement to be compliant with buildout option "relative_paths = true"
- 423. By Jacques-Etienne Baudoux
-
Fix format string
Georges Racinet (gracinet) wrote : | # |
inclusion in trunk could be done faster, if that matters to you.
Also, with the new Sphinx documentation, that seems to be the most sensible choice for a new feature (even if we should have supported this from the beginning). Mention of relocability can be done in the non-specific parts of doc/configurati
Jacques-Etienne Baudoux (jbaudoux) wrote : | # |
It allows me to deploy in a chroot subdirectory.
It's now compliant with the relative_paths option of buildout for the python scripts.
For your information, it's, however, still missing some hack to take care the the addons path in the openerp.cfg. I didn't found a nice way to solve that. For now, I'm solving it by creating a symling this: mybuildoutdirfu
Georges Racinet (gracinet) wrote : | # |
OpenERP has a tendency to interpret paths relative to what if feels to be its home directory, namely the parent dir of the 'openerp' package.
In our case that's self.openerp_dir, so maybe you could work out something with os.path.relpath based on it ?
I don't know if that's true for addons, but it is for log files : bin/start_openerp --log-file=my.log will put the log file at <buildout_
One of the many reasons we wanted to normalize stuff in upgrade scripts (easy to forget to write down in maintainance procedures).
Jacques-Etienne Baudoux (jbaudoux) wrote : | # |
As the openerp.cfg is generated by importing openerp.
I don't see anyway to have relative path here.
And as having full path in openerp.cfg is not blocking, so I'm gonna leave it like this.
Nevertheless, for python, relative path is required for the python module loader if you deploy in chroot jail. So, I suggest you merge this MP.
Georges Racinet (gracinet) wrote : | # |
> As the openerp.cfg is generated by importing openerp.
> buildout, and the path is generated by openerp with os.path.
> panduser(
> I don't see anyway to have relative path here.
This I don't really understand: that'd be the initial generation, but the recipe overwrites openerp.cfg afterwards by writing directly to it with a ConfigParser instance, IIRC
> And as having full path in openerp.cfg is not blocking, so I'm gonna leave it
> like this.
>
> Nevertheless, for python, relative path is required for the python module
> loader if you deploy in chroot jail. So, I suggest you merge this MP.
I see, for the chroot use case, you *need* paths to be relative.
But for simple relocability without rerunning buildout, it'd be neat to have a full relative setup.
I'll take a look at the merge this afternoon. Meanwhile, if you have opportunity to add tests in anybox/
Georges Racinet (gracinet) wrote : | # |
Took a look at the merge today (sorry, I'm late) and a few more question arise:
- the invocation of Session in the generated interpreter now uses the buildout dir (to read the expected VERSION file)
- is there a specific reason not to pass a relative path in the scripts generation, too ?
That makes too much questionning for merging before 1.8.0, I'll take a look at these again rigth after the release of 1.8.0 (should be first thing tomorrow morning CEST).
Georges Racinet (gracinet) wrote : | # |
But I'm confident that it can make it before 1.8.1
Jacques-Etienne Baudoux (jbaudoux) wrote : | # |
> This I don't really understand: that'd be the initial generation, but the recipe overwrites openerp.cfg afterwards by writing directly to it with a ConfigParser instance, IIRC
ok, I see what you mean. This has to be investigated a bit more.
> - is there a specific reason not to pass a relative path in the scripts generation, too ?
Of what scripts are you talking? All the python scripts in bin seems to be with relative path
Anyway, thanks for the time you spend reviewing this. I need to look at your latest developments
Jacques-Etienne Baudoux (jbaudoux) wrote : | # |
Hi Georges,
I'm coming back on this MP as I just found some time to investigate that openerp.cfg addons_path that is not relative to the root of the chroot jail.
So, it's coming from server.py:
|- def _create_
|| """Have OpenERP generate its default config file.
|| """
|| self.options.
|| if self.major_version <= (6, 0):
|| # root-path not available as command-line option
|| os.chdir(
|| subprocess.
|| ])
|| else:
|| sys.path.
|| sys.path.
|| from openerp.
|| configmanager(
I see 2 options:
1/ no improvement to this MP. Only python scripts are relative. However, each item in the addons path is prefixed by the path of the jail.
addons_path = /home/jbaudoux/
and, inside the jail, workaround by creating a symlink /home/jbaudoux/
2/ don't use
|| from openerp.
|| configmanager(
but run the jail start script like it was previously
|| subprocess.
|| ])
where self.script_path has to be replaced by a new buildout variable specifying the script to run
This also has the advantage that if buildout is not run by the user that will run openerp, the openerp.cfg file gets the right ownership which is currently not the case.
What do you prefer? Option 1 is working fine (so I keep this MP as it is) but if you'd like to have option 2 implemented, I can make a MP to this MP.
Stefan Rijnhart (Opener) (stefan-opener) wrote : | # |
Hi Jacques Etienne,
thank you for your work! I'm suggesting some changes to streamline the preparation of running the buildout in a jail root here: https:/
Jacques-Etienne Baudoux (jbaudoux) wrote : | # |
This MP is now obsolete and replaced by:
https:/
Keeping this MP for history until latest gets merged.
Unmerged revisions
- 423. By Jacques-Etienne Baudoux
-
Fix format string
- 422. By Jacques-Etienne Baudoux
-
pep8
- 421. By Jacques-Etienne Baudoux
-
Support buildout option "relative_paths = true"
Preview Diff
1 | === modified file 'anybox/recipe/openerp/base.py' |
2 | --- anybox/recipe/openerp/base.py 2013-09-05 22:45:15 +0000 |
3 | +++ anybox/recipe/openerp/base.py 2013-09-08 17:19:36 +0000 |
4 | @@ -111,6 +111,15 @@ |
5 | self.clear_retry = clear_retry == 'true' |
6 | |
7 | # same as in zc.recipe.eggs |
8 | + relative_paths = options.get( |
9 | + 'relative-paths', |
10 | + buildout['buildout'].get('relative-paths', 'false') |
11 | + ) |
12 | + if relative_paths == 'true': |
13 | + self._relative_paths = self.buildout_dir |
14 | + else: |
15 | + self._relative_paths = '' |
16 | + assert relative_paths == 'false' |
17 | self.extra_paths = [ |
18 | join(self.buildout_dir, p.strip()) |
19 | for p in self.options.get('extra-paths', '').split(os.linesep) |
20 | |
21 | === modified file 'anybox/recipe/openerp/server.py' |
22 | --- anybox/recipe/openerp/server.py 2013-09-07 11:43:18 +0000 |
23 | +++ anybox/recipe/openerp/server.py 2013-09-08 17:19:36 +0000 |
24 | @@ -13,6 +13,21 @@ |
25 | SERVER_COMMA_LIST_OPTIONS = ('log_handler', ) |
26 | |
27 | |
28 | +def _relative_path(common, path): |
29 | + """Copied from easy_install""" |
30 | + r = [] |
31 | + while 1: |
32 | + dirname, basename = os.path.split(path) |
33 | + r.append(basename) |
34 | + if dirname == common: |
35 | + break |
36 | + if dirname == path: |
37 | + raise AssertionError("dirname of %s is the same" % dirname) |
38 | + path = dirname |
39 | + r.reverse() |
40 | + return os.path.join(*r) |
41 | + |
42 | + |
43 | class ServerRecipe(BaseRecipe): |
44 | """Recipe for server install and config |
45 | """ |
46 | @@ -266,15 +281,28 @@ |
47 | desc = self.openerp_scripts[name] = dict(entry=entry) |
48 | return name, desc |
49 | |
50 | + def _relativitize(self, path): |
51 | + """Inspired from easy_install""" |
52 | + if self._relative_paths: |
53 | + eggs = os.path.normcase(os.path.abspath( |
54 | + self.b_options['eggs-directory'])) |
55 | + common = os.path.dirname(os.path.commonprefix([path, eggs])) |
56 | + if (common == self._relative_paths or |
57 | + common.startswith(os.path.join(self._relative_paths, '')) |
58 | + ): |
59 | + return "join(base, %r)" % _relative_path(common, path) |
60 | + return path |
61 | + |
62 | def _register_main_startup_script(self, qualified_name): |
63 | """Register main startup script, usually ``start_openerp`` for install. |
64 | """ |
65 | desc = self._get_or_create_script('openerp_starter', |
66 | name=qualified_name)[1] |
67 | desc.update( |
68 | - arguments='%r, %r, version=%r' % (self._get_server_command(), |
69 | - self.config_path, |
70 | - self.major_version), |
71 | + arguments='%s, %s, version=%r' % ( |
72 | + self._relativitize(self._get_server_command()), |
73 | + self._relativitize(self.config_path), |
74 | + self.major_version), |
75 | ) |
76 | |
77 | startup_delay = float(self.options.get('startup_delay', 0)) |
78 | @@ -305,9 +333,9 @@ |
79 | "from anybox.recipe.openerp import devtools", |
80 | "devtools.load(for_tests=True)", |
81 | "")), |
82 | - arguments='%r, %r, version=%r, just_test=True' % ( |
83 | - self._get_server_command(), |
84 | - self.config_path, |
85 | + arguments='%s, %s, version=%r, just_test=True' % ( |
86 | + self._relativitize(self._get_server_command()), |
87 | + self._relativitize(self.config_path), |
88 | self.major_version), |
89 | ) |
90 | |
91 | @@ -340,7 +368,8 @@ |
92 | # to resort on hacking sys.argv |
93 | desc['initialization'] = ( |
94 | "from sys import argv; argv[1:] = ['%s', '-c', '%s.conf.py']" % ( |
95 | - gunicorn_entry_point, join(self.etc, qualified_name))) |
96 | + gunicorn_entry_point, |
97 | + self._relativitize(join(self.etc, qualified_name)))) |
98 | |
99 | def _register_openerp_command(self, qualified_name): |
100 | """Register https://launchpad.net/openerp-command for install. |
101 | @@ -403,7 +432,9 @@ |
102 | desc = self._get_or_create_script('openerp_cron_worker', |
103 | name=qualified_name)[1] |
104 | desc.update(entry='openerp_cron_worker', |
105 | - arguments='%r, %r' % (script_src, self.config_path), |
106 | + arguments='%s, %s' % ( |
107 | + self._relativitize(script_src), |
108 | + self._relativitize(self.config_path)), |
109 | initialization='', |
110 | ) |
111 | |
112 | @@ -418,7 +449,7 @@ |
113 | initialization = os.linesep.join(( |
114 | "", |
115 | "from anybox.recipe.openerp.startup import Session", |
116 | - "session = Session(%r)" % self.config_path, |
117 | + "session = Session(%s)" % self._relativitize(self.config_path), |
118 | "if len(sys.argv) <= 1:", |
119 | " print('To start the OpenERP working session, just do:')", |
120 | " print(' session.open(db=DATABASE_NAME)')", |
121 | @@ -441,8 +472,7 @@ |
122 | initialization=initialization, |
123 | arguments=self.options.get('arguments', ''), |
124 | extra_paths=self.extra_paths, |
125 | - # TODO investigate these options: |
126 | - # relative_paths=self._relative_paths, |
127 | + relative_paths=self._relative_paths, |
128 | ) |
129 | |
130 | def _install_openerp_scripts(self): |
131 | @@ -476,9 +506,8 @@ |
132 | interpreter='', |
133 | initialization=initialization, |
134 | arguments=desc.get('arguments', ''), |
135 | - # TODO investigate these options: |
136 | extra_paths=self.extra_paths, |
137 | - # relative_paths=self._relative_paths, |
138 | + relative_paths=self._relative_paths, |
139 | ) |
140 | self.openerp_installed.append(join(self.bin_dir, script_name)) |
141 |
Really interesting if I understand it correctly, this the forever delayed "TODO investigate these options" ! Thank you for the contribution.
I'd need to read the details of _relativitize(), and especially understand why the one from zc.buildout. easy_install is not enough, but one thing is for sure : this will need dedicated unit tests and documentation : if OpenERP buildouts can be made relocatable, then the doc must state it explicitely, along with limitations (simply pointing out that it behaves exactly as zc.recipe.egg in that respect, it that is the case).
Not yet decided whether this can go to 1.7 or trunk. There's nothing that seems to be so dangerous (a breakage would not stay unnoticed for long).