~ubuntu-branches/ubuntu/lucid/sabayon/lucid

« back to all changes in this revision

Viewing changes to lib/storage.py

  • Committer: Bazaar Package Importer
  • Author(s): Scott Balneaves
  • Date: 2009-12-28 16:58:21 UTC
  • mfrom: (1.1.16 upstream)
  • Revision ID: james.westby@ubuntu.com-20091228165821-38riqcxr41abmelj
Tags: 2.29.5~rc1-0ubuntu1
* New upstream release
  - Depend on Pessulus
  - Added manual
  - Fixed several crasher bugs
  - Added apply by group
  - Symlinks now saved in zipfile
* debian
  - Updated deps in control
  - removed sabayon.8, sabayon-apply.8, install.manpages (upstream man)

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
    fact that there is a temporary directory are both
93
93
    implementation details and not exposed in the API.
94
94
 
95
 
    Profile files are stored in /etc/desktop-profiles.
 
95
    Profile files are stored in /etc/sabayon/profiles.
96
96
 
97
97
    Each file or directory in the profile has metadata
98
98
    associated with it - the "source" of the file/directory
104
104
        """Create a ProfileStorage.
105
105
 
106
106
        @name: the name of the profile - translates to
107
 
        /etc/desktop-profiles/$(name).zip.
 
107
        /etc/sabayon/profiles/$(name).zip.
108
108
        """
109
109
        self.name = name
110
110
        self.readonly = 0
151
151
        metadata = libxml2.newDoc ("1.0")
152
152
        root = metadata.newChild (None, "metadata", None)
153
153
        root.newChild (None, "directories", None)
 
154
        root.newChild (None, "links", None)
154
155
        root.newChild (None, "files", None)
155
156
        return metadata
156
157
 
257
258
 
258
259
        self.__update_file_or_dir_node (directory_node, source, attributes, metadata)
259
260
 
 
261
    def __update_link_node (self, path, source, attributes, metadata = None):
 
262
        if metadata is None:
 
263
            metadata = self.metadata
 
264
        assert metadata
 
265
 
 
266
        files_node = metadata.xpathEval ("/metadata/links")[0]
 
267
 
 
268
        # Ensure the directory node exists
 
269
        nodes = files_node.xpathEval ("link[@path='%s']" % path)
 
270
        if len (nodes):
 
271
            link_node = nodes[0]
 
272
        else:
 
273
            link_node = files_node.newChild (None, "link", None)
 
274
            link_node.setProp ("path", path)
 
275
            link_node.setProp ("dest", os.readlink(path))
 
276
 
 
277
        self.__update_file_or_dir_node (link_node, source, attributes, metadata)
 
278
 
260
279
    def __unpack (self):
261
280
        self.__read_metadata ()
262
281
 
284
303
                    os.makedirs (dest_dir)
285
304
 
286
305
                # It sucks that we lose file permissions, mtime etc. with ZIP
287
 
                file (dest_path, "w").write (zip.read (f))
 
306
                zip.extract(f, dir)
288
307
 
289
308
        def unzip_foreach (path, is_directory, data):
290
309
            (zip, temp_path) = data
302
321
                    os.makedirs (dest_dir)
303
322
 
304
323
                # It sucks that we lose file permissions, mtime etc. with ZIP
305
 
                file (abs_path, "w").write (zip.read (path))
 
324
                zip.extract(path, temp_path)
306
325
 
307
326
        self.__foreach_all (unzip_foreach, (self.zip, self.temp_path))
308
327
 
359
378
        dst_path = os.path.join (self.temp_path, path)
360
379
 
361
380
        if not os.path.exists (src_path):
362
 
            raise ProfileStorageException (_("Cannot add non-existent file '%s'") % src_path)
 
381
            # change the raise to a dprint, since some files seem to disappear.
 
382
            # raise ProfileStorageException (_("Cannot add non-existent file '%s'") % src_path)
 
383
            dprint (_("Cannot add non-existent file '%s'"), src_path)
 
384
            return
363
385
 
364
386
        # Remove old version
365
387
        node = self.__get_node (path)
371
393
        if os.path.isdir (src_path):
372
394
            self.__update_directory_node (path, source, attributes)
373
395
            copy_tree (self.temp_path, src_dir, path)
374
 
        else:
 
396
        elif os.path.islink (src_path):
 
397
            self.__update_link_node (path, source, attributes)
 
398
        elif os.path.isfile (src_path) and not os.path.islink (src_path):
375
399
            self.__update_file_node (path, source, attributes)
376
400
            dirname = os.path.dirname (dst_path)
377
401
            if not os.path.exists (dirname):
389
413
            return dir_nodes[0]
390
414
        return None
391
415
 
 
416
    def __get_link_node (self, path, metadata = None):
 
417
        if metadata is None:
 
418
            metadata = self.metadata
 
