]>
git.ipfire.org Git - pakfire.git/blob - python/pakfire/actions.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
29 from constants
import *
33 def __init__(self
, pakfire
, pkg
):
34 self
.pakfire
= pakfire
35 self
.pkg_solv
= self
.pkg
= pkg
37 # Try to get the binary version of the package from the cache if
39 binary_package
= self
.pkg
.get_from_cache()
41 self
.pkg
= binary_package
45 def __cmp__(self
, other
):
46 return cmp(self
.pkg
, other
.pkg
)
49 return "<%s %s>" % (self
.__class
__.__name
__, self
.pkg
.friendly_name
)
52 # A function to run additional initialization.
56 def needs_download(self
):
57 return self
.type in ("install", "reinstall", "upgrade", "downgrade",) \
58 and not isinstance(self
.pkg
, packages
.BinaryPackage
)
60 def download(self
, text
):
61 if not self
.needs_download
:
64 self
.pkg
= self
.pkg
.download(text
)
67 raise NotImplementedError
72 Reference to local repository.
74 return self
.pakfire
.repos
.local
77 class ActionScript(Action
):
83 self
.scriptlet
= self
.pkg
.get_scriptlet(self
.script_action
)
86 def interpreter(self
):
88 Get the interpreter of this scriptlet.
90 return util
.scriptlet_interpreter(self
.scriptlet
)
97 # Exit immediately, if the scriptlet is empty.
98 if not self
.scriptlet
:
101 # Actually run the scriplet.
102 logging
.debug("Running scriptlet %s" % self
)
104 # Check if the interpreter does exist and is executable.
106 interpreter
= "%s/%s" % (self
.pakfire
.path
, self
.interpreter
)
107 if not os
.path
.exists(interpreter
):
108 raise ActionError
, _("Cannot run scriptlet because no interpreter is available: %s" \
111 if not os
.access(interpreter
, os
.X_OK
):
112 raise ActionError
, _("Cannot run scriptlet because the interpreter is not executable: %s" \
115 # Create a name for the temporary script file.
116 script_file_chroot
= os
.path
.join("/", LOCAL_TMP_PATH
,
117 "scriptlet_%s" % util
.random_string(10))
118 script_file
= os
.path
.join(self
.pakfire
.path
, script_file_chroot
[1:])
119 assert script_file
.startswith("%s/" % self
.pakfire
.path
)
121 # Create script directory, if it does not exist.
122 script_dir
= os
.path
.dirname(script_file
)
123 if not os
.path
.exists(script_dir
):
124 os
.makedirs(script_dir
)
126 # Write the scriptlet to a file that we can execute it.
128 f
= open(script_file
, "wb")
129 f
.write(self
.scriptlet
)
132 # The file is only accessable by root.
133 os
.chmod(script_file
, 700)
135 # Remove the file if an error occurs.
137 os
.unlink(script_file
)
141 # XXX catch errors and return a beautiful message to the user
144 # Generate the script command.
145 command
= [script_file_chroot
] + self
.args
147 # If we are running in /, we do not need to chroot there.
149 if not self
.pakfire
.path
== "/":
150 chroot_path
= self
.pakfire
.path
153 ret
= chroot
.do(command
, cwd
="/tmp",
154 chrootPath
=chroot_path
,
155 personality
=self
.pakfire
.distro
.personality
,
157 timeout
=SCRIPTLET_TIMEOUT
,
158 logger
=logging
.getLogger())
161 raise ActionError
, _("The scriptlet returned an error:\n%s" % e
)
163 except commandTimeoutExpired
:
164 raise ActionError
, _("The scriptlet ran more than %s seconds and was killed." \
168 # Remove the script file.
170 os
.unlink(script_file
)
172 logging
.debug("Could not remove scriptlet file: %s" % script_file
)
175 class ActionScriptPreIn(ActionScript
):
176 script_action
= "prein"
179 class ActionScriptPostIn(ActionScript
):
180 script_action
= "postin"
183 class ActionScriptPreUn(ActionScript
):
184 script_action
= "preun"
187 class ActionScriptPostUn(ActionScript
):
188 script_action
= "postun"
191 class ActionScriptPreUp(ActionScript
):
192 script_action
= "preup"
195 class ActionScriptPostUp(ActionScript
):
196 script_action
= "postup"
199 class ActionScriptPostTrans(ActionScript
):
203 class ActionScriptPostTransIn(ActionScriptPostTrans
):
204 script_action
= "posttransin"
207 class ActionScriptPostTransUn(ActionScriptPostTrans
):
208 script_action
= "posttransun"
211 class ActionScriptPostTransUp(ActionScriptPostTrans
):
212 script_action
= "posttransup"
215 class ActionInstall(Action
):
219 # Add package to the database.
220 self
.local
.add_package(self
.pkg
)
222 self
.pkg
.extract(_("Installing"), prefix
=self
.pakfire
.path
)
225 class ActionUpdate(Action
):
229 # Add new package to the database.
230 self
.local
.add_package(self
.pkg
)
232 self
.pkg
.extract(_("Updating"), prefix
=self
.pakfire
.path
)
235 class ActionRemove(Action
):
238 def __init__(self
, *args
, **kwargs
):
239 Action
.__init
__(self
, *args
, **kwargs
)
241 # XXX This is ugly, but works for the moment.
242 self
.pkg
= self
.local
.index
.db
.get_package_from_solv(self
.pkg_solv
)
246 self
.pkg
.cleanup(_("Removing"), prefix
=self
.pakfire
.path
)
248 # Remove package from the database.
249 self
.local
.rem_package(self
.pkg
)
252 class ActionCleanup(Action
):
255 def __init__(self
, *args
, **kwargs
):
256 Action
.__init
__(self
, *args
, **kwargs
)
258 # XXX This is ugly, but works for the moment.
259 self
.pkg
= self
.local
.index
.db
.get_package_from_solv(self
.pkg_solv
)
263 # Cleaning up leftover files and stuff.
264 self
.pkg
.cleanup(_("Cleanup"), prefix
=self
.pakfire
.path
)
266 # Remove package from the database.
267 self
.local
.rem_package(self
.pkg
)
270 class ActionReinstall(Action
):
274 # Remove package from the database and add it afterwards.
275 # Sounds weird, but fixes broken entries in the database.
276 self
.local
.rem_package(self
.pkg
)
277 self
.local
.add_package(self
.pkg
)
279 self
.pkg
.extract(_("Installing"), prefix
=self
.pakfire
.path
)
282 class ActionDowngrade(Action
):
286 # Add new package to database.
287 self
.local
.add_package(self
.pkg
)
289 self
.pkg
.extract(_("Downgrading"), prefix
=self
.pakfire
.path
)
292 class ActionChange(Action
):
295 # XXX still need to find out what this should be doing
298 print "XXX Change: %s" % self
.pkg