@startuml
hide circle
hide empty methods
hide empty fields
namespace juju.charm {
class StorageMetadata {
Name: string
Description : string
Kind : StorageKind
ReadOnly : bool
Shared : bool
Location: string
CountMin : int
CountMax : int
}
enum StorageKind {
block
filesystem
}
Charm "1" *-- "*" StorageMetadata : specifies >
}
namespace juju.juju.state <> {
class Volume {
Id : string
Life : Life
Pool : string
Info : VolumeInfo
Params : VolumeParams
}
class VolumeInfo {
VolumeId : string
Size : int
Detachable : bool
ExtendedAttrs : map[string]interface{}
}
class VolumeParams {
Size : int
}
class VolumeAttachment {
DeviceName : string
}
class Filesystem {
Id : string
Life : Life
Pool : string
Info : FilesystemInfo
Params : FilesystemParams
}
class FilesystemInfo {
FilesystemId : string
Size : int
Detachable : bool
ExtendedAttrs : map[string]interface{}
}
class FilesystemParams {
Size : int
Location : string
}
class FilesystemAttachment {
MountPoint : string
}
class BlockDevice {
DeviceName : string
HardwareId : string
Size : int
FilesystemType : string
}
class StorageConstraints {
StorageName : string
Size : int
Count : int
Pool : StoragePool
}
class StoragePool {
Name : string
StorageProvider : string
Attributes : map[string]string
}
class StorageInstance {
Id : string
Pool : StoragePool
Life : Life
}
class StorageAttachment {
Location : string
}
Machine "1" *-- "*" BlockDevice : > has
Machine "1" *-- "*" VolumeAttachment : has >
Machine "1" *-- "*" FilesystemAttachment : has >
Unit "1" *-- "*" StorageInstance : owns (non-shared) >
Unit "1" *-- "*" StorageAttachment : has
Unit "1" *-- "*" StorageConstraints : records >
application "1" *-- "*" StorageInstance : owns (shared) >
application "1" *-- "*" StorageConstraints : records >
application "1" -- "1" juju.charm.Charm
StorageInstance --* StoragePool
StorageInstance "1" *-- "*" StorageAttachment : has >
Volume "1" *-- "0-1" StorageInstance : assigned >
Volume "1" *-- "*" VolumeAttachment
Volume "1" *-- "*" VolumeParams
Volume "1" *-- "*" VolumeInfo
Filesystem "1" *-- "0-1" StorageInstance : assigned to >
Filesystem "1" *-- "0-1" FilesystemAttachment : assigned to >
Filesystem "1" *-- "0-1" FilesystemParams
Filesystem "1" *-- "0-1" FilesystemInfo
note as N1
Non-shared storage instances
are owned by and managed by a
unit, shared storage instances
are owned by a service and managed
by a unit of that service with
with a lease.
end note
StorageInstance .. N1
note as N2
The machine agent will periodically list
block devices on the machine and publish
them to state. This gives us a mechanism
to determine when a volume is attached
and visible to a machine. Additioally,
users will later be able to create a
Volume from an unused BlockDevice, e.g.
hot-plugged disks in MAAS.
end note
BlockDevice .. N2
note as N3
Volumes and Filesystems will initially
be unprovisioned, and will have Params
documents associated. Once provisioned,
the Params are dropped and replaced with
Info. We don't currently, but may later
periodically update Info with, e.g.
currently available size.
end note
VolumeInfo .. N3
FilesystemInfo .. N3
VolumeParams .. N3
FilesystemParams .. N3
note as N4
StorageInstance represents a possibly
shared store, whereas a StorageAttachment
represents the storage instance's attachment
to a unit. For non-shared stores, there
will be a one-to-one relationship between
StorageInstance and StorageAttachment.
For shared stores, there may be multiple
units attached to a store, potentially with
different locations (e.g. block device paths,
filesystem mount points).
end note
StorageInstance .. N4
StorageAttachment .. N4
note as N5
Volumes and Filesystems may be multi-attachable,
hence we model attachment as well as the entity
itself. Each VolumeAttachment and
FilesystemAttachment may have different
machine-specific properties (e.g. device name,
filesystem mount point).
end note
Volume .. N5
VolumeAttachment .. N5
Filesystem .. N5
FilesystemAttachment .. N5
note as N6
Volumes and Filesystems may be persistent, and
so are not tied to a single storage instance
forever. For example, if we deploy a service
with persistent storage, and later destroy the
unit, we should later be able to reuse that
persistent storage with another unit to revive
the service.
end note
Volume .. N6
Filesystem .. N6
StorageInstance .. N6
}
namespace juju.names {
VolumeTag ..> juju.juju.state.Volume : identifies
FilesystemTag ..> juju.juju.state.Filesystem : identifies
StorageTag ..> juju.juju.state.StorageInstance : identifies
}
@enduml