~ubuntu-branches/ubuntu/trusty/swift/trusty-updates

« back to all changes in this revision

Viewing changes to swift/obj/server.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2013-01-28 09:40:30 UTC
  • mfrom: (1.2.16)
  • Revision ID: package-import@ubuntu.com-20130128094030-aetz57x2qz9ye2d4
Tags: 1.7.6-0ubuntu1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
118
118
            path, device, storage_directory(DATADIR, partition, name_hash))
119
119
        self.device_path = os.path.join(path, device)
120
120
        self.tmpdir = os.path.join(path, device, 'tmp')
 
121
        self.tmppath = None
121
122
        self.logger = logger
122
123
        self.metadata = {}
123
124
        self.meta_file = None
278
279
        """Contextmanager to make a temporary file."""
279
280
        if not os.path.exists(self.tmpdir):
280
281
            mkdirs(self.tmpdir)
281
 
        fd, tmppath = mkstemp(dir=self.tmpdir)
 
282
        fd, self.tmppath = mkstemp(dir=self.tmpdir)
282
283
        try:
283
 
            yield fd, tmppath
 
284
            yield fd
284
285
        finally:
285
286
            try:
286
287
                os.close(fd)
287
288
            except OSError:
288
289
                pass
 
290
            tmppath, self.tmppath = self.tmppath, None
289
291
            try:
290
292
                os.unlink(tmppath)
291
293
            except OSError:
292
294
                pass
293
295
 
294
 
    def put(self, fd, tmppath, metadata, extension='.data'):
 
296
    def put(self, fd, metadata, extension='.data'):
295
297
        """
296
298
        Finalize writing the file on disk, and renames it from the temp file to
297
299
        the real location.  This should be called after the data has been
298
300
        written to the temp file.
299
301
 
300
 
        :params fd: file descriptor of the temp file
301
 
        :param tmppath: path to the temporary file being used
 
302
        :param fd: file descriptor of the temp file
302
303
        :param metadata: dictionary of metadata to be written
303
304
        :param extension: extension to be used when making the file
304
305
        """
 
306
        assert self.tmppath is not None
305
307
        metadata['name'] = self.name
306
308
        timestamp = normalize_timestamp(metadata['X-Timestamp'])
307
309
        write_metadata(fd, metadata)
309
311
            self.drop_cache(fd, 0, int(metadata['Content-Length']))
310
312
        tpool.execute(fsync, fd)
311
313
        invalidate_hash(os.path.dirname(self.datadir))
312
 
        renamer(tmppath, os.path.join(self.datadir, timestamp + extension))
 
314
        renamer(self.tmppath,
 
315
                os.path.join(self.datadir, timestamp + extension))
313
316
        self.metadata = metadata
314
317
 
 
318
    def put_metadata(self, metadata, tombstone=False):
 
319
        """
 
320
        Short hand for putting metadata to .meta and .ts files.
 
321
 
 
322
        :param metadata: dictionary of metadata to be written
 
323
        :param tombstone: whether or not we are writing a tombstone
 
324
        """
 
325
        extension = '.ts' if tombstone else '.meta'
 
326
        with self.mkstemp() as fd:
 
327
            self.put(fd, metadata, extension=extension)
 
328
 
315
329
    def unlinkold(self, timestamp):
316
330
        """
317
331
        Remove any older versions of the object file.  Any file that has an
565
579
            if old_delete_at:
566
580
                self.delete_at_update('DELETE', old_delete_at, account,
567
581
                                      container, obj, request.headers, device)
568
 
        with file.mkstemp() as (fd, tmppath):
569
 
            file.put(fd, tmppath, metadata, extension='.meta')
 
582
        file.put_metadata(metadata)
570
583
        return HTTPAccepted(request=request)
571
584
 
572
585
    @public
600
613
        etag = md5()
601
614
        upload_size = 0
602
615
        last_sync = 0
603
 
        with file.mkstemp() as (fd, tmppath):
 
616
        with file.mkstemp() as fd:
604
617
            if 'content-length' in request.headers:
605
618
                try:
606
619
                    fallocate(fd, int(request.headers['content-length']))
654
667
                    self.delete_at_update(
655
668
                        'DELETE', old_delete_at, account, container, obj,
656
669
                        request.headers, device)
657
 
            file.put(fd, tmppath, metadata)
 
670
            file.put(fd, metadata)
658
671
        file.unlinkold(metadata['X-Timestamp'])
659
672
        if not orig_timestamp or \
660
673
                orig_timestamp < request.headers['x-timestamp']:
821
834
        metadata = {
822
835
            'X-Timestamp': request.headers['X-Timestamp'], 'deleted': True,
823
836
        }
824
 
        with file.mkstemp() as (fd, tmppath):
825
 
            old_delete_at = int(file.metadata.get('X-Delete-At') or 0)
826
 
            if old_delete_at:
827
 
                self.delete_at_update('DELETE', old_delete_at, account,
828
 
                                      container, obj, request.headers, device)
829
 
            file.put(fd, tmppath, metadata, extension='.ts')
 
837
        old_delete_at = int(file.metadata.get('X-Delete-At') or 0)
 
838
        if old_delete_at:
 
839
            self.delete_at_update('DELETE', old_delete_at, account,
 
840
                                  container, obj, request.headers, device)
 
841
        file.put_metadata(metadata, tombstone=True)
830
842
        file.unlinkold(metadata['X-Timestamp'])
831
843
        if not orig_timestamp or \
832
844
                orig_timestamp < request.headers['x-timestamp']:
868
880
        self.logger.txn_id = req.headers.get('x-trans-id', None)
869
881
 
870
882
        if not check_utf8(req.path_info):
871
 
            res = HTTPPreconditionFailed(body='Invalid UTF8')
 
883
            res = HTTPPreconditionFailed(body='Invalid UTF8 or contains NULL')
872
884
        else:
873
885
            try:
874
886
                # disallow methods which have not been marked 'public'