This is an automated email from the ASF dual-hosted git repository.
zhonghongsheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git
The following commit(s) were added to refs/heads/main by this push:
new e2a5864 feat: introduce new pitr subcommand delete (#461)
e2a5864 is described below
commit e2a586401673dccf0e6c6abe1e45627a352ed3d4
Author: liyao <[email protected]>
AuthorDate: Wed Nov 15 17:38:43 2023 +0800
feat: introduce new pitr subcommand delete (#461)
* feat: use common header in DELETE request
* feat: add filename as backup metainfo
* feat: add HideByName and DeleteByHidedName
* feat: add delete backup record
* chore: update local storage mock
* chore: add test for delete
* refactor: change func name delete to deleteRecord
* refactor: optimize _execDelete
* feat: add add delete status
* chore: update delete func name
* chore: add nolint for command definition
* refactor: seperate common func validate
* chore: adjust style according to lint
---
pitr/cli/internal/cmd/common.go | 47 +++++++
pitr/cli/internal/cmd/delete.go | 192 +++++++++++++++++++++++++++
pitr/cli/internal/cmd/delete_test.go | 116 ++++++++++++++++
pitr/cli/internal/cmd/restore.go | 17 +--
pitr/cli/internal/pkg/local-storage.go | 30 ++++-
pitr/cli/internal/pkg/mocks/local-storage.go | 112 +++++++++-------
pitr/cli/internal/pkg/model/ls_backup.go | 1 +
pitr/cli/pkg/httputils/req.go | 10 +-
8 files changed, 456 insertions(+), 69 deletions(-)
diff --git a/pitr/cli/internal/cmd/common.go b/pitr/cli/internal/cmd/common.go
new file mode 100644
index 0000000..0e80d5d
--- /dev/null
+++ b/pitr/cli/internal/cmd/common.go
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cmd
+
+import (
+ "fmt"
+
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/xerr"
+)
+
+func validate(ls pkg.ILocalStorage, csn, recordID string) (*model.LsBackup,
error) {
+ var (
+ bak *model.LsBackup
+ err error
+ )
+ if CSN != "" {
+ bak, err = ls.ReadByCSN(csn)
+ if err != nil {
+ return bak, xerr.NewCliErr(fmt.Sprintf("read backup
record by csn failed. err: %s", err))
+ }
+ }
+
+ if RecordID != "" {
+ bak, err = ls.ReadByID(recordID)
+ if err != nil {
+ return bak, xerr.NewCliErr(fmt.Sprintf("read backup
record by id failed. err: %s", err))
+ }
+ }
+ return bak, nil
+}
diff --git a/pitr/cli/internal/cmd/delete.go b/pitr/cli/internal/cmd/delete.go
new file mode 100644
index 0000000..6107097
--- /dev/null
+++ b/pitr/cli/internal/cmd/delete.go
@@ -0,0 +1,192 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cmd
+
+import (
+ "fmt"
+ "os"
+ "time"
+
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/xerr"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/pkg/logging"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/pkg/prettyoutput"
+ "github.com/jedib0t/go-pretty/v6/table"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/pflag"
+)
+
+//nolint:dupl
+var DeleteCmd = &cobra.Command{
+ Use: "delete",
+ Short: "Delete a backup record",
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Flags().VisitAll(func(flag *pflag.Flag) {
+ fmt.Printf("Flag: %s Value: %s\n", flag.Name,
flag.Value)
+ })
+
+ if CSN == "" && RecordID == "" {
+ logging.Error("Please specify csn or record id")
+ return
+ }
+
+ if CSN != "" && RecordID != "" {
+ logging.Error("Please specify only one of csn and
record id")
+ return
+ }
+
+ if err := deleteRecord(); err != nil {
+ logging.Error(err.Error())
+ }
+ },
+}
+
+//nolint:dupl
+func init() {
+ RootCmd.AddCommand(DeleteCmd)
+
+ DeleteCmd.Flags().StringVarP(&Host, "host", "H", "", "ss-proxy hostname
or ip")
+ _ = DeleteCmd.MarkFlagRequired("host")
+ DeleteCmd.Flags().Uint16VarP(&Port, "port", "P", 0, "ss-proxy port")
+ _ = DeleteCmd.MarkFlagRequired("port")
+ DeleteCmd.Flags().StringVarP(&Username, "username", "u", "", "ss-proxy
username")
+ _ = DeleteCmd.MarkFlagRequired("username")
+ DeleteCmd.Flags().StringVarP(&Password, "password", "p", "", "ss-proxy
password")
+ _ = DeleteCmd.MarkFlagRequired("password")
+ DeleteCmd.Flags().StringVarP(&BackupPath, "dn-backup-path", "B", "",
"openGauss data backup path")
+ _ = DeleteCmd.MarkFlagRequired("dn-backup-path")
+ DeleteCmd.Flags().Uint16VarP(&AgentPort, "agent-port", "a", 443, "agent
server port")
+ _ = DeleteCmd.MarkFlagRequired("agent-port")
+
+ DeleteCmd.Flags().StringVarP(&CSN, "csn", "", "", "commit sequence
number")
+ DeleteCmd.Flags().StringVarP(&RecordID, "id", "", "", "backup record
id")
+}
+
+func deleteRecord() error {
+ // init local storage
+ ls, err := pkg.NewLocalStorage(pkg.DefaultRootDir())
+ if err != nil {
+ return xerr.NewCliErr(fmt.Sprintf("new local storage failed.
err: %s", err.Error()))
+ }
+
+ // get backup record
+ var bak *model.LsBackup
+ bak, err = validate(ls, CSN, RecordID)
+ if err != nil {
+ return err
+ }
+
+ if bak == nil {
+ return xerr.NewCliErr(fmt.Sprintf("backup record not found.
err: %s", err))
+ }
+
+ // check agent server status
+ logging.Info("Checking agent server status...")
+ if available := checkAgentServerStatus(bak); !available {
+ return xerr.NewCliErr("one or more agent server are not
available.")
+ }
+
+ // mark the target backup record to be deleted
+ // meanwhile this record cannot be restored
+ if err := ls.HideByName(bak.Info.FileName); err != nil {
+ return xerr.NewCliErr("cannot mark backup record.")
+ }
+
+ // exec delete
+ logging.Info("Start delete backup data to openGauss...")
+ if err := _execDelete(bak); err != nil {
+ return xerr.NewCliErr(fmt.Sprintf("exec delete failed. err:
%s", err))
+ }
+ logging.Info("Delete backup data success!")
+
+ // delete the backup record
+ if err := ls.DeleteByHidedName(bak.Info.FileName); err != nil {
+ return xerr.NewCliErr(fmt.Sprintf("exec delete backup record
failed. err: %s", err))
+ }
+
+ logging.Info("Delete success!")
+ return nil
+}
+
+func _execDelete(lsBackup *model.LsBackup) error {
+ var (
+ dataNodeMap = make(map[string]*model.DataNode)
+ totalNum = len(lsBackup.SsBackup.StorageNodes)
+ resultCh = make(chan *model.DeleteBackupResult,
totalNum)
+ dnResult = make([]*model.DeleteBackupResult, 0)
+ deleteFinalStatus = "Completed"
+ )
+ for _, dn := range lsBackup.DnList {
+ dataNodeMap[dn.IP] = dn
+ }
+
+ if totalNum == 0 {
+ logging.Info("No data node need to delete backup files")
+ return nil
+ }
+
+ pw := prettyoutput.NewPW(totalNum)
+ go pw.Render()
+
+ for _, storagenode := range lsBackup.SsBackup.StorageNodes {
+ sn := storagenode
+ if dn, ok := dataNodeMap[sn.IP]; !ok {
+ logging.Warn(fmt.Sprintf("SKIPPED! data node %s:%d not
found in backup info.", sn.IP, sn.Port))
+ continue
+ } else {
+ as := pkg.NewAgentServer(fmt.Sprintf("%s:%d",
convertLocalhost(sn.IP), AgentPort))
+ go doDelete(as, sn, dn, resultCh, pw)
+ }
+ }
+
+ time.Sleep(time.Millisecond * 100)
+
+ for pw.IsRenderInProgress() {
+ time.Sleep(time.Millisecond * 100)
+ }
+
+ close(resultCh)
+
+ for result := range resultCh {
+ dnResult = append(dnResult, result)
+ if result.Status != "Completed" {
+ deleteFinalStatus = "Failed"
+ }
+ }
+
+ t := table.NewWriter()
+ t.SetOutputMirror(os.Stdout)
+ t.SetTitle("Delete Backup Files Result")
+ t.AppendHeader(table.Row{"#", "Node IP", "Node Port", "Result",
"Message"})
+ t.SetColumnConfigs([]table.ColumnConfig{{Number: 5, WidthMax: 50}})
+
+ for i, result := range dnResult {
+ t.AppendRow([]interface{}{i + 1, result.IP, result.Port,
result.Status, result.Msg})
+ t.AppendSeparator()
+ }
+
+ t.Render()
+
+ if deleteFinalStatus == "Failed" {
+ return xerr.NewCliErr("delete failed, please check the log for
more details.")
+ }
+
+ return nil
+}
diff --git a/pitr/cli/internal/cmd/delete_test.go
b/pitr/cli/internal/cmd/delete_test.go
new file mode 100644
index 0000000..194e617
--- /dev/null
+++ b/pitr/cli/internal/cmd/delete_test.go
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package cmd
+
+import (
+ "reflect"
+ "time"
+
+ "bou.ke/monkey"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg"
+ mock_pkg
"github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/mocks"
+ "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
+ "github.com/golang/mock/gomock"
+ . "github.com/onsi/ginkgo/v2"
+ . "github.com/onsi/gomega"
+)
+
+var _ = Describe("test delete", func() {
+ var (
+ proxy *mock_pkg.MockIShardingSphereProxy
+ ls *mock_pkg.MockILocalStorage
+ as *mock_pkg.MockIAgentServer
+ bak = &model.LsBackup{
+ Info: &model.BackupMetaInfo{
+ ID: "backup-id-1",
+ FileName: "backup",
+ },
+ DnList: []*model.DataNode{
+ {
+ IP: "127.0.0.1",
+ },
+ },
+ SsBackup: &model.SsBackup{
+ Status: "",
+ ClusterInfo: &model.ClusterInfo{
+ MetaData: model.MetaData{
+ Databases: map[string]string{},
+ Props: "",
+ Rules: "",
+ },
+ SnapshotInfo: nil,
+ },
+ StorageNodes: []*model.StorageNode{
+ {
+ IP: "127.0.0.1",
+ },
+ },
+ },
+ }
+ )
+
+ BeforeEach(func() {
+ ctrl = gomock.NewController(GinkgoT())
+ proxy = mock_pkg.NewMockIShardingSphereProxy(ctrl)
+ as = mock_pkg.NewMockIAgentServer(ctrl)
+ ls = mock_pkg.NewMockILocalStorage(ctrl)
+ monkey.Patch(pkg.NewShardingSphereProxy, func(user, password,
database, host string, port uint16) (pkg.IShardingSphereProxy, error) {
+ return proxy, nil
+ })
+ monkey.Patch(pkg.NewLocalStorage, func(rootDir string)
(pkg.ILocalStorage, error) {
+ return ls, nil
+ })
+ })
+
+ AfterEach(func() {
+ ctrl.Finish()
+ monkey.UnpatchAll()
+ })
+
+ It("test exec delete main func", func() {
+ // patch ReadByID of mock ls
+ monkey.PatchInstanceMethod(reflect.TypeOf(ls), "ReadByID",
func(_ *mock_pkg.MockILocalStorage, _ string) (*model.LsBackup, error) { return
bak, nil })
+ monkey.Patch(pkg.NewAgentServer, func(_ string)
pkg.IAgentServer { return as })
+
+ RecordID = "backup-id"
+ as.EXPECT().CheckStatus(gomock.Any()).Return(nil)
+ ls.EXPECT().HideByName(bak.Info.FileName).Return(nil)
+ as.EXPECT().DeleteBackup(gomock.Any()).Return(nil)
+ ls.EXPECT().DeleteByHidedName(bak.Info.FileName).Return(nil)
+
+ Expect(deleteRecord()).To(BeNil())
+ })
+
+ Context("test exec delete", func() {
+ It("should be success", func() {
+ ctrl := gomock.NewController(GinkgoT())
+ as := mock_pkg.NewMockIAgentServer(ctrl)
+ monkey.Patch(pkg.NewAgentServer, func(_ string)
pkg.IAgentServer {
+ return as
+ })
+ defer func() {
+ ctrl.Finish()
+ monkey.UnpatchAll()
+ }()
+ as.EXPECT().DeleteBackup(gomock.Any()).Do(func(_
*model.DeleteBackupIn) {
+ time.Sleep(3 * time.Second)
+ }).Return(nil)
+ Expect(_execDelete(bak)).To(BeNil())
+ })
+ })
+})
diff --git a/pitr/cli/internal/cmd/restore.go b/pitr/cli/internal/cmd/restore.go
index 92ca2a7..791a043 100644
--- a/pitr/cli/internal/cmd/restore.go
+++ b/pitr/cli/internal/cmd/restore.go
@@ -40,6 +40,7 @@ var (
databaseNamesExist []string
)
+//nolint:dupl
var RestoreCmd = &cobra.Command{
Use: "restore",
Short: "Restore a database cluster ",
@@ -64,6 +65,7 @@ var RestoreCmd = &cobra.Command{
},
}
+//nolint:dupl
func init() {
RootCmd.AddCommand(RestoreCmd)
@@ -97,18 +99,9 @@ func restore() error {
// get backup record
var bak *model.LsBackup
- if CSN != "" {
- bak, err = ls.ReadByCSN(CSN)
- if err != nil {
- return xerr.NewCliErr(fmt.Sprintf("read backup record
by csn failed. err: %s", err))
- }
- }
-
- if RecordID != "" {
- bak, err = ls.ReadByID(RecordID)
- if err != nil {
- return xerr.NewCliErr(fmt.Sprintf("read backup record
by id failed. err: %s", err))
- }
+ bak, err = validate(ls, CSN, RecordID)
+ if err != nil {
+ return err
}
if bak == nil {
return xerr.NewCliErr(fmt.Sprintf("backup record not found.
err: %s", err))
diff --git a/pitr/cli/internal/pkg/local-storage.go
b/pitr/cli/internal/pkg/local-storage.go
index ca00480..47693a2 100644
--- a/pitr/cli/internal/pkg/local-storage.go
+++ b/pitr/cli/internal/pkg/local-storage.go
@@ -44,6 +44,8 @@ type (
ReadByID(id string) (*model.LsBackup, error)
ReadByCSN(csn string) (*model.LsBackup, error)
DeleteByName(name string) error
+ HideByName(name string) error
+ DeleteByHidedName(name string) error
}
Extension string
@@ -164,7 +166,7 @@ func (ls *localStorage) ReadAll() ([]*model.LsBackup,
error) {
if err := json.Unmarshal(file, b); err != nil {
return nil, xerr.NewCliErr(fmt.Sprintf("invalid
contents[filePath=%s]. err: %s", path, err))
}
-
+ b.Info.FileName = info.Name()
backups = append(backups, b)
}
return backups, nil
@@ -214,10 +216,34 @@ func (ls *localStorage) GenFilename(extn Extension)
string {
}
}
-func (ls *localStorage) DeleteByName(name string) error {
+type mode int
+
+const (
+ normal mode = iota
+ hided
+)
+
+func (ls *localStorage) deleteByName(name string, mode mode) error {
path := fmt.Sprintf("%s/%s", ls.backupDir, name)
if err := os.Remove(path); err != nil {
return xerr.NewCliErr(fmt.Sprintf("delete file failed. err:
%s", err))
}
return nil
}
+
+func (ls *localStorage) DeleteByName(name string) error {
+ return ls.deleteByName(name, normal)
+}
+
+func (ls *localStorage) DeleteByHidedName(name string) error {
+ return ls.deleteByName(fmt.Sprintf(".%s", name), hided)
+}
+
+func (ls *localStorage) HideByName(name string) error {
+ path := fmt.Sprintf("%s/%s", ls.backupDir, name)
+ hided := fmt.Sprintf("%s/.%s", ls.backupDir, name)
+ if err := os.Rename(path, hided); err != nil {
+ return xerr.NewCliErr(fmt.Sprintf("hide file failed. err: %s",
err))
+ }
+ return nil
+}
diff --git a/pitr/cli/internal/pkg/mocks/local-storage.go
b/pitr/cli/internal/pkg/mocks/local-storage.go
index 9284834..5005197 100644
--- a/pitr/cli/internal/pkg/mocks/local-storage.go
+++ b/pitr/cli/internal/pkg/mocks/local-storage.go
@@ -1,72 +1,54 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements. See the NOTICE file distributed with
-* this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
- */
-
// Code generated by MockGen. DO NOT EDIT.
-// Source: local-storage.go
+// Source: internal/pkg/local-storage.go
// Package mock_pkg is a generated GoMock package.
package mock_pkg
import (
- reflect "reflect"
-
pkg "github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg"
model
"github.com/apache/shardingsphere-on-cloud/pitr/cli/internal/pkg/model"
gomock "github.com/golang/mock/gomock"
+ reflect "reflect"
)
-// MockILocalStorage is a mock of ILocalStorage interface.
+// MockILocalStorage is a mock of ILocalStorage interface
type MockILocalStorage struct {
ctrl *gomock.Controller
recorder *MockILocalStorageMockRecorder
}
-// MockILocalStorageMockRecorder is the mock recorder for MockILocalStorage.
+// MockILocalStorageMockRecorder is the mock recorder for MockILocalStorage
type MockILocalStorageMockRecorder struct {
mock *MockILocalStorage
}
-// NewMockILocalStorage creates a new mock instance.
+// NewMockILocalStorage creates a new mock instance
func NewMockILocalStorage(ctrl *gomock.Controller) *MockILocalStorage {
mock := &MockILocalStorage{ctrl: ctrl}
mock.recorder = &MockILocalStorageMockRecorder{mock}
return mock
}
-// EXPECT returns an object that allows the caller to indicate expected use.
+// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockILocalStorage) EXPECT() *MockILocalStorageMockRecorder {
return m.recorder
}
-// DeleteByName mocks base method.
-func (m *MockILocalStorage) DeleteByName(name string) error {
+// WriteByJSON mocks base method
+func (m *MockILocalStorage) WriteByJSON(name string, contents *model.LsBackup)
error {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "DeleteByName", name)
+ ret := m.ctrl.Call(m, "WriteByJSON", name, contents)
ret0, _ := ret[0].(error)
return ret0
}
-// DeleteByName indicates an expected call of DeleteByName.
-func (mr *MockILocalStorageMockRecorder) DeleteByName(name interface{})
*gomock.Call {
+// WriteByJSON indicates an expected call of WriteByJSON
+func (mr *MockILocalStorageMockRecorder) WriteByJSON(name, contents
interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByName",
reflect.TypeOf((*MockILocalStorage)(nil).DeleteByName), name)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteByJSON",
reflect.TypeOf((*MockILocalStorage)(nil).WriteByJSON), name, contents)
}
-// GenFilename mocks base method.
+// GenFilename mocks base method
func (m *MockILocalStorage) GenFilename(extn pkg.Extension) string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GenFilename", extn)
@@ -74,13 +56,13 @@ func (m *MockILocalStorage) GenFilename(extn pkg.Extension)
string {
return ret0
}
-// GenFilename indicates an expected call of GenFilename.
+// GenFilename indicates an expected call of GenFilename
func (mr *MockILocalStorageMockRecorder) GenFilename(extn interface{})
*gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenFilename",
reflect.TypeOf((*MockILocalStorage)(nil).GenFilename), extn)
}
-// ReadAll mocks base method.
+// ReadAll mocks base method
func (m *MockILocalStorage) ReadAll() ([]*model.LsBackup, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReadAll")
@@ -89,13 +71,28 @@ func (m *MockILocalStorage) ReadAll() ([]*model.LsBackup,
error) {
return ret0, ret1
}
-// ReadAll indicates an expected call of ReadAll.
+// ReadAll indicates an expected call of ReadAll
func (mr *MockILocalStorageMockRecorder) ReadAll() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadAll",
reflect.TypeOf((*MockILocalStorage)(nil).ReadAll))
}
-// ReadByCSN mocks base method.
+// ReadByID mocks base method
+func (m *MockILocalStorage) ReadByID(id string) (*model.LsBackup, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "ReadByID", id)
+ ret0, _ := ret[0].(*model.LsBackup)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// ReadByID indicates an expected call of ReadByID
+func (mr *MockILocalStorageMockRecorder) ReadByID(id interface{}) *gomock.Call
{
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadByID",
reflect.TypeOf((*MockILocalStorage)(nil).ReadByID), id)
+}
+
+// ReadByCSN mocks base method
func (m *MockILocalStorage) ReadByCSN(csn string) (*model.LsBackup, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReadByCSN", csn)
@@ -104,37 +101,50 @@ func (m *MockILocalStorage) ReadByCSN(csn string)
(*model.LsBackup, error) {
return ret0, ret1
}
-// ReadByCSN indicates an expected call of ReadByCSN.
+// ReadByCSN indicates an expected call of ReadByCSN
func (mr *MockILocalStorageMockRecorder) ReadByCSN(csn interface{})
*gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadByCSN",
reflect.TypeOf((*MockILocalStorage)(nil).ReadByCSN), csn)
}
-// ReadByID mocks base method.
-func (m *MockILocalStorage) ReadByID(id string) (*model.LsBackup, error) {
+// DeleteByName mocks base method
+func (m *MockILocalStorage) DeleteByName(name string) error {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ReadByID", id)
- ret0, _ := ret[0].(*model.LsBackup)
- ret1, _ := ret[1].(error)
- return ret0, ret1
+ ret := m.ctrl.Call(m, "DeleteByName", name)
+ ret0, _ := ret[0].(error)
+ return ret0
}
-// ReadByID indicates an expected call of ReadByID.
-func (mr *MockILocalStorageMockRecorder) ReadByID(id interface{}) *gomock.Call
{
+// DeleteByName indicates an expected call of DeleteByName
+func (mr *MockILocalStorageMockRecorder) DeleteByName(name interface{})
*gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadByID",
reflect.TypeOf((*MockILocalStorage)(nil).ReadByID), id)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByName",
reflect.TypeOf((*MockILocalStorage)(nil).DeleteByName), name)
}
-// WriteByJSON mocks base method.
-func (m *MockILocalStorage) WriteByJSON(name string, contents *model.LsBackup)
error {
+// HideByName mocks base method
+func (m *MockILocalStorage) HideByName(name string) error {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "WriteByJSON", name, contents)
+ ret := m.ctrl.Call(m, "HideByName", name)
ret0, _ := ret[0].(error)
return ret0
}
-// WriteByJSON indicates an expected call of WriteByJSON.
-func (mr *MockILocalStorageMockRecorder) WriteByJSON(name, contents
interface{}) *gomock.Call {
+// HideByName indicates an expected call of HideByName
+func (mr *MockILocalStorageMockRecorder) HideByName(name interface{})
*gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "WriteByJSON",
reflect.TypeOf((*MockILocalStorage)(nil).WriteByJSON), name, contents)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HideByName",
reflect.TypeOf((*MockILocalStorage)(nil).HideByName), name)
+}
+
+// DeleteByHidedName mocks base method
+func (m *MockILocalStorage) DeleteByHidedName(name string) error {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "DeleteByHidedName", name)
+ ret0, _ := ret[0].(error)
+ return ret0
+}
+
+// DeleteByHidedName indicates an expected call of DeleteByHidedName
+func (mr *MockILocalStorageMockRecorder) DeleteByHidedName(name interface{})
*gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock,
"DeleteByHidedName",
reflect.TypeOf((*MockILocalStorage)(nil).DeleteByHidedName), name)
}
diff --git a/pitr/cli/internal/pkg/model/ls_backup.go
b/pitr/cli/internal/pkg/model/ls_backup.go
index 8301a95..8b5a428 100644
--- a/pitr/cli/internal/pkg/model/ls_backup.go
+++ b/pitr/cli/internal/pkg/model/ls_backup.go
@@ -31,6 +31,7 @@ type (
BackupMode DBBackupMode `json:"backup_mode"`
StartTime int64 `json:"start_time"` // Unix time
EndTime int64 `json:"end_time"` // Unix time
+ FileName string
}
DataNode struct {
diff --git a/pitr/cli/pkg/httputils/req.go b/pitr/cli/pkg/httputils/req.go
index 49138d8..c38a5ca 100644
--- a/pitr/cli/pkg/httputils/req.go
+++ b/pitr/cli/pkg/httputils/req.go
@@ -131,14 +131,16 @@ func (r *req) setReqHeader(req *http.Request)
*http.Request {
req.Header.Set(k, v)
}
+ if req.Header.Get("x-request-id") == "" {
+ req.Header.Set("x-request-id", uuid.New().String())
+ }
+
// set default header if method is post
- if r.method == http.MethodPost {
+ if r.method == http.MethodPost || r.method == http.MethodDelete {
if req.Header.Get("Content-Type") == "" {
req.Header.Set("Content-Type", "application/json")
}
- if req.Header.Get("x-request-id") == "" {
- req.Header.Set("x-request-id", uuid.New().String())
- }
+
}
return req
}