github.com/Cloud-Foundations/Dominator@v0.3.4/imageserver/scanner/api.go (about) 1 package scanner 2 3 import ( 4 "io" 5 "sync" 6 "time" 7 8 "github.com/Cloud-Foundations/Dominator/lib/hash" 9 "github.com/Cloud-Foundations/Dominator/lib/image" 10 "github.com/Cloud-Foundations/Dominator/lib/lockwatcher" 11 "github.com/Cloud-Foundations/Dominator/lib/log" 12 "github.com/Cloud-Foundations/Dominator/lib/objectserver" 13 "github.com/Cloud-Foundations/Dominator/lib/srpc" 14 proto "github.com/Cloud-Foundations/Dominator/proto/imageserver" 15 ) 16 17 // TODO: the types should probably be moved into a separate package, leaving 18 // behind the scanner code. 19 20 const metadataFile = ".metadata" 21 22 type Config struct { 23 BaseDirectory string 24 LockCheckInterval time.Duration 25 LockLogTimeout time.Duration 26 MaximumExpirationDuration time.Duration // Default: 1 day. 27 MaximumExpirationDurationPrivileged time.Duration // Default: 1 month. 28 ReplicationMaster string 29 } 30 31 type notifiers map[<-chan string]chan<- string 32 type makeDirectoryNotifiers map[<-chan image.Directory]chan<- image.Directory 33 34 type ImageDataBase struct { 35 Config 36 Params 37 lockWatcher *lockwatcher.LockWatcher 38 sync.RWMutex 39 // Protected by main lock. 40 directoryMap map[string]image.DirectoryMetadata 41 imageMap map[string]*image.Image 42 addNotifiers notifiers 43 deleteNotifiers notifiers 44 mkdirNotifiers makeDirectoryNotifiers 45 // Unprotected by main lock. 46 pendingImageLock sync.Mutex 47 objectFetchLock sync.Mutex 48 } 49 50 type Params struct { 51 Logger log.DebugLogger 52 ObjectServer objectserver.FullObjectServer 53 } 54 55 func Load(config Config, params Params) (*ImageDataBase, error) { 56 return loadImageDataBase(config, params) 57 } 58 59 func LoadImageDataBase(baseDir string, objSrv objectserver.FullObjectServer, 60 replicationMaster string, logger log.DebugLogger) (*ImageDataBase, error) { 61 return loadImageDataBase( 62 Config{ 63 BaseDirectory: baseDir, 64 ReplicationMaster: replicationMaster, 65 }, 66 Params{ 67 Logger: logger, 68 ObjectServer: objSrv, 69 }) 70 } 71 72 func (imdb *ImageDataBase) AddImage(img *image.Image, name string, 73 authInfo *srpc.AuthInformation) error { 74 return imdb.addImage(img, name, authInfo) 75 } 76 77 func (imdb *ImageDataBase) ChangeImageExpiration(name string, 78 expiresAt time.Time, authInfo *srpc.AuthInformation) (bool, error) { 79 return imdb.changeImageExpiration(name, expiresAt, authInfo) 80 } 81 82 func (imdb *ImageDataBase) CheckDirectory(name string) bool { 83 return imdb.checkDirectory(name) 84 } 85 86 func (imdb *ImageDataBase) CheckImage(name string) bool { 87 return imdb.checkImage(name) 88 } 89 90 func (imdb *ImageDataBase) ChownDirectory(dirname, ownerGroup string, 91 authInfo *srpc.AuthInformation) error { 92 return imdb.chownDirectory(dirname, ownerGroup, authInfo) 93 } 94 95 func (imdb *ImageDataBase) CountDirectories() uint { 96 return imdb.countDirectories() 97 } 98 99 func (imdb *ImageDataBase) CountImages() uint { 100 return imdb.countImages() 101 } 102 103 func (imdb *ImageDataBase) DeleteImage(name string, 104 authInfo *srpc.AuthInformation) error { 105 return imdb.deleteImage(name, authInfo) 106 } 107 108 // DeleteUnreferencedObjects will delete some or all unreferenced objects. 109 // Objects are randomly selected for deletion, until both the percentage and 110 // bytes thresholds are satisfied. 111 // If an image upload/replication is in process this operation is unsafe as it 112 // may delete objects that the new image will be using. 113 func (imdb *ImageDataBase) DeleteUnreferencedObjects(percentage uint8, 114 bytes uint64) error { 115 _, _, err := imdb.Params.ObjectServer.DeleteUnreferenced(percentage, bytes) 116 return err 117 } 118 119 func (imdb *ImageDataBase) DoWithPendingImage(img *image.Image, 120 doFunc func() error) error { 121 return imdb.doWithPendingImage(img, doFunc) 122 } 123 124 func (imdb *ImageDataBase) FindLatestImage( 125 request proto.FindLatestImageRequest) (string, error) { 126 return imdb.findLatestImage(request) 127 } 128 129 func (imdb *ImageDataBase) GetImage(name string) *image.Image { 130 return imdb.getImage(name) 131 } 132 133 func (imdb *ImageDataBase) GetUnreferencedObjectsStatistics() (uint64, uint64) { 134 return 0, 0 135 } 136 137 func (imdb *ImageDataBase) ListDirectories() []image.Directory { 138 return imdb.listDirectories() 139 } 140 141 func (imdb *ImageDataBase) ListImages() []string { 142 return imdb.listImages(proto.ListSelectedImagesRequest{}) 143 } 144 145 func (imdb *ImageDataBase) ListSelectedImages( 146 request proto.ListSelectedImagesRequest) []string { 147 return imdb.listImages(request) 148 } 149 150 // ListUnreferencedObjects will return a map listing all the objects and their 151 // corresponding sizes which are not referenced by an image. 152 // Note that some objects may have been recently added and the referencing image 153 // may not yet be present (i.e. it may be added after missing objects are 154 // uploaded). 155 func (imdb *ImageDataBase) ListUnreferencedObjects() map[hash.Hash]uint64 { 156 return imdb.Params.ObjectServer.ListUnreferenced() 157 } 158 159 func (imdb *ImageDataBase) MakeDirectory(dirname string, 160 authInfo *srpc.AuthInformation) error { 161 return imdb.makeDirectory(image.Directory{Name: dirname}, authInfo, true) 162 } 163 164 func (imdb *ImageDataBase) ObjectServer() objectserver.ObjectServer { 165 return imdb.Params.ObjectServer 166 } 167 168 func (imdb *ImageDataBase) RegisterAddNotifier() <-chan string { 169 return imdb.registerAddNotifier() 170 } 171 172 func (imdb *ImageDataBase) RegisterDeleteNotifier() <-chan string { 173 return imdb.registerDeleteNotifier() 174 } 175 176 func (imdb *ImageDataBase) RegisterMakeDirectoryNotifier() <-chan image.Directory { 177 return imdb.registerMakeDirectoryNotifier() 178 } 179 180 func (imdb *ImageDataBase) UnregisterAddNotifier(channel <-chan string) { 181 imdb.unregisterAddNotifier(channel) 182 } 183 184 func (imdb *ImageDataBase) UnregisterDeleteNotifier(channel <-chan string) { 185 imdb.unregisterDeleteNotifier(channel) 186 } 187 188 func (imdb *ImageDataBase) UnregisterMakeDirectoryNotifier( 189 channel <-chan image.Directory) { 190 imdb.unregisterMakeDirectoryNotifier(channel) 191 } 192 193 func (imdb *ImageDataBase) UpdateDirectory(directory image.Directory) error { 194 return imdb.makeDirectory(directory, nil, false) 195 } 196 197 func (imdb *ImageDataBase) WriteHtml(writer io.Writer) { 198 imdb.writeHtml(writer) 199 }