~ubuntu-branches/ubuntu/lucid/landscape-client/lucid-updates

« back to all changes in this revision

Viewing changes to landscape/package/changer.py

  • Committer: Package Import Robot
  • Author(s): Andreas Hasenack
  • Date: 2012-04-10 14:28:48 UTC
  • mfrom: (1.1.27)
  • mto: This revision was merged to the branch mainline in revision 35.
  • Revision ID: package-import@ubuntu.com-20120410142848-7xsy4g2xii7y7ntc
ImportĀ upstreamĀ versionĀ 12.04.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
from landscape.package.taskhandler import (
19
19
    PackageTaskHandler, PackageTaskHandlerConfiguration, PackageTaskError,
20
20
    run_task_handler)
21
 
from landscape.manager.manager import SUCCEEDED
 
21
from landscape.manager.manager import FAILED, SUCCEEDED
22
22
 
23
23
 
24
24
class UnknownPackageData(Exception):
63
63
        """
64
64
        Handle our tasks and spawn the reporter if package data has changed.
65
65
        """
66
 
        if not self.smart_update_stamp_exists():
 
66
        if not self.update_stamp_exists():
67
67
            logging.warning("The package-reporter hasn't run yet, exiting.")
68
68
            return succeed(None)
69
69
 
103
103
            return result.addErrback(self.unknown_package_data_error, task)
104
104
        if message["type"] == "change-package-locks":
105
105
            return self.handle_change_package_locks(message)
 
106
        if message["type"] == "change-package-holds":
 
107
            return self.handle_change_package_holds(message)
106
108
 
107
109
    def unknown_package_data_error(self, failure, task):
108
110
        """Handle L{UnknownPackageData} data errors.
127
129
        else:
128
130
            raise PackageTaskError()
129
131
 
130
 
    def smart_update_stamp_exists(self):
131
 
        """
132
 
        Return a boolean indicating if the smart-update stamp file exists.
133
 
        """
134
 
        return os.path.exists(self._config.smart_update_stamp_filename)
 
132
    def update_stamp_exists(self):
 
133
        """
 
134
        Return a boolean indicating if the update-stamp stamp file exists.
 
135
        """
 
136
        return os.path.exists(self._config.update_stamp_filename)
 
137
 
 
138
    def _clear_binaries(self):
 
139
        """Remove any binaries and its associated channel."""
 
140
        binaries_path = self._config.binaries_path
 
141
 
 
142
        for existing_deb_path in os.listdir(binaries_path):
 
143
            # Clean up the binaries we wrote in former runs
 
144
            os.remove(os.path.join(binaries_path, existing_deb_path))
 
145
        self._facade.clear_channels()
135
146
 
136
147
    def init_channels(self, binaries=()):
137
148
        """Initialize the Smart channels as needed.
142
153
        """
143
154
        binaries_path = self._config.binaries_path
144
155
 
145
 
        for existing_deb_path in os.listdir(binaries_path):
146
 
            # Clean up the binaries we wrote in former runs
147
 
            os.remove(os.path.join(binaries_path, existing_deb_path))
 
156
        # Clean up the binaries we wrote in former runs
 
157
        self._clear_binaries()
148
158
 
149
159
        if binaries:
150
160
            hash_ids = {}
154
164
                hash_ids[hash] = id
155
165
            self._store.set_hash_ids(hash_ids)
156
166
            self._facade.add_channel_deb_dir(binaries_path)
 
167
            self._facade.reload_channels(force_reload_binaries=True)
157
168
 
158
169
        self._facade.ensure_channels_reloaded()
159
170
 
169
180
            self._facade.reset_marks()
170
181
 
171
182
        if upgrade:
172
 
            for package in self._facade.get_packages():
173
 
                if package.installed:
174
 
                    self._facade.mark_upgrade(package)
 
183
            self._facade.mark_global_upgrade()
175
184
 
176
185
        for ids, mark_func in [(install, self._facade.mark_install),
177
186
                                 (remove, self._facade.mark_remove)]:
215
224
                        # Will have to wait until the server lets us know about
216
225
                        # this id.
217
226
                        raise UnknownPackageData(hash)
218
 
                    if package.installed:
 
227
                    if self._facade.is_package_installed(package):
219
228
                        # Package currently installed. Must remove it.
220
229
                        result.removals.append(id)
221
230
                    else:
260
269
                           message.get("remove", ()))
261
270
 
262
271
        result = self.change_packages(message.get("policy", POLICY_STRICT))
 
272
        self._clear_binaries()
263
273
 
264
274
        response = {"type": "change-packages-result",
265
275
                   "operation-id": message.get("operation-id")}
272
282
        if result.removals:
273
283
            response["must-remove"] = sorted(result.removals)
274
284
 
275
 
 
276
285
        logging.info("Queuing response with change package results to "
277
286
                     "exchange urgently.")
278
287
        return self._broker.send_message(response, True)
283
292
        Create and delete package locks as requested by the given C{message}.
284
293
        """
