diff --git a/cluster/etcd.go b/cluster/etcd.go index 5e027335..51b19d03 100644 --- a/cluster/etcd.go +++ b/cluster/etcd.go @@ -3,7 +3,6 @@ package cluster import ( "context" "fmt" - "regexp" "github.com/sirupsen/logrus" @@ -16,10 +15,6 @@ import ( "golang.org/x/sync/errgroup" ) -const ( - BackupPrepareError = "failed to prepare backup: restoring S3 backups with no cluster level S3 configuration is not supported" -) - func (c *Cluster) SnapshotEtcd(ctx context.Context, snapshotName string) error { backupImage := c.getBackupImage() for _, host := range c.EtcdHosts { @@ -62,7 +57,13 @@ func (c *Cluster) PrepareBackup(ctx context.Context, snapshotPath string) error backupImage := c.getBackupImage() var errors []error if c.Services.Etcd.BackupConfig == nil || // legacy rke local backup - (c.Services.Etcd.BackupConfig != nil && IsLocalSnapshot(snapshotPath)) { // rancher local backup and snapshot name indicates a local snapshot + (c.Services.Etcd.BackupConfig != nil && c.Services.Etcd.BackupConfig.S3BackupConfig == nil) { // rancher local backup + if c.Services.Etcd.BackupConfig == nil { + log.Infof(ctx, "[etcd] No etcd snapshot configuration found, will use local as source") + } + if c.Services.Etcd.BackupConfig != nil && c.Services.Etcd.BackupConfig.S3BackupConfig == nil { + log.Infof(ctx, "[etcd] etcd snapshot configuration found and no s3 backup configuration found, will use local as source") + } // stop etcd on all etcd nodes, we need this because we start the backup server on the same port for _, host := range c.EtcdHosts { if err := docker.StopContainer(ctx, host.DClient, host.Address, services.EtcdContainerName); err != nil { @@ -104,7 +105,8 @@ func (c *Cluster) PrepareBackup(ctx context.Context, snapshotPath string) error // s3 backup case if c.Services.Etcd.BackupConfig != nil && - c.Services.Etcd.BackupConfig.S3BackupConfig != nil && !IsLocalSnapshot(snapshotPath) { + c.Services.Etcd.BackupConfig.S3BackupConfig != nil { + log.Infof(ctx, "[etcd] etcd s3 backup configuration found, will use s3 as source") for _, host := range c.EtcdHosts { if err := services.DownloadEtcdSnapshotFromS3(ctx, host, c.PrivateRegistriesMap, backupImage, snapshotPath, c.Services.Etcd); err != nil { return err @@ -113,11 +115,6 @@ func (c *Cluster) PrepareBackup(ctx context.Context, snapshotPath string) error backupReady = true } if !backupReady { - if !IsLocalSnapshot(snapshotPath) && - c.Services.Etcd.BackupConfig != nil && - c.Services.Etcd.BackupConfig.S3BackupConfig == nil { // s3 backup with no s3 configuration! - return fmt.Errorf(BackupPrepareError) - } return fmt.Errorf("failed to prepare backup for restore") } // this applies to all cases! @@ -179,16 +176,6 @@ func (c *Cluster) getBackupImage() string { logrus.Errorf("[etcd] error getting backup image %v", err) return "" } + logrus.Debugf("[etcd] Image used for etcd snapshot is: [%s]", rkeToolsImage) return rkeToolsImage } - -func IsLocalSnapshot(name string) bool { - // name is fmt.Sprintf("%s-%s%s-", cluster.Name, typeFlag, providerFlag) - // typeFlag = "r": recurring - // typeFlag = "m": manaul - // - // providerFlag = "l" local - // providerFlag = "s" s3 - re := regexp.MustCompile("^c-[a-z0-9].*?-.l-") - return re.MatchString(name) -} diff --git a/services/etcd.go b/services/etcd.go index 9ec43bcc..e6492691 100644 --- a/services/etcd.go +++ b/services/etcd.go @@ -378,7 +378,6 @@ func RunEtcdSnapshotSave(ctx context.Context, etcdHost *hosts.Host, prsMap map[s } func DownloadEtcdSnapshotFromS3(ctx context.Context, etcdHost *hosts.Host, prsMap map[string]v3.PrivateRegistry, etcdSnapshotImage string, name string, es v3.ETCDService) error { - log.Infof(ctx, "[etcd] Get snapshot [%s] on host [%s]", name, etcdHost.Address) s3Backend := es.BackupConfig.S3BackupConfig if len(s3Backend.Endpoint) == 0 || len(s3Backend.BucketName) == 0 { return fmt.Errorf("failed to get snapshot [%s] from s3 on host [%s], invalid s3 configurations", name, etcdHost.Address) @@ -399,13 +398,21 @@ func DownloadEtcdSnapshotFromS3(ctx context.Context, etcdHost *hosts.Host, prsMa Image: etcdSnapshotImage, Env: es.ExtraEnv, } + s3Logline := fmt.Sprintf("[etcd] Snapshot [%s] will be downloaded on host [%s] from S3 compatible backend at [%s] from bucket [%s] using accesskey [%s]", name, etcdHost.Address, s3Backend.Endpoint, s3Backend.BucketName, s3Backend.AccessKey) + if s3Backend.Region != "" { + s3Logline += fmt.Sprintf(" and using region [%s]", s3Backend.Region) + } + if s3Backend.CustomCA != "" { caStr := base64.StdEncoding.EncodeToString([]byte(s3Backend.CustomCA)) imageCfg.Cmd = append(imageCfg.Cmd, "--s3-endpoint-ca="+caStr) + s3Logline += fmt.Sprintf(" and using endpoint CA [%s]", caStr) } if s3Backend.Folder != "" { imageCfg.Cmd = append(imageCfg.Cmd, "--s3-folder="+s3Backend.Folder) + s3Logline += fmt.Sprintf(" and using folder [%s]", s3Backend.Folder) } + log.Infof(ctx, s3Logline) hostCfg := &container.HostConfig{ Binds: []string{ fmt.Sprintf("%s:/backup:z", EtcdSnapshotPath), @@ -610,7 +617,10 @@ func configS3BackupImgCmd(ctx context.Context, imageCfg *container.Config, bc *v "--s3-bucketName=" + bc.S3BackupConfig.BucketName, "--s3-region=" + bc.S3BackupConfig.Region, }...) - s3Logline := fmt.Sprintf("[etcd] Snapshot will be uploaded to S3 compatible backend at [%s] in region [%s] to bucket [%s] using accesskey [%s]", bc.S3BackupConfig.Endpoint, bc.S3BackupConfig.Region, bc.S3BackupConfig.BucketName, bc.S3BackupConfig.AccessKey) + s3Logline := fmt.Sprintf("[etcd] Snapshots configured to S3 compatible backend at [%s] to bucket [%s] using accesskey [%s]", bc.S3BackupConfig.Endpoint, bc.S3BackupConfig.BucketName, bc.S3BackupConfig.AccessKey) + if bc.S3BackupConfig.Region != "" { + s3Logline += fmt.Sprintf(" and using region [%s]", bc.S3BackupConfig.Region) + } if bc.S3BackupConfig.CustomCA != "" { caStr := base64.StdEncoding.EncodeToString([]byte(bc.S3BackupConfig.CustomCA)) cmd = append(cmd, "--s3-endpoint-ca="+caStr)