lgp: add new 'shell' command

Replace 'script' and 'login' commands with 'shell'. With no argument, starts an interactive shell in the chrooted distribution. Otherwise, run a script from SCRIPTS_DIR.

Closes #66589

authorJulien Cristau <julien.cristau@logilab.fr>
changesetf3ff8d88cfdb
branchdefault
phasepublic
hiddenno
parent revision#dbe060a879ce make_debian_source_package now returns the path to the new dsc file
child revision#3369c007c23f lgp: change urls of new Logilab repository
files modified by this revision
lgp/__init__.py
lgp/login.py
lgp/script.py
lgp/shell.py
# HG changeset patch
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1307711761 -7200
# Fri Jun 10 15:16:01 2011 +0200
# Node ID f3ff8d88cfdb6df18f2699b23f9772ec71838b55
# Parent dbe060a879ce8c38fe059cad5f034172248ef9da
lgp: add new 'shell' command

Replace 'script' and 'login' commands with 'shell'. With no argument,
starts an interactive shell in the chrooted distribution. Otherwise,
run a script from SCRIPTS_DIR.

Closes #66589

diff --git a/lgp/__init__.py b/lgp/__init__.py
@@ -64,7 +64,6 @@
1 
2  LGP = LGPCommandLine('lgp', doc=description, rcfile=LGP_CONFIG_FILE,
3                       version=version)
4 
5 
6 -__all__ = ['LGP', 'clean', 'build', 'check', 'tag', 'setup',
7 -           'login', 'script']
8 +__all__ = ['LGP', 'clean', 'build', 'check', 'tag', 'setup', 'shell']
diff --git a/lgp/login.py b/lgp/login.py
@@ -1,84 +0,0 @@
9 -# -*- coding: utf-8 -*-
10 -#
11 -# Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE).
12 -# http://www.logilab.fr/ -- mailto:contact@logilab.fr
13 -#
14 -# This program is free software; you can redistribute it and/or modify it under
15 -# the terms of the GNU General Public License as published by the Free Software
16 -# Foundation; either version 2 of the License, or (at your option) any later
17 -# version.
18 -#
19 -# This program is distributed in the hope that it will be useful, but WITHOUT
20 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
21 -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
22 -#
23 -# You should have received a copy of the GNU General Public License along with
24 -# this program; if not, write to the Free Software Foundation, Inc.,
25 -# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
26 -
27 -import os
28 -from subprocess import check_call, CalledProcessError
29 -
30 -from logilab.devtools.lgp import LGP, CONFIG_FILE, HOOKS_DIR
31 -from logilab.devtools.lgp.setupinfo import SetupInfo
32 -
33 -
34 -@LGP.register
35 -class Login(SetupInfo):
36 -    """Log into a build image.
37 -    """
38 -    name = "login"
39 -    options = SetupInfo.options + [
40 -               ('result',
41 -                {'type': 'string',
42 -                 'default' : '~/dists',
43 -                 'dest' : "dist_dir",
44 -                 'short': 'r',
45 -                 'metavar': "<directory>",
46 -                 'help': "mount compilation results directory"
47 -               })
48 -              ]
49 -    cmd = ("%s %s --configfile %s  --hookdir %s --bindmounts %s"
50 -           "--othermirror %s  --override-config")
51 -    pbuilder_cmd = "/usr/sbin/pbuilder %s" % name
52 -    sudo_cmd = "/usr/bin/sudo -E"
53 -
54 -    def go_into_package_dir(self, arguments):
55 -        pass
56 -
57 -    def _set_package_format(self):
58 -        pass
59 -
60 -    def _prune_pkg_dir(self):
61 -        pass
62 -
63 -    def other_mirror(self, resultdir):
64 -        dirname, basename = os.path.split(self.get_distrib_dir(resultdir))
65 -        return "'deb file://%s %s/'" % (dirname, basename)
66 -
67 -    def guess_environment(self):
68 -        # if no default value for distribution, try to retrieve it from changelog
69 -        if self.config.distrib is None or 'changelog' in self.config.distrib:
70 -            self.config.distrib = 'changelog'
71 -        super(Login, self).guess_environment()
72 -
73 -    def run(self, args):
74 -        for arch in self.get_architectures():
75 -            for distrib in self.distributions:
76 -                image = self.get_basetgz(distrib, arch)
77 -
78 -                resultdir = self.get_distrib_dir(distrib)
79 -                other_mirror = self.other_mirror(resultdir)
80 -                cmd = self.cmd % (self.sudo_cmd, self.pbuilder_cmd, CONFIG_FILE,
81 -                                  HOOKS_DIR, resultdir, other_mirror)
82 -
83 -                self.logger.info("login into '%s/%s' image" % (distrib, arch))
84 -                self.logger.debug("run command: %s", cmd)
85 -                try:
86 -                    check_call(cmd, shell=True,
87 -                               env={'DIST': distrib, 'ARCH': arch, 'IMAGE': image,
88 -                                    'DISPLAY': os.environ.get('DISPLAY', ""),
89 -                                    'OTHERMIRROR': other_mirror})
90 -                except CalledProcessError, err:
91 -                    self.logger.warn("returned non-zero exit status %s",
92 -                                     err.returncode)
diff --git a/lgp/script.py b/lgp/script.py
@@ -1,95 +0,0 @@
93 -# -*- coding: utf-8 -*-
94 -#
95 -# Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE).
96 -# http://www.logilab.fr/ -- mailto:contact@logilab.fr
97 -#
98 -# This program is free software; you can redistribute it and/or modify it under
99 -# the terms of the GNU General Public License as published by the Free Software
100 -# Foundation; either version 2 of the License, or (at your option) any later
101 -# version.
102 -#
103 -# This program is distributed in the hope that it will be useful, but WITHOUT
104 -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
105 -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
106 -#
107 -# You should have received a copy of the GNU General Public License along with
108 -# this program; if not, write to the Free Software Foundation, Inc.,
109 -# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
110 -
111 -import os
112 -import sys
113 -import glob
114 -from subprocess import check_call, CalledProcessError
115 -
116 -from logilab.devtools.lgp import LGP, CONFIG_FILE, SCRIPTS_DIR, HOOKS_DIR
117 -from logilab.devtools.lgp.setupinfo import SetupInfo
118 -from logilab.devtools.lgp.exceptions import LGPException, LGPCommandException
119 -
120 -
121 -@LGP.register
122 -class Script(SetupInfo):
123 -    """Execute script in a chrooted distribution.
124 -
125 -    Full list of scripts is provided with no argument
126 -    """
127 -    name = "script"
128 -    options = [('command',
129 -                {'type': 'choice',
130 -                 'choices': [os.path.basename(x)
131 -                             for x
132 -                             in glob.glob(os.path.join(SCRIPTS_DIR, '*'))],
133 -                 'dest': 'command',
134 -                 'short': 'c',
135 -                 'metavar': "<command>",
136 -                 'help': "script command to run with pbuilder"
137 -                }),
138 -              ]
139 -    arguments = "[options] [<script> FILES...]"
140 -    #min_args = 1
141 -    cmd = "IMAGE=%s DIST=%s ARCH=%s %s %s %s --configfile %s --hookdir %s -- %s %s"
142 -    pbuilder_cmd = "/usr/sbin/pbuilder execute"
143 -    sudo_cmd = "/usr/bin/sudo -E"
144 -
145 -    def go_into_package_dir(self, arguments):
146 -        pass
147 -
148 -    def _set_package_format(self):
149 -        pass
150 -
151 -    def run(self, args):
152 -
153 -        if not self.config.command and len(args)==0:
154 -            commands = dict(self.options)['command']['choices']
155 -            self.logger.info('available command(s): %s', commands)
156 -            sys.exit()
157 -
158 -        if not self.config.command:
159 -            self.config.command = args[0]
160 -            args = args[1:]
161 -
162 -        commands = [c for c in glob.glob(os.path.join(SCRIPTS_DIR, self.config.command))
163 -                    if os.path.basename(c)==self.config.command]
164 -
165 -        if not commands:
166 -            raise LGPException("command '%s' not found. Please check commands in %s"
167 -                               % (self.config.command, SCRIPTS_DIR))
168 -
169 -        for arch in self.get_architectures():
170 -            for distrib in self.distributions:
171 -                for command in commands:
172 -                    image = self.get_basetgz(distrib, arch)
173 -
174 -                    cmd = self.cmd % (image, distrib, arch, self.setarch_cmd, self.sudo_cmd,
175 -                                      self.pbuilder_cmd, CONFIG_FILE, HOOKS_DIR, command,
176 -                                      ' '.join(args))
177 -
178 -                    self.logger.info("execute script '%s' with arguments: %s",
179 -                                     command, ' '.join(args))
180 -                    self.logger.debug("run command: %s", cmd)
181 -                    try:
182 -                        check_call(cmd, stdout=sys.stdout, shell=True,
183 -                                   env={'DIST': distrib, 'ARCH': arch, 'IMAGE': image})
184 -                    except CalledProcessError, err:
185 -                        raise LGPCommandException('an error occured in %s process' %
186 -                                                  self.name, err)
187 -
diff --git a/lgp/shell.py b/lgp/shell.py
@@ -0,0 +1,94 @@
188 +# -*- coding: utf-8 -*-
189 +#
190 +# Copyright (c) 2003-2011 LOGILAB S.A. (Paris, FRANCE).
191 +# http://www.logilab.fr/ -- mailto:contact@logilab.fr
192 +#
193 +# This program is free software; you can redistribute it and/or modify it under
194 +# the terms of the GNU General Public License as published by the Free Software
195 +# Foundation; either version 2 of the License, or (at your option) any later
196 +# version.
197 +#
198 +# This program is distributed in the hope that it will be useful, but WITHOUT
199 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
200 +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
201 +#
202 +# You should have received a copy of the GNU General Public License along with
203 +# this program; if not, write to the Free Software Foundation, Inc.,
204 +# 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
205 +
206 +import os
207 +import sys
208 +import glob
209 +from subprocess import check_call, CalledProcessError
210 +
211 +from logilab.devtools.lgp import LGP, CONFIG_FILE, HOOKS_DIR, SCRIPTS_DIR
212 +from logilab.devtools.lgp.setupinfo import SetupInfo
213 +
214 +@LGP.register
215 +class Shell(SetupInfo):
216 +    """Run a script or interactive shell in a chrooted distribution"""
217 +
218 +    name = "shell"
219 +    options = SetupInfo.options + [
220 +               ('command',
221 +                {'type': 'choice',
222 +                 'choices': [os.path.basename(x)
223 +                             for x in glob.glob(os.path.join(SCRIPTS_DIR, '*'))],
224 +                 'dest': 'command',
225 +                 'short': 'c',
226 +                 'metavar': '<command>',
227 +                 'help': 'script to run in pbuilder'
228 +                }
229 +               ),
230 +              ]
231 +    arguments = "[options] [<script> [args...]]"
232 +    cmd = "%s %s --configfile %s --hookdir %s %s"
233 +    pbuilder_cmd = "/usr/sbin/pbuilder %s"
234 +    sudo_cmd = "/usr/bin/sudo -E"
235 +
236 +    def go_into_package_dir(self, arguments):
237 +        pass
238 +
239 +    def _set_package_format(self):
240 +        pass
241 +
242 +    def _prune_pkg_dir(self):
243 +        pass
244 +
245 +    def run(self, args):
246 +        if not self.config.command and len(args) == 0:
247 +            command = "login"
248 +            script = ""
249 +        else:
250 +            command = "execute"
251 +            if not self.config.command:
252 +                self.config.command = args[0]
253 +                args = args[1:]
254 +            script = os.path.join(SCRIPTS_DIR, self.config.command)
255 +
256 +        if self.config.command and not os.path.exists(script):
257 +            commands = dict(self.options)['command']['choices']
258 +            self.logger.info('available command(s): %s', commands)
259 +            sys.exit(1)
260 +
261 +        for arch in self.get_architectures():
262 +            for distrib in self.distributions:
263 +                image = self.get_basetgz(distrib, arch)
264 +
265 +                cmd = self.cmd % (self.sudo_cmd, (self.pbuilder_cmd % command), CONFIG_FILE, HOOKS_DIR,
266 +                                  script + ' '.join(args))
267 +
268 +                if command == "login":
269 +                    msg = "run shell in %s/%s image" % (distrib, arch)
270 +                else:
271 +                    msg = "run script '%s' in %s/%s image with arguments: %s" % (script, distrib, arch, ' '.join(args))
272 +                self.logger.info(msg)
273 +                self.logger.debug("run command: %s", cmd)
274 +
275 +                try:
276 +                    check_call(cmd, shell=True,
277 +                               env={'DIST': distrib, 'ARCH': arch, 'IMAGE': image})
278 +                except CalledProcessError, err:
279 +                    self.logger.warn("returned non-zero exit status %s", err.returncode)
280 +
281 +