1package releasedir 2 3import ( 4 "path/filepath" 5 6 "code.cloudfoundry.org/clock" 7 boshblob "github.com/cloudfoundry/bosh-utils/blobstore" 8 bosherr "github.com/cloudfoundry/bosh-utils/errors" 9 boshlog "github.com/cloudfoundry/bosh-utils/logger" 10 boshsys "github.com/cloudfoundry/bosh-utils/system" 11 boshuuid "github.com/cloudfoundry/bosh-utils/uuid" 12 13 bicrypto "github.com/cloudfoundry/bosh-cli/crypto" 14 boshrel "github.com/cloudfoundry/bosh-cli/release" 15 boshidx "github.com/cloudfoundry/bosh-cli/releasedir/index" 16 boshcrypto "github.com/cloudfoundry/bosh-utils/crypto" 17) 18 19type Provider struct { 20 indexReporter boshidx.Reporter 21 releaseIndexReporter ReleaseIndexReporter 22 blobsReporter BlobsDirReporter 23 releaseProvider boshrel.Provider 24 digestCalculator bicrypto.DigestCalculator 25 26 cmdRunner boshsys.CmdRunner 27 uuidGen boshuuid.Generator 28 timeService clock.Clock 29 fs boshsys.FileSystem 30 logger boshlog.Logger 31 digestCreateAlgorithms []boshcrypto.Algorithm 32} 33 34func NewProvider( 35 indexReporter boshidx.Reporter, 36 releaseIndexReporter ReleaseIndexReporter, 37 blobsReporter BlobsDirReporter, 38 releaseProvider boshrel.Provider, 39 digestCalculator bicrypto.DigestCalculator, 40 cmdRunner boshsys.CmdRunner, 41 uuidGen boshuuid.Generator, 42 timeService clock.Clock, 43 fs boshsys.FileSystem, 44 digestCreateAlgorithms []boshcrypto.Algorithm, 45 logger boshlog.Logger, 46) Provider { 47 return Provider{ 48 indexReporter: indexReporter, 49 releaseIndexReporter: releaseIndexReporter, 50 blobsReporter: blobsReporter, 51 releaseProvider: releaseProvider, 52 digestCalculator: digestCalculator, 53 cmdRunner: cmdRunner, 54 uuidGen: uuidGen, 55 timeService: timeService, 56 fs: fs, 57 digestCreateAlgorithms: digestCreateAlgorithms, 58 logger: logger, 59 } 60} 61 62func (p Provider) NewFSReleaseDir(dirPath string, parallel int) FSReleaseDir { 63 gitRepo := NewFSGitRepo(dirPath, p.cmdRunner, p.fs) 64 blobsDir := p.NewFSBlobsDir(dirPath) 65 generator := NewFSGenerator(dirPath, p.fs) 66 67 devRelsPath := filepath.Join(dirPath, "dev_releases") 68 devReleases := NewFSReleaseIndex("dev", devRelsPath, p.releaseIndexReporter, p.uuidGen, p.fs) 69 70 finalRelsPath := filepath.Join(dirPath, "releases") 71 finalReleases := NewFSReleaseIndex("final", finalRelsPath, p.releaseIndexReporter, p.uuidGen, p.fs) 72 73 indiciesProvider := boshidx.NewProvider(p.indexReporter, p.newBlobstore(dirPath), p.fs) 74 _, finalIndex := indiciesProvider.DevAndFinalIndicies(dirPath) 75 76 releaseReader := p.NewReleaseReader(dirPath, parallel) 77 78 return NewFSReleaseDir( 79 dirPath, 80 p.newConfig(dirPath), 81 gitRepo, 82 blobsDir, 83 generator, 84 devReleases, 85 finalReleases, 86 finalIndex, 87 releaseReader, 88 p.timeService, 89 p.fs, 90 parallel, 91 ) 92} 93 94func (p Provider) NewFSBlobsDir(dirPath string) FSBlobsDir { 95 return NewFSBlobsDir(dirPath, p.blobsReporter, p.newBlobstore(dirPath), p.digestCalculator, p.fs, p.logger) 96} 97 98func (p Provider) NewReleaseReader(dirPath string, parallel int) boshrel.BuiltReader { 99 multiReader := p.releaseProvider.NewMultiReader(dirPath) 100 indiciesProvider := boshidx.NewProvider(p.indexReporter, p.newBlobstore(dirPath), p.fs) 101 devIndex, finalIndex := indiciesProvider.DevAndFinalIndicies(dirPath) 102 return boshrel.NewBuiltReader(multiReader, devIndex, finalIndex, parallel) 103} 104 105func (p Provider) newBlobstore(dirPath string) boshblob.DigestBlobstore { 106 provider, options, err := p.newConfig(dirPath).Blobstore() 107 if err != nil { 108 return NewErrBlobstore(err) 109 } 110 111 var blobstore boshblob.Blobstore 112 113 switch provider { 114 case "local": 115 blobstore = boshblob.NewLocalBlobstore(p.fs, p.uuidGen, options) 116 case "s3": 117 blobstore = NewS3Blobstore(p.fs, p.uuidGen, options) 118 case "gcs": 119 blobstore = NewGCSBlobstore(p.fs, p.uuidGen, options) 120 default: 121 return NewErrBlobstore(bosherr.Error("Expected release blobstore to be configured")) 122 } 123 124 digestBlobstore := boshblob.NewDigestVerifiableBlobstore(blobstore, p.fs, p.digestCreateAlgorithms) 125 digestBlobstore = boshblob.NewRetryableBlobstore(digestBlobstore, 3, p.logger) 126 127 err = digestBlobstore.Validate() 128 if err != nil { 129 return NewErrBlobstore(err) 130 } 131 132 return digestBlobstore 133} 134 135func (p Provider) newConfig(dirPath string) FSConfig { 136 publicPath := filepath.Join(dirPath, "config", "final.yml") 137 privatePath := filepath.Join(dirPath, "config", "private.yml") 138 return NewFSConfig(publicPath, privatePath, p.fs) 139} 140