285
294
 
 
295
        if not self._facade.supports_package_locks:
 
296
            response = {
 
297
                "type": "operation-result",
 
298
                "operation-id": message.get("operation-id"),
 
299
                "status": FAILED,
 
300
                "result-text": "This client doesn't support package locks.",
 
301
                "result-code": 1}
 
302
            return self._broker.send_message(response, True)
 
303
 
286
304
        for lock in message.get("create", ()):
287
305
            self._facade.set_package_lock(*lock)
288
306
        for lock in message.get("delete", ()):
299
317
                     "exchange urgently.")
300
318
        return self._broker.send_message(response, True)
301
319
 
 
320
    def _send_change_package_holds_response(self, response):
 
321
        """Log that a package holds result is sent and send the response."""
 
322
        logging.info("Queuing message with change package holds results to "
 
323
                     "exchange urgently.")
 
324
        return self._broker.send_message(response, True)
 
325
 
 
326
    def handle_change_package_holds(self, message):
 
327
        """Handle a C{change-package-holds} message.
 
328
 
 
329
        Create and delete package holds as requested by the given C{message}.
 
330
        """
 
331
        if not self._facade.supports_package_holds:
 
332
            response = {
 
333
                "type": "operation-result",
 
334
                "operation-id": message.get("operation-id"),
 
335
                "status": FAILED,
 
336
                "result-text": "This client doesn't support package holds.",
 
337
                "result-code": 1}
 
338
            return self._send_change_package_holds_response(response)
 
339
 
 
340
        not_installed = set()
 
341
        holds_to_create = message.get("create", [])
 
342
        versions_to_create = set()
 
343
        for id in holds_to_create:
 
344
            hash = self._store.get_id_hash(id)
 
345
            hold_version = self._facade.get_package_by_hash(hash)
 
346
            if (hold_version
 
347
                and self._facade.is_package_installed(hold_version)):
 
348
                versions_to_create.add((hold_version.package, hold_version))
 
349
            else:
 
350
                not_installed.add(str(id))
 
351
        holds_to_remove = message.get("delete", [])
 
352
        versions_to_remove = set()
 
353
        for id in holds_to_remove:
 
354
            hash = self._store.get_id_hash(id)
 
355
            hold_version = self._facade.get_package_by_hash(hash)
 
356
            if (hold_version
 
357
                and self._facade.is_package_installed(hold_version)):
 
358
                versions_to_remove.add((hold_version.package, hold_version))
 
359
 
 
360
        if not_installed:
 
361
            response = {
 
362
                "type": "operation-result",
 
363
                "operation-id": message.get("operation-id"),
 
364
                "status": FAILED,
 
365
                "result-text": "Package holds not changed, since the" +
 
366
                               " following packages are not installed: %s" % (
 
367
                                   ", ".join(sorted(not_installed))),
 
368
                "result-code": 1}
 
369
            return self._send_change_package_holds_response(response)
 
370
 
 
371
        for package, hold_version in versions_to_create:
 
372
            self._facade.set_package_hold(hold_version)
 
373
        for package, hold_version in versions_to_remove:
 
374
            self._facade.remove_package_hold(hold_version)
 
375
 
 
376
        self._facade.reload_channels()
 
377
 
 
378
        response = {"type": "operation-result",
 
379
                    "operation-id": message.get("operation-id"),
 
380
                    "status": SUCCEEDED,
 
381
                    "result-text": "Package holds successfully changed.",
 
382
                    "result-code": 0}
 
383
 
 
384
        return self._send_change_package_holds_response(response)
 
385
 
302
386
    @staticmethod
303
387
    def find_command():
304
388
        return find_changer_command()