github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/storage/interface.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package storage 5 6 import ( 7 "github.com/juju/names/v5" 8 9 "github.com/juju/juju/core/instance" 10 "github.com/juju/juju/environs/context" 11 ) 12 13 // ProviderType uniquely identifies a storage provider, such as "ebs" or "loop". 14 type ProviderType string 15 16 // Scope defines the scope of the storage that a provider manages. 17 // Machine-scoped storage must be managed from within the machine, 18 // whereas environment-level storage must be managed by an environment 19 // storage provisioner. 20 type Scope int 21 22 const ( 23 ScopeEnviron Scope = iota 24 ScopeMachine 25 ) 26 27 // ProviderRegistry is an interface for obtaining storage providers. 28 type ProviderRegistry interface { 29 // StorageProviderTypes returns the storage provider types 30 // contained within this registry. 31 // 32 // Determining the supported storage providers may be dynamic. 33 // Multiple calls for the same registry must return consistent 34 // results. 35 StorageProviderTypes() ([]ProviderType, error) 36 37 // StorageProvider returns the storage provider with the given 38 // provider type. StorageProvider must return an errors satisfying 39 // errors.IsNotFound if the registry does not contain the 40 // specified provider type. 41 StorageProvider(ProviderType) (Provider, error) 42 } 43 44 // Provider is an interface for obtaining storage sources. 45 type Provider interface { 46 // VolumeSource returns a VolumeSource given the specified storage 47 // provider configurations, or an error if the provider does not 48 // support creating volumes or the configuration is invalid. 49 // 50 // If the storage provider does not support creating volumes as a 51 // first-class primitive, then VolumeSource must return an error 52 // satisfying errors.IsNotSupported. 53 VolumeSource(*Config) (VolumeSource, error) 54 55 // FilesystemSource returns a FilesystemSource given the specified 56 // storage provider configurations, or an error if the provider does 57 // not support creating filesystems or the configuration is invalid. 58 FilesystemSource(*Config) (FilesystemSource, error) 59 60 // Supports reports whether or not the storage provider supports 61 // the specified storage kind. 62 // 63 // A provider that supports volumes but not filesystems can still 64 // be used for creating filesystem storage; Juju will request a 65 // volume from the provider and then manage the filesystem itself. 66 Supports(kind StorageKind) bool 67 68 // Scope returns the scope of storage managed by this provider. 69 Scope() Scope 70 71 // Dynamic reports whether or not the storage provider is capable 72 // of dynamic storage provisioning. Non-dynamic storage must be 73 // created at the time a machine is provisioned. 74 Dynamic() bool 75 76 // Releasable reports whether or not the storage provider is capable 77 // of releasing dynamic storage, with either ReleaseVolumes or 78 // ReleaseFilesystems. 79 Releasable() bool 80 81 // DefaultPools returns the default storage pools for this provider, 82 // to register in each new model. 83 DefaultPools() []*Config 84 85 // ValidateConfig validates the provided storage provider config, 86 // returning an error if it is invalid. 87 ValidateConfig(*Config) error 88 89 // ValidateForK8s validates if a storage provider can be set for 90 // a given K8s configuration. 91 ValidateForK8s(map[string]any) error 92 } 93 94 // VolumeSource provides an interface for creating, destroying, describing, 95 // attaching and detaching volumes in the environment. A VolumeSource is 96 // configured in a particular way, and corresponds to a storage "pool". 97 type VolumeSource interface { 98 // CreateVolumes creates volumes with the specified parameters. If the 99 // volumes are initially attached, then CreateVolumes returns 100 // information about those attachments too. 101 CreateVolumes(ctx context.ProviderCallContext, params []VolumeParams) ([]CreateVolumesResult, error) 102 103 // ListVolumes lists the provider volume IDs for every volume 104 // created by this volume source. 105 ListVolumes(ctx context.ProviderCallContext) ([]string, error) 106 107 // DescribeVolumes returns the properties of the volumes with the 108 // specified provider volume IDs. 109 DescribeVolumes(ctx context.ProviderCallContext, volIds []string) ([]DescribeVolumesResult, error) 110 111 // DestroyVolumes destroys the volumes with the specified provider 112 // volume IDs. 113 DestroyVolumes(ctx context.ProviderCallContext, volIds []string) ([]error, error) 114 115 // ReleaseVolumes releases the volumes with the specified provider 116 // volume IDs from the model/controller. 117 ReleaseVolumes(ctx context.ProviderCallContext, volIds []string) ([]error, error) 118 119 // ValidateVolumeParams validates the provided volume creation 120 // parameters, returning an error if they are invalid. 121 ValidateVolumeParams(params VolumeParams) error 122 123 // AttachVolumes attaches volumes to machines. 124 // 125 // AttachVolumes must be idempotent; it may be called even if the 126 // attachment already exists, to ensure that it exists, e.g. over 127 // machine restarts. 128 // 129 // TODO(axw) we need to validate attachment requests prior to 130 // recording in state. For example, the ec2 provider must reject 131 // an attempt to attach a volume to an instance if they are in 132 // different availability zones. 133 AttachVolumes(ctx context.ProviderCallContext, params []VolumeAttachmentParams) ([]AttachVolumesResult, error) 134 135 // DetachVolumes detaches the volumes with the specified provider 136 // volume IDs from the instances with the corresponding index. 137 // 138 // TODO(axw) we need to record in state whether or not volumes 139 // are detachable, and reject attempts to attach/detach on 140 // that basis. 141 DetachVolumes(ctx context.ProviderCallContext, params []VolumeAttachmentParams) ([]error, error) 142 } 143 144 // FilesystemSource provides an interface for creating, destroying and 145 // describing filesystems in the environment. A FilesystemSource is 146 // configured in a particular way, and corresponds to a storage "pool". 147 type FilesystemSource interface { 148 // ValidateFilesystemParams validates the provided filesystem creation 149 // parameters, returning an error if they are invalid. 150 ValidateFilesystemParams(params FilesystemParams) error 151 152 // CreateFilesystems creates filesystems with the specified size, in MiB. 153 CreateFilesystems(ctx context.ProviderCallContext, params []FilesystemParams) ([]CreateFilesystemsResult, error) 154 155 // DestroyFilesystems destroys the filesystems with the specified 156 // providerd filesystem IDs. 157 DestroyFilesystems(ctx context.ProviderCallContext, fsIds []string) ([]error, error) 158 159 // ReleaseFilesystems releases the filesystems with the specified provider 160 // filesystem IDs from the model/controller. 161 ReleaseFilesystems(ctx context.ProviderCallContext, volIds []string) ([]error, error) 162 163 // AttachFilesystems attaches filesystems to machines. 164 // 165 // AttachFilesystems must be idempotent; it may be called even if 166 // the attachment already exists, to ensure that it exists, e.g. over 167 // machine restarts. 168 // 169 // TODO(axw) we need to validate attachment requests prior to 170 // recording in state. For example, the ec2 provider must reject 171 // an attempt to attach a volume to an instance if they are in 172 // different availability zones. 173 AttachFilesystems(ctx context.ProviderCallContext, params []FilesystemAttachmentParams) ([]AttachFilesystemsResult, error) 174 175 // DetachFilesystems detaches the filesystems with the specified 176 // provider filesystem IDs from the instances with the corresponding 177 // index. 178 DetachFilesystems(ctx context.ProviderCallContext, params []FilesystemAttachmentParams) ([]error, error) 179 } 180 181 // FilesystemImporter provides an interface for importing filesystems 182 // into the controller/model. 183 // 184 // TODO(axw) make this part of FilesystemSource? 185 type FilesystemImporter interface { 186 // ImportFilesystem updates the filesystem with the specified 187 // filesystem provider ID with the given resource tags, so that 188 // it is seen as being managed by this Juju controller/model. 189 // ImportFilesystem returns the filesystem information to store 190 // in the model. 191 // 192 // Implementations of ImportFilesystem should validate that the 193 // filesystem is not in use before allowing the import to proceed. 194 // Once it is imported, it is assumed to be in a detached state. 195 ImportFilesystem( 196 ctx context.ProviderCallContext, 197 filesystemId string, 198 resourceTags map[string]string, 199 ) (FilesystemInfo, error) 200 } 201 202 // VolumeImporter provides an interface for importing volumes 203 // into the controller/model. 204 // 205 // TODO(axw) make this part of VolumeSource? 206 type VolumeImporter interface { 207 // ImportVolume updates the volume with the specified volume 208 // provider ID with the given resource tags, so that it is 209 // seen as being managed by this Juju controller/model. 210 // ImportVolume returns the volume information to store 211 // in the model. 212 // 213 // Implementations of ImportVolume should validate that the 214 // volume is not in use before allowing the import to proceed. 215 // Once it is imported, it is assumed to be in a detached state. 216 ImportVolume( 217 ctx context.ProviderCallContext, 218 volumeId string, 219 resourceTags map[string]string, 220 ) (VolumeInfo, error) 221 } 222 223 // VolumeParams is a fully specified set of parameters for volume creation, 224 // derived from one or more of user-specified storage constraints, a 225 // storage pool definition, and charm storage metadata. 226 type VolumeParams struct { 227 // Tag is a unique tag name assigned by Juju for the requested volume. 228 Tag names.VolumeTag 229 230 // Size is the minimum size of the volume in MiB. 231 Size uint64 232 233 // Provider is the name of the storage provider that is to be used to 234 // create the volume. 235 Provider ProviderType 236 237 // Attributes is the set of provider-specific attributes to pass to 238 // the storage provider when creating the volume. Attributes is derived 239 // from the storage pool configuration. 240 Attributes map[string]interface{} 241 242 // ResourceTags is a set of tags to set on the created volume, if the 243 // storage provider supports tags. 244 ResourceTags map[string]string 245 246 // Attachment identifies the machine that the volume should be attached 247 // to initially, or nil if the volume should not be attached to any 248 // machine. Some providers, such as MAAS, do not support dynamic 249 // attachment, and so provisioning time is the only opportunity to 250 // perform attachment. 251 // 252 // When machine instances are created, the instance provider will be 253 // presented with parameters for any due-to-be-attached volumes. If 254 // once the instance is created there are still unprovisioned volumes, 255 // the dynamic storage provisioner will take care of creating them. 256 Attachment *VolumeAttachmentParams 257 } 258 259 // VolumeAttachmentParams is a set of parameters for volume attachment or 260 // detachment. 261 type VolumeAttachmentParams struct { 262 AttachmentParams 263 264 // Volume is a unique tag assigned by Juju for the volume that 265 // should be attached/detached. 266 Volume names.VolumeTag 267 268 // VolumeId is the unique provider-supplied ID for the volume that 269 // should be attached/detached. 270 VolumeId string 271 } 272 273 // AttachmentParams describes the parameters for attaching a volume or 274 // filesystem to a machine. 275 type AttachmentParams struct { 276 // Provider is the name of the storage provider that is to be used to 277 // create the attachment. 278 Provider ProviderType 279 280 // Machine is the tag of the Juju machine that the storage should be 281 // attached to. Storage providers may use this to perform machine- 282 // specific operations, such as configuring access controls for the 283 // machine. 284 // This is a generic tag as it's also used to hold a unit for caas storage. 285 // TODO(caas)-rename to Host 286 Machine names.Tag 287 288 // InstanceId is the ID of the cloud instance that the storage should 289 // be attached to. This will only be of interest to storage providers 290 // that interact with the instances, such as EBS/EC2. The InstanceId 291 // field will be empty if the instance is not yet provisioned. 292 InstanceId instance.Id 293 294 // ReadOnly indicates that the storage should be attached as read-only. 295 ReadOnly bool 296 } 297 298 // FilesystemParams is a fully specified set of parameters for filesystem creation, 299 // derived from one or more of user-specified storage constraints, a 300 // storage pool definition, and charm storage metadata. 301 type FilesystemParams struct { 302 // Tag is a unique tag assigned by Juju for the requested filesystem. 303 Tag names.FilesystemTag 304 305 // Volume is the tag of the volume that backs the filesystem, if any. 306 Volume names.VolumeTag 307 308 // Size is the minimum size of the filesystem in MiB. 309 Size uint64 310 311 // The provider type for this filesystem. 312 Provider ProviderType 313 314 // Attributes is a set of provider-specific options for storage creation, 315 // as defined in a storage pool. 316 Attributes map[string]interface{} 317 318 // ResourceTags is a set of tags to set on the created filesystem, if the 319 // storage provider supports tags. 320 ResourceTags map[string]string 321 322 // Attachment identifies the machine that the filesystem should be attached 323 // to initially, or nil if the filesystem should not be attached to any 324 // machine. 325 Attachment *FilesystemAttachmentParams 326 } 327 328 // FilesystemAttachmentParams is a set of parameters for filesystem attachment 329 // or detachment. 330 type FilesystemAttachmentParams struct { 331 AttachmentParams 332 333 // Filesystem is a unique tag assigned by Juju for the filesystem that 334 // should be attached/detached. 335 Filesystem names.FilesystemTag 336 337 // FilesystemId is the unique provider-supplied ID for the filesystem that 338 // should be attached/detached. 339 FilesystemId string 340 341 // Path is the path at which the filesystem is to be mounted on the machine that 342 // this attachment corresponds to. 343 Path string 344 } 345 346 // CreateVolumesResult contains the result of a VolumeSource.CreateVolumes call 347 // for one volume. Volume and VolumeAttachment should only be used if Error is 348 // nil. 349 type CreateVolumesResult struct { 350 Volume *Volume 351 VolumeAttachment *VolumeAttachment 352 Error error 353 } 354 355 // DescribeVolumesResult contains the result of a VolumeSource.DescribeVolumes call 356 // for one volume. Volume should only be used if Error is nil. 357 type DescribeVolumesResult struct { 358 VolumeInfo *VolumeInfo 359 Error error 360 } 361 362 // AttachVolumesResult contains the result of a VolumeSource.AttachVolumes call 363 // for one volume. VolumeAttachment should only be used if Error is nil. 364 type AttachVolumesResult struct { 365 VolumeAttachment *VolumeAttachment 366 Error error 367 } 368 369 // CreateFilesystemsResult contains the result of a FilesystemSource.CreateFilesystems call 370 // for one filesystem. Filesystem should only be used if Error is nil. 371 type CreateFilesystemsResult struct { 372 Filesystem *Filesystem 373 Error error 374 } 375 376 // AttachFilesystemsResult contains the result of a FilesystemSource.AttachFilesystems call 377 // for one filesystem. FilesystemAttachment should only be used if Error is nil. 378 type AttachFilesystemsResult struct { 379 FilesystemAttachment *FilesystemAttachment 380 Error error 381 }