lfs: move abstract local blobstore to core mercurial

Summary: It will be used by snapshot extension too.

Reviewed By: markbt

Differential Revision: D17132134

fbshipit-source-id: 6c9fc285e0f1eb445bfa0abe0b6f4de4a1bd1db0
This commit is contained in:
Aleksei Kulikov 2019-09-04 11:07:35 -07:00 committed by Facebook Github Bot
parent 4576ab19c2
commit bead18e577
3 changed files with 59 additions and 33 deletions

View File

@ -7,11 +7,11 @@
from __future__ import absolute_import
import hashlib
import json
import os
from edenscm.mercurial import (
blobstore,
error,
pathutil,
perftrace,
@ -58,7 +58,7 @@ class filewithprogress(object):
self._fp = None
class local(object):
class local(blobstore.localblobstore):
"""Local blobstore for large file contents.
This blobstore is used both as a cache and as a staging area for large blobs
@ -67,38 +67,12 @@ class local(object):
def __init__(self, repo):
fullpath = repo.svfs.join("lfs/objects")
self.vfs = vfsmod.blobvfs(fullpath)
vfs = vfsmod.blobvfs(fullpath)
cachevfs = None
usercachepath = repo.ui.config("lfs", "usercache")
if usercachepath:
self.cachevfs = vfsmod.blobvfs(usercachepath)
else:
self.cachevfs = None
def write(self, oid, data):
"""Write blob to local blobstore."""
contentsha256 = hashlib.sha256(data).hexdigest()
if contentsha256 != oid:
raise error.Abort(
_("lfs: sha256 mismatch (oid: %s, content: %s)") % (oid, contentsha256)
)
with self.vfs(oid, "wb", atomictemp=True) as fp:
fp.write(data)
# XXX: should we verify the content of the cache, and hardlink back to
# the local store on success, but truncate, write and link on failure?
if self.cachevfs and not self.cachevfs.exists(oid):
self.vfs.linktovfs(oid, self.cachevfs)
def read(self, oid):
"""Read blob from local blobstore."""
if self.cachevfs and not self.vfs.exists(oid):
self.cachevfs.linktovfs(oid, self.vfs)
return self.vfs.read(oid)
def has(self, oid):
"""Returns True if the local blobstore contains the requested blob,
False otherwise."""
return (self.cachevfs and self.cachevfs.exists(oid)) or self.vfs.exists(oid)
cachevfs = vfsmod.blobvfs(usercachepath)
super(local, self).__init__(vfs, cachevfs)
class memlocal(object):

View File

@ -0,0 +1,52 @@
# blobstore.py - local blob storage
#
# Copyright 2017 Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import hashlib
from . import error
from .i18n import _
class localblobstore(object):
"""A local blobstore.
This blobstore is used both as a cache and as a staging area for large blobs
to be uploaded to the remote blobstore.
"""
def __init__(self, vfs, cachevfs):
self.vfs = vfs
self.cachevfs = cachevfs
def write(self, oid, data):
"""Write blob to local blobstore."""
contentsha256 = hashlib.sha256(data).hexdigest()
if contentsha256 != oid:
raise error.Abort(
_("blobstore: sha256 mismatch (oid: %s, content: %s)")
% (oid, contentsha256)
)
with self.vfs(oid, "wb", atomictemp=True) as fp:
fp.write(data)
# XXX: should we verify the content of the cache, and hardlink back to
# the local store on success, but truncate, write and link on failure?
if self.cachevfs and not self.cachevfs.exists(oid):
self.vfs.linktovfs(oid, self.cachevfs)
def read(self, oid):
"""Read blob from local blobstore."""
if self.cachevfs and not self.vfs.exists(oid):
self.cachevfs.linktovfs(oid, self.vfs)
return self.vfs.read(oid)
def has(self, oid):
"""Returns True if the local blobstore contains the requested blob,
False otherwise."""
return (self.cachevfs and self.cachevfs.exists(oid)) or self.vfs.exists(oid)

View File

@ -30,7 +30,7 @@ Download it again in a fresh new repo - should fail
$ echo remotefilelog >> .hg/requires
$ hg pull ../source -q
$ hg update tip -q
abort: lfs: sha256 mismatch (oid: 2f7548e627a92d9ce3f912eb71226f692ec83deed2e72298270b198540d7c70b, content: 3dff7d61038895144c0eca9d06ac8d067919785a5ba2604db7aef154899a494d)
abort: blobstore: sha256 mismatch (oid: 2f7548e627a92d9ce3f912eb71226f692ec83deed2e72298270b198540d7c70b, content: 3dff7d61038895144c0eca9d06ac8d067919785a5ba2604db7aef154899a494d)
[255]
$ [ -f A ]