Skip to content

Commit

Permalink
feat(backup): extends manifest with info needed for 1-to-1 restore.
Browse files Browse the repository at this point in the history
This adds following data to the backup manifest:
General:
  cluster_id: uuid of the cluster
  dc: data center name
  rack: rack from the scylla configuration
  node_id: id of the scylla node (equals to host id)
  task_id: uuid of the backup task
  snapshot_tag: snapshot tag
Instance Details:
  shard_count: number of shard in scylla node
  storage_size: total size of the disk in bytes
  cloud_provider: aws|gcp|azure or empty in case of on-premise
  instance_type: instance type, e.g. t2.nano or empty when on-premise

Fixes: #4130
  • Loading branch information
VAveryanov8 committed Jan 3, 2025
1 parent 982383a commit f34d1dd
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
29 changes: 23 additions & 6 deletions pkg/service/backup/backupspec/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,29 @@ func (m *ManifestInfo) fileNameParser(v string) error {

// ManifestContent is structure containing information about the backup.
type ManifestContent struct {
Version string `json:"version"`
ClusterName string `json:"cluster_name"`
IP string `json:"ip"`
Size int64 `json:"size"`
Tokens []int64 `json:"tokens"`
Schema string `json:"schema"`
Version string `json:"version"`
ClusterID uuid.UUID `json:"cluster_id"`
ClusterName string `json:"cluster_name"`
NodeID string `json:"node_id"`
DC string `json:"dc"`
TaskID uuid.UUID `json:"task_id"`
SnapshotTag string `json:"snapshot_tag"`
IP string `json:"ip"`
Size int64 `json:"size"`
Tokens []int64 `json:"tokens"`
Schema string `json:"schema"`
Rack string `json:"rack"`
InstanceDetails InstanceDetails `json:"instance_details"`
}

// InstanceDetails extends backup manifest with additional instance details.
// Mainly needed for 1-to-1 restore.
type InstanceDetails struct {
CloudProvider string `json:"cloud_provider,omitempty"`
InstanceType string `json:"instance_type,omitempty"`

ShardCount int `json:"shard_count"`
StorageSize uint64 `json:"storage_size"`
}

// ManifestContentWithIndex is structure containing information about the backup
Expand Down
50 changes: 48 additions & 2 deletions pkg/service/backup/worker_manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,14 @@ func (w *worker) createAndUploadHostManifest(ctx context.Context, h hostInfo) er
return err
}

m := w.createTemporaryManifest(h, tokens)
m, err := w.createTemporaryManifest(ctx, h, tokens)
if err != nil {
return errors.Wrap(err, "create temp manifest")
}
return w.uploadHostManifest(ctx, h, m)
}

func (w *worker) createTemporaryManifest(h hostInfo, tokens []int64) ManifestInfoWithContent {
func (w *worker) createTemporaryManifest(ctx context.Context, h hostInfo, tokens []int64) (ManifestInfoWithContent, error) {
m := &ManifestInfo{
Location: h.Location,
DC: h.DC,
Expand All @@ -66,6 +69,11 @@ func (w *worker) createTemporaryManifest(h hostInfo, tokens []int64) ManifestInf
ManifestContent: ManifestContent{
Version: "v2",
ClusterName: w.ClusterName,
ClusterID: w.ClusterID,
NodeID: h.ID,
DC: h.DC,
SnapshotTag: w.SnapshotTag,
TaskID: w.TaskID,
IP: h.IP,
Tokens: tokens,
},
Expand All @@ -88,10 +96,48 @@ func (w *worker) createTemporaryManifest(h hostInfo, tokens []int64) ManifestInf
c.Size += d.Progress.Size
}

rack, err := w.Client.HostRack(ctx, h.IP)
if err != nil {
return ManifestInfoWithContent{}, errors.Wrap(err, "client.HostRack")
}
c.Rack = rack

instanceDetails, err := w.manifestInstanceDetails(ctx, h)
if err != nil {
return ManifestInfoWithContent{}, errors.Wrap(err, "manifest instance details")
}
c.InstanceDetails = instanceDetails

return ManifestInfoWithContent{
ManifestInfo: m,
ManifestContentWithIndex: c,
}, nil
}

// manifestInstanceDetails collects node/instance specific information that's needed for 1-to-1 restore.
func (w *worker) manifestInstanceDetails(ctx context.Context, host hostInfo) (InstanceDetails, error) {
var result InstanceDetails

shardCound, err := w.Client.ShardCount(ctx, host.IP)
if err != nil {
return InstanceDetails{}, errors.Wrap(err, "client.ShardCount")
}
result.ShardCount = int(shardCound)

nodeInfo, err := w.Client.NodeInfo(ctx, host.IP)
if err != nil {
return InstanceDetails{}, errors.Wrap(err, "client.NodeInfo")
}
result.StorageSize = nodeInfo.StorageSize

instanceMeta, err := w.Client.CloudMetadata(ctx, host.IP)
if err != nil {
return InstanceDetails{}, errors.Wrap(err, "client.CloudMetadata")
}
result.CloudProvider = instanceMeta.CloudProvider
result.InstanceType = instanceMeta.InstanceType

return result, nil
}

func (w *worker) uploadHostManifest(ctx context.Context, h hostInfo, m ManifestInfoWithContent) error {
Expand Down

0 comments on commit f34d1dd

Please sign in to comment.