本文整理汇总了Golang中github.com/coreos/rkt/pkg/lock.ExclusiveKeyLock函数的典型用法代码示例。如果您正苦于以下问题:Golang ExclusiveKeyLock函数的具体用法?Golang ExclusiveKeyLock怎么用?Golang ExclusiveKeyLock使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了ExclusiveKeyLock函数的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: RenderTreeStore
// RenderTreeStore renders a treestore for the given image key if it's not
// already fully rendered.
// Users of treestore should call s.RenderTreeStore before using it to ensure
// that the treestore is completely rendered.
func (s Store) RenderTreeStore(key string, rebuild bool) error {
// this lock references the treestore dir for the specified key. This
// is different from a lock on an image key as internally
// treestore.Write calls the acirenderer functions that use GetACI and
// GetImageManifest which are taking the image(s) lock.
treeStoreKeyLock, err := lock.ExclusiveKeyLock(s.treeStoreLockDir, key)
if err != nil {
return fmt.Errorf("error locking tree store: %v", err)
}
defer treeStoreKeyLock.Close()
if !rebuild {
rendered, err := s.treestore.IsRendered(key)
if err != nil {
return fmt.Errorf("cannot determine if tree is already rendered: %v", err)
}
if rendered {
return nil
}
}
// Firstly remove a possible partial treestore if existing.
// This is needed as a previous ACI removal operation could have failed
// cleaning the tree store leaving some stale files.
if err := s.treestore.Remove(key); err != nil {
return err
}
if err := s.treestore.Write(key, &s); err != nil {
return err
}
return nil
}
示例2: Render
// Render renders a treestore for the given image key if it's not
// already fully rendered.
// Users of treestore should call s.Render before using it to ensure
// that the treestore is completely rendered.
// Returns the id and hash of the rendered treestore if it is newly rendered,
// and only the id if it is already rendered.
func (ts *Store) Render(key string, rebuild bool) (id string, hash string, err error) {
id, err = ts.GetID(key)
if err != nil {
return "", "", errwrap.Wrap(errors.New("cannot calculate treestore id"), err)
}
// this lock references the treestore dir for the specified id.
treeStoreKeyLock, err := lock.ExclusiveKeyLock(ts.lockDir, id)
if err != nil {
return "", "", errwrap.Wrap(errors.New("error locking tree store"), err)
}
defer treeStoreKeyLock.Close()
if !rebuild {
rendered, err := ts.IsRendered(id)
if err != nil {
return "", "", errwrap.Wrap(errors.New("cannot determine if tree is already rendered"), err)
}
if rendered {
return id, "", nil
}
}
// Firstly remove a possible partial treestore if existing.
// This is needed as a previous ACI removal operation could have failed
// cleaning the tree store leaving some stale files.
if err := ts.remove(id); err != nil {
return "", "", err
}
if hash, err = ts.render(id, key); err != nil {
return "", "", err
}
return id, hash, nil
}
示例3: gcTreeStore
// gcTreeStore removes all treeStoreIDs not referenced by any non garbage
// collected pod from the store.
func gcTreeStore(s *store.Store) error {
// Take an exclusive lock to block other pods being created.
// This is needed to avoid races between the below steps (getting the
// list of referenced treeStoreIDs, getting the list of treeStoreIDs
// from the store, removal of unreferenced treeStoreIDs) and new
// pods/treeStores being created/referenced
keyLock, err := lock.ExclusiveKeyLock(lockDir(), common.PrepareLock)
if err != nil {
return fmt.Errorf("cannot get exclusive prepare lock: %v", err)
}
defer keyLock.Close()
referencedTreeStoreIDs, err := getReferencedTreeStoreIDs()
if err != nil {
return fmt.Errorf("cannot get referenced treestoreIDs: %v", err)
}
treeStoreIDs, err := s.GetTreeStoreIDs()
if err != nil {
return fmt.Errorf("cannot get treestoreIDs from the store: %v", err)
}
for _, treeStoreID := range treeStoreIDs {
if _, ok := referencedTreeStoreIDs[treeStoreID]; !ok {
if err := s.RemoveTreeStore(treeStoreID); err != nil {
stderr("rkt: error removing treestore %q: %v", treeStoreID, err)
} else {
stderr("rkt: removed treestore %q", treeStoreID)
}
}
}
return nil
}
示例4: gcTreeStore
// gcTreeStore removes all treeStoreIDs not referenced by any non garbage
// collected pod from the store.
func gcTreeStore(ts *treestore.Store) error {
// Take an exclusive lock to block other pods being created.
// This is needed to avoid races between the below steps (getting the
// list of referenced treeStoreIDs, getting the list of treeStoreIDs
// from the store, removal of unreferenced treeStoreIDs) and new
// pods/treeStores being created/referenced
keyLock, err := lock.ExclusiveKeyLock(lockDir(), common.PrepareLock)
if err != nil {
return errwrap.Wrap(errors.New("cannot get exclusive prepare lock"), err)
}
defer keyLock.Close()
referencedTreeStoreIDs, err := getReferencedTreeStoreIDs()
if err != nil {
return errwrap.Wrap(errors.New("cannot get referenced treestoreIDs"), err)
}
treeStoreIDs, err := ts.GetIDs()
if err != nil {
return errwrap.Wrap(errors.New("cannot get treestoreIDs from the store"), err)
}
for _, treeStoreID := range treeStoreIDs {
if _, ok := referencedTreeStoreIDs[treeStoreID]; !ok {
if err := ts.Remove(treeStoreID); err != nil {
stderr.PrintE(fmt.Sprintf("error removing treestore %q", treeStoreID), err)
} else {
stderr.Printf("removed treestore %q", treeStoreID)
}
}
}
return nil
}
示例5: RenderTreeStore
// RenderTreeStore renders a treestore for the given image key if it's not
// already fully rendered.
// Users of treestore should call s.RenderTreeStore before using it to ensure
// that the treestore is completely rendered.
// Returns the id of the rendered treestore.
func (s Store) RenderTreeStore(key string, rebuild bool) (string, error) {
id, err := s.GetTreeStoreID(key)
if err != nil {
return "", fmt.Errorf("cannot calculate treestore id: %v", err)
}
// this lock references the treestore dir for the specified id.
treeStoreKeyLock, err := lock.ExclusiveKeyLock(s.treeStoreLockDir, id)
if err != nil {
return "", fmt.Errorf("error locking tree store: %v", err)
}
defer treeStoreKeyLock.Close()
if !rebuild {
rendered, err := s.treestore.IsRendered(id)
if err != nil {
return "", fmt.Errorf("cannot determine if tree is already rendered: %v", err)
}
if rendered {
return id, nil
}
}
// Firstly remove a possible partial treestore if existing.
// This is needed as a previous ACI removal operation could have failed
// cleaning the tree store leaving some stale files.
if err := s.treestore.Remove(id); err != nil {
return "", err
}
if err := s.treestore.Write(id, key, &s); err != nil {
return "", err
}
return id, nil
}
示例6: RemoveTreeStore
// RemoveTreeStore removes the rendered image in tree store with the given key.
func (ds Store) RemoveTreeStore(key string) error {
treeStoreKeyLock, err := lock.ExclusiveKeyLock(ds.treeStoreLockDir, key)
if err != nil {
return fmt.Errorf("error locking tree store: %v", err)
}
defer treeStoreKeyLock.Close()
if err := ds.treestore.Remove(key); err != nil {
return fmt.Errorf("error removing the tree store: %v", err)
}
return nil
}
示例7: Remove
// Remove removes the rendered image in tree store with the given id.
func (ts *Store) Remove(id string) error {
treeStoreKeyLock, err := lock.ExclusiveKeyLock(ts.lockDir, id)
if err != nil {
return errwrap.Wrap(errors.New("error locking tree store"), err)
}
defer treeStoreKeyLock.Close()
if err := ts.remove(id); err != nil {
return errwrap.Wrap(errors.New("error removing the tree store"), err)
}
return nil
}
示例8: RemoveTreeStore
// RemoveTreeStore removes the rendered image in tree store with the given id.
func (s *Store) RemoveTreeStore(id string) error {
treeStoreKeyLock, err := lock.ExclusiveKeyLock(s.treeStoreLockDir, id)
if err != nil {
return fmt.Errorf("error locking tree store: %v", err)
}
defer treeStoreKeyLock.Close()
if err := s.treestore.Remove(id, s); err != nil {
return fmt.Errorf("error removing the tree store: %v", err)
}
return nil
}
示例9: RemoveACI
// RemoveACI removes the ACI with the given key. It firstly removes the aci
// infos inside the db, then it tries to remove the non transactional data.
// If some error occurs removing some non transactional data a
// StoreRemovalError is returned.
func (ds Store) RemoveACI(key string) error {
imageKeyLock, err := lock.ExclusiveKeyLock(ds.imageLockDir, key)
if err != nil {
return fmt.Errorf("error locking image: %v", err)
}
defer imageKeyLock.Close()
// Firstly remove aciinfo and remote from the db in an unique transaction.
// remote needs to be removed or a GetRemote will return a blobKey not
// referenced by any ACIInfo.
err = ds.db.Do(func(tx *sql.Tx) error {
if _, found, err := GetACIInfoWithBlobKey(tx, key); err != nil {
return fmt.Errorf("error getting aciinfo: %v", err)
} else if !found {
return fmt.Errorf("cannot find image with key: %s", key)
}
if err := RemoveACIInfo(tx, key); err != nil {
return err
}
if err := RemoveRemote(tx, key); err != nil {
return err
}
return nil
})
if err != nil {
return fmt.Errorf("cannot remove image with key: %s from db: %v", key, err)
}
// Then remove non transactional entries from the blob, imageManifest
// and tree store.
// TODO(sgotti). Now that the ACIInfo is removed the image doesn't
// exists anymore, but errors removing non transactional entries can
// leave stale data that will require a cas GC to be implemented.
storeErrors := []error{}
for _, s := range ds.stores {
if err := s.Erase(key); err != nil {
// If there's an error save it and continue with the other stores
storeErrors = append(storeErrors, err)
}
}
if len(storeErrors) > 0 {
return &StoreRemovalError{errors: storeErrors}
}
return nil
}
示例10: WriteACI
// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if
// necessary, and then stores it in the store under a key based on the image ID
// (i.e. the hash of the uncompressed ACI)
// latest defines if the aci has to be marked as the latest. For example an ACI
// discovered without asking for a specific version (latest pattern).
func (s Store) WriteACI(r io.ReadSeeker, latest bool) (string, error) {
dr, err := aci.NewCompressedReader(r)
if err != nil {
return "", fmt.Errorf("error decompressing image: %v", err)
}
// Write the decompressed image (tar) to a temporary file on disk, and
// tee so we can generate the hash
h := sha512.New()
tr := io.TeeReader(dr, h)
fh, err := s.TmpFile()
if err != nil {
return "", fmt.Errorf("error creating image: %v", err)
}
if _, err := io.Copy(fh, tr); err != nil {
return "", fmt.Errorf("error copying image: %v", err)
}
im, err := aci.ManifestFromImage(fh)
if err != nil {
return "", fmt.Errorf("error extracting image manifest: %v", err)
}
if err := fh.Close(); err != nil {
return "", fmt.Errorf("error closing image: %v", err)
}
// Import the uncompressed image into the store at the real key
key := s.HashToKey(h)
keyLock, err := lock.ExclusiveKeyLock(s.imageLockDir, key)
if err != nil {
return "", fmt.Errorf("error locking image: %v", err)
}
defer keyLock.Close()
if err = s.stores[blobType].Import(fh.Name(), key, true); err != nil {
return "", fmt.Errorf("error importing image: %v", err)
}
// Save the imagemanifest using the same key used for the image
imj, err := json.Marshal(im)
if err != nil {
return "", fmt.Errorf("error marshalling image manifest: %v", err)
}
if err = s.stores[imageManifestType].Write(key, imj); err != nil {
return "", fmt.Errorf("error importing image manifest: %v", err)
}
// Save aciinfo
if err = s.db.Do(func(tx *sql.Tx) error {
aciinfo := &ACIInfo{
BlobKey: key,
AppName: im.Name.String(),
ImportTime: time.Now(),
Latest: latest,
}
return WriteACIInfo(tx, aciinfo)
}); err != nil {
return "", fmt.Errorf("error writing ACI Info: %v", err)
}
// The treestore for this ACI is not written here as ACIs downloaded as
// dependencies of another ACI will be exploded also if never directly used.
// Users of treestore should call s.RenderTreeStore before using it.
return key, nil
}
示例11: WriteACI
// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if
// necessary, and then stores it in the store under a key based on the image ID
// (i.e. the hash of the uncompressed ACI)
// latest defines if the aci has to be marked as the latest. For example an ACI
// discovered without asking for a specific version (latest pattern).
func (s Store) WriteACI(r io.Reader, latest bool) (string, error) {
// Peek at the first 512 bytes of the reader to detect filetype
br := bufio.NewReaderSize(r, 32768)
hd, err := br.Peek(512)
switch err {
case nil:
case io.EOF: // We may have still peeked enough to guess some types, so fall through
default:
return "", fmt.Errorf("error reading image header: %v", err)
}
typ, err := aci.DetectFileType(bytes.NewBuffer(hd))
if err != nil {
return "", fmt.Errorf("error detecting image type: %v", err)
}
dr, err := decompress(br, typ)
if err != nil {
return "", fmt.Errorf("error decompressing image: %v", err)
}
// Write the decompressed image (tar) to a temporary file on disk, and
// tee so we can generate the hash
h := sha512.New()
tr := io.TeeReader(dr, h)
fh, err := s.TmpFile()
if err != nil {
return "", fmt.Errorf("error creating image: %v", err)
}
if _, err := io.Copy(fh, tr); err != nil {
return "", fmt.Errorf("error copying image: %v", err)
}
im, err := aci.ManifestFromImage(fh)
if err != nil {
return "", fmt.Errorf("error extracting image manifest: %v", err)
}
if err := fh.Close(); err != nil {
return "", fmt.Errorf("error closing image: %v", err)
}
// Import the uncompressed image into the store at the real key
key := s.HashToKey(h)
keyLock, err := lock.ExclusiveKeyLock(s.imageLockDir, key)
if err != nil {
return "", fmt.Errorf("error locking image: %v", err)
}
defer keyLock.Close()
if err = s.stores[blobType].Import(fh.Name(), key, true); err != nil {
return "", fmt.Errorf("error importing image: %v", err)
}
// Save the imagemanifest using the same key used for the image
imj, err := json.Marshal(im)
if err != nil {
return "", fmt.Errorf("error marshalling image manifest: %v", err)
}
if err = s.stores[imageManifestType].Write(key, imj); err != nil {
return "", fmt.Errorf("error importing image manifest: %v", err)
}
// Save aciinfo
if err = s.db.Do(func(tx *sql.Tx) error {
aciinfo := &ACIInfo{
BlobKey: key,
AppName: im.Name.String(),
ImportTime: time.Now(),
Latest: latest,
}
return WriteACIInfo(tx, aciinfo)
}); err != nil {
return "", fmt.Errorf("error writing ACI Info: %v", err)
}
// The treestore for this ACI is not written here as ACIs downloaded as
// dependencies of another ACI will be exploded also if never directly used.
// Users of treestore should call s.RenderTreeStore before using it.
return key, nil
}
示例12: WriteACI
// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if
// necessary, and then stores it in the store under a key based on the image ID
// (i.e. the hash of the uncompressed ACI)
// latest defines if the aci has to be marked as the latest. For example an ACI
// discovered without asking for a specific version (latest pattern).
func (s *Store) WriteACI(r io.ReadSeeker, fetchInfo ACIFetchInfo) (string, error) {
// We need to allow the store's setgid bits (if any) to propagate, so
// disable umask
um := syscall.Umask(0)
defer syscall.Umask(um)
dr, err := aci.NewCompressedReader(r)
if err != nil {
return "", errwrap.Wrap(errors.New("error decompressing image"), err)
}
defer dr.Close()
// Write the decompressed image (tar) to a temporary file on disk, and
// tee so we can generate the hash
h := sha512.New()
tr := io.TeeReader(dr, h)
fh, err := s.TmpFile()
if err != nil {
return "", errwrap.Wrap(errors.New("error creating image"), err)
}
sz, err := io.Copy(fh, tr)
if err != nil {
return "", errwrap.Wrap(errors.New("error copying image"), err)
}
im, err := aci.ManifestFromImage(fh)
if err != nil {
return "", errwrap.Wrap(errors.New("error extracting image manifest"), err)
}
if err := fh.Close(); err != nil {
return "", errwrap.Wrap(errors.New("error closing image"), err)
}
// Import the uncompressed image into the store at the real key
key := s.HashToKey(h)
keyLock, err := lock.ExclusiveKeyLock(s.imageLockDir, key)
if err != nil {
return "", errwrap.Wrap(errors.New("error locking image"), err)
}
defer keyLock.Close()
if err = s.stores[blobType].Import(fh.Name(), key, true); err != nil {
return "", errwrap.Wrap(errors.New("error importing image"), err)
}
// Save the imagemanifest using the same key used for the image
imj, err := json.Marshal(im)
if err != nil {
return "", errwrap.Wrap(errors.New("error marshalling image manifest"), err)
}
if err := s.stores[imageManifestType].Write(key, imj); err != nil {
return "", errwrap.Wrap(errors.New("error importing image manifest"), err)
}
// Save aciinfo
if err = s.db.Do(func(tx *sql.Tx) error {
aciinfo := &ACIInfo{
BlobKey: key,
Name: im.Name.String(),
ImportTime: time.Now(),
LastUsed: time.Now(),
Latest: fetchInfo.Latest,
Size: sz,
}
return WriteACIInfo(tx, aciinfo)
}); err != nil {
return "", errwrap.Wrap(errors.New("error writing ACI Info"), err)
}
return key, nil
}
示例13: RemoveACI
// RemoveACI removes the ACI with the given key. It firstly removes the aci
// infos inside the db, then it tries to remove the non transactional data.
// If some error occurs removing some non transactional data a
// StoreRemovalError is returned.
func (ds Store) RemoveACI(key string) error {
imageKeyLock, err := lock.ExclusiveKeyLock(ds.imageLockDir, key)
if err != nil {
return fmt.Errorf("error locking image: %v", err)
}
defer imageKeyLock.Close()
// Try to see if we are the owner of the images, if not, returns not enough permission error.
for _, s := range ds.stores {
// XXX: The construction of 'path' depends on the implementation of diskv.
path := filepath.Join(s.BasePath, filepath.Join(s.Transform(key)...))
fi, err := os.Stat(path)
if err != nil {
return fmt.Errorf("cannot get the stat of the image directory: %v", err)
}
uid := os.Getuid()
dirUid := int(fi.Sys().(*syscall.Stat_t).Uid)
if uid != dirUid && uid != 0 {
return fmt.Errorf("permission denied, are you root or the owner of the image?")
}
}
// Firstly remove aciinfo and remote from the db in an unique transaction.
// remote needs to be removed or a GetRemote will return a blobKey not
// referenced by any ACIInfo.
err = ds.db.Do(func(tx *sql.Tx) error {
if _, found, err := GetACIInfoWithBlobKey(tx, key); err != nil {
return fmt.Errorf("error getting aciinfo: %v", err)
} else if !found {
return fmt.Errorf("cannot find image with key: %s", key)
}
if err := RemoveACIInfo(tx, key); err != nil {
return err
}
if err := RemoveRemote(tx, key); err != nil {
return err
}
return nil
})
if err != nil {
return fmt.Errorf("cannot remove image with ID: %s from db: %v", key, err)
}
// Then remove non transactional entries from the blob, imageManifest
// and tree store.
// TODO(sgotti). Now that the ACIInfo is removed the image doesn't
// exists anymore, but errors removing non transactional entries can
// leave stale data that will require a cas GC to be implemented.
storeErrors := []error{}
for _, s := range ds.stores {
if err := s.Erase(key); err != nil {
// If there's an error save it and continue with the other stores
storeErrors = append(storeErrors, err)
}
}
if len(storeErrors) > 0 {
return &StoreRemovalError{errors: storeErrors}
}
return nil
}