private static async Task ExpandCluster(ExpandClusterOptions options) { logger.LogDebug($"Expanding cluster from {options.OldConfigPath} to {options.NewConfigPath}"); var oldConfig = await ClusterConfiguration.FromYamlFile(options.OldConfigPath); var newConfig = await ClusterConfiguration.FromYamlFile(options.NewConfigPath); foreach (var vdisk in newConfig.VDisks) { using var _ = logger.BeginScope("VDisk {vdiskId}", vdisk.Id); logger.LogDebug("Analyzing vdisk from new config"); var oldVdisk = oldConfig.VDisks.Find(vd => vd.Id == vdisk.Id); if (oldVdisk != null && oldVdisk.Replicas.Count > 0) { foreach (var replica in vdisk.Replicas) { using var __ = logger.BeginScope("Replica = {replicaNode}-{replicaDisk}", replica.Node, replica.Disk); logger.LogDebug("Analyzing replica from new config"); var node = newConfig.Nodes.Find(n => n.Name == replica.Node); var disk = node.Disks.Find(d => d.Name == replica.Disk); using var ___ = logger.BeginScope("Path = {replicaPath}", disk.Path); var oldReplica = oldVdisk.Replicas.Find(r => r.Node == replica.Node && r.Disk == replica.Disk); if (oldReplica != null) { logger.LogDebug("Found replica in old config"); } else { logger.LogWarning("Replica not found in old config, restoring data..."); foreach (var selectedReplica in oldVdisk.Replicas) { var oldNode = oldConfig.Nodes.Find(n => n.Name == selectedReplica.Node); var oldDisk = oldNode.Disks.Find(d => d.Name == selectedReplica.Disk); if (CopyReplica(vdisk, replica, selectedReplica, oldDisk.Path, disk.Path, options)) { break; } else { logger.LogWarning($"Failed to copy from replica on node {selectedReplica.Node}"); } } } } } else { logger.LogDebug($"Vdisk's replicas not found in old config"); } } if (options.RemoveSourceFiles) { foreach (var vDisk in oldConfig.VDisks) { using var _ = logger.BeginScope("VDisk {vdiskId}", vDisk.Id); foreach (var replica in vDisk.Replicas.Where(r => !newConfig.VDisks.Any(vd => vd.Replicas.Any(r1 => r.Disk == r1.Disk && r.Node == r1.Node)))) { using var __ = logger.BeginScope("Replica = {replicaNode}-{replicaDisk}", replica.Node, replica.Disk); var node = oldConfig.Nodes.Find(n => n.Name == replica.Node); var disk = node.Disks.Find(d => d.Name == replica.Disk); RemoveReplica(replica, vDisk, disk.Path, options); } } } }