func()

in lib/torrent/storage/agentstorage/torrent_archive.go [74:109]


func (a *TorrentArchive) CreateTorrent(namespace string, d core.Digest) (storage.Torrent, error) {
	var tm metadata.TorrentMeta
	if err := a.cads.Any().GetMetadata(d.Hex(), &tm); os.IsNotExist(err) {
		downloadTimer := a.stats.Timer("metainfo_download").Start()
		mi, err := a.metaInfoClient.Download(namespace, d)
		if err != nil {
			if err == metainfoclient.ErrNotFound {
				return nil, storage.ErrNotFound
			}
			return nil, fmt.Errorf("download metainfo: %s", err)
		}
		downloadTimer.Stop()

		// There's a race condition here, but it's "okay"... Basically, we could
		// initialize a download file with metainfo that is rejected by file store,
		// because someone else beats us to it. However, we catch a lucky break
		// because the only piece of metainfo we use is file length -- which digest
		// is derived from, so it's "okay".
		createErr := a.cads.CreateDownloadFile(mi.Digest().Hex(), mi.Length())
		if createErr != nil &&
			!(a.cads.InDownloadError(createErr) || a.cads.InCacheError(createErr)) {
			return nil, fmt.Errorf("create download file: %s", createErr)
		}
		tm.MetaInfo = mi
		if err := a.cads.Any().GetOrSetMetadata(d.Hex(), &tm); err != nil {
			return nil, fmt.Errorf("get or set metainfo: %s", err)
		}
	} else if err != nil {
		return nil, fmt.Errorf("get metainfo: %s", err)
	}
	t, err := NewTorrent(a.cads, tm.MetaInfo)
	if err != nil {
		return nil, fmt.Errorf("initialize torrent: %s", err)
	}
	return t, nil
}