419
        assert metadata
 
420
        link_nodes = metadata.xpathEval ("/metadata/links/link[@path='%s']" % path)
 
421
        if len (link_nodes) > 0:
 
422
            return link_nodes[0]
 
423
        return None
 
424
 
392
425
    def __get_file_node (self, path, metadata = None):
393
426
        if metadata is None:
394
427
            metadata = self.metadata
404
437
        node = self.__get_dir_node (path, metadata)
405
438
        if node:
406
439
            return node
 
440
        node = self.__get_link_node (path, metadata)
 
441
        if node:
 
442
            return node
407
443
        node = self.__get_file_node (path, metadata)
408
444
        if node:
409
445
            return node
436
472
        node = self.__get_dir_node (path)
437
473
        if node:
438
474
            return "directory"
 
475
        node = self.__get_link_node (path)
 
476
        if node:
 
477
            return "link"
439
478
        node = self.__get_file_node (path)
440
479
        if node:
441
480
            return "file"
481
520
                    raise err
482
521
 
483
522
            if got_stat:
484
 
                os.unlink (dest) # FIXME: this could fail, but that would be because the parent
485
 
                                 # directory is not writable.  Then we have bigger problems, anyway.
 
523
                if os.path.isdir (dest):
 
524
                    try:
 
525
                        os.rmdir (dest)
 
526
                    except OSError, err:
 
527
                        raise ProfileStorageException (_("Couldn't rmdir '%s'") % dest)
 
528
                else:
 
529
                    try:
 
530
                        os.unlink (dest)
 
531
                    except OSError, err:
 
532
                        raise ProfileStorageException (_("Couldn't unlink file '%s'") % dest)
486
533
 
487
534
            # FIXME: we lose the "original" permissions, mtime, etc. with ZIP files.
488
535
            shutil.copy2 (src, dest)
498
545
 
499
546
        if item_type == "directory":
500
547
            copy_tree (dst_dir, self.temp_path, path, None, overwrite)
 
548
        elif item_type == "link":
 
549
            link_node = self.__get_link_node (path)
 
550
            dest = link_node.prop("dest")
 
551
            os.symlink(dest, path)
501
552
        else:
502
553
            dst_path = os.path.join (dst_dir, path)
503
554
            if overwrite or not os.path.exists (dst_path):
554
605
        """
555
606
        self.__read_metadata ()
556
607
 
 
608
        for node in self.metadata.xpathEval ("/metadata/directories/directory"):
 
609
            self.__foreach_node (node, callback, user_data, source)
 
610
 
 
611
        for node in self.metadata.xpathEval ("/metadata/links/link"):
 
612
            self.__foreach_node (node, callback, user_data, source)
 
613
 
557
614
        for node in self.metadata.xpathEval ("/metadata/files/file"):
558
615
            self.__foreach_node (node, callback, user_data, source)
559
616
 
560
 
        for node in self.metadata.xpathEval ("/metadata/directories/directory"):
561
 
            self.__foreach_node (node, callback, user_data, source)
562
 
 
563
617
    def save (self):
564
618
        """Save the contents of the profile to
565
 
        /etc/desktop-profiles/$(name).zip.
 
619
        /etc/sabayon/profiles/$(name).zip.
566
620
        """
567
621
        if self.readonly:
568
622
            raise ProfileStorageException (_("Profile is read-only %s") %
600
654
                    if os.path.isdir (path):
601
655
                        # We need to stop if we are recursing inside a ignored 
602
656
                        # directory.
603
 
                        if util.should_ignore_dir (homedir, 
 
657
                        if util.should_ignore_dir (homedir,
604
658
                                                   DIRECTORIES_TO_IGNORE_PROFILE,
605
659
                                                   os.path.join (homedir, name, f)):
606
660
                            dprint ("Not going inside %s as it is an ignored directory.", path)
608
662
                            zip_directory (save_zip,
609
663
                                        path,
610
664
                                        os.path.join (name, f))
611
 
                    elif os.path.isfile (path):
 
665
                    elif os.path.isfile (path) and not os.path.islink (path):
612
666
                        # Avoid putting in a duplicate file entry
613
667
                        # See bug #476761
614
668
                        if os.path.join (name, f) in zip_filelist:
615
669
                            dprint ("Not adding %s to zipfile since it is already in the file", os.path.join (name, f))
616
 
                        elif util.should_ignore_file (homedir, 
 
670
                        elif util.should_ignore_file (homedir,
617
671
                                                      DIRECTORIES_TO_IGNORE_PROFILE,
618
672
                                                      FILES_TO_IGNORE,
619
673
                                                      os.path.join (homedir, name, f)):
638
692
        except:
639
693
            if backup:
640
694
                failsafe_rename (backup, self.path)
641
 
            raise
642
695
 
643
696
        if backup:
644
697
            os.remove (backup)