[#9999] adm: Add dry-run
flag to zombie scan
command
Some checks failed
DCO action / DCO (pull_request) Successful in 45s
Vulncheck / Vulncheck (pull_request) Failing after 1m14s
Build / Build Components (pull_request) Successful in 1m21s
Tests and linters / Staticcheck (pull_request) Successful in 2m50s
Tests and linters / Lint (pull_request) Successful in 2m55s
Tests and linters / Tests (pull_request) Successful in 3m0s
Tests and linters / Tests with -race (pull_request) Successful in 3m25s
Tests and linters / gopls check (pull_request) Successful in 3m56s
Some checks failed
DCO action / DCO (pull_request) Successful in 45s
Vulncheck / Vulncheck (pull_request) Failing after 1m14s
Build / Build Components (pull_request) Successful in 1m21s
Tests and linters / Staticcheck (pull_request) Successful in 2m50s
Tests and linters / Lint (pull_request) Successful in 2m55s
Tests and linters / Tests (pull_request) Successful in 3m0s
Tests and linters / Tests with -race (pull_request) Successful in 3m25s
Tests and linters / gopls check (pull_request) Successful in 3m56s
This allows to just print object addresses that should be moved to quarantine. Change-Id: I551979d8bffaf45fe21d92f6edadfaadcb5d6e25 Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
6278986d62
commit
87c9e53c29
2 changed files with 39 additions and 23 deletions
|
@ -18,6 +18,8 @@ const (
|
||||||
walletFlagUsage = "Path to the wallet or binary key"
|
walletFlagUsage = "Path to the wallet or binary key"
|
||||||
addressFlag = "address"
|
addressFlag = "address"
|
||||||
addressFlagUsage = "Address of wallet account"
|
addressFlagUsage = "Address of wallet account"
|
||||||
|
dryRunFlag = "dry-run"
|
||||||
|
dryRunFlagUsage = "Print addresses of objects - candidates for quarantine without actually moving"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -36,6 +38,7 @@ var (
|
||||||
_ = viper.BindPFlag(walletFlag, cmd.Flags().Lookup(walletFlag))
|
_ = viper.BindPFlag(walletFlag, cmd.Flags().Lookup(walletFlag))
|
||||||
_ = viper.BindPFlag(addressFlag, cmd.Flags().Lookup(addressFlag))
|
_ = viper.BindPFlag(addressFlag, cmd.Flags().Lookup(addressFlag))
|
||||||
_ = viper.BindPFlag(flagBatchSize, cmd.Flags().Lookup(flagBatchSize))
|
_ = viper.BindPFlag(flagBatchSize, cmd.Flags().Lookup(flagBatchSize))
|
||||||
|
_ = viper.BindPFlag(dryRunFlag, cmd.Flags().Lookup(dryRunFlag))
|
||||||
},
|
},
|
||||||
Run: scan,
|
Run: scan,
|
||||||
}
|
}
|
||||||
|
@ -92,6 +95,7 @@ func initScanCmd() {
|
||||||
scanCmd.Flags().Uint32(flagBatchSize, 1000, flagBatchSizeUsage)
|
scanCmd.Flags().Uint32(flagBatchSize, 1000, flagBatchSizeUsage)
|
||||||
scanCmd.Flags().StringP(walletFlag, walletFlagShorthand, "", walletFlagUsage)
|
scanCmd.Flags().StringP(walletFlag, walletFlagShorthand, "", walletFlagUsage)
|
||||||
scanCmd.Flags().String(addressFlag, "", addressFlagUsage)
|
scanCmd.Flags().String(addressFlag, "", addressFlagUsage)
|
||||||
|
scanCmd.Flags().Bool(dryRunFlag, false, dryRunFlagUsage)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initListCmd() {
|
func initListCmd() {
|
||||||
|
|
|
@ -34,6 +34,7 @@ func scan(cmd *cobra.Command, _ []string) {
|
||||||
if batchSize == 0 {
|
if batchSize == 0 {
|
||||||
commonCmd.ExitOnErr(cmd, "invalid batch size: %w", errors.New("batch size must be positive value"))
|
commonCmd.ExitOnErr(cmd, "invalid batch size: %w", errors.New("batch size must be positive value"))
|
||||||
}
|
}
|
||||||
|
dryRun, _ := cmd.Flags().GetBool(dryRunFlag)
|
||||||
|
|
||||||
storageEngine := newEngine(cmd, appCfg)
|
storageEngine := newEngine(cmd, appCfg)
|
||||||
morphClient := createMorphClient(cmd, appCfg)
|
morphClient := createMorphClient(cmd, appCfg)
|
||||||
|
@ -76,7 +77,7 @@ func scan(cmd *cobra.Command, _ []string) {
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
err = scanStorageEngine(cmd.Context(), batchSize, storageEngine, ps, appCfg, cnrCli, nmCli, q, pk)
|
err = scanStorageEngine(cmd, batchSize, storageEngine, ps, appCfg, cnrCli, nmCli, q, pk, dryRun)
|
||||||
close(stopCh)
|
close(stopCh)
|
||||||
}()
|
}()
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
@ -156,8 +157,8 @@ func checkAddr(ctx context.Context, cnrCli *cntClient.Client, nmCli *netmap.Clie
|
||||||
return statusQuarantine, nil
|
return statusQuarantine, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func scanStorageEngine(ctx context.Context, batchSize uint32, storageEngine *engine.StorageEngine, ps *processStatus,
|
func scanStorageEngine(cmd *cobra.Command, batchSize uint32, storageEngine *engine.StorageEngine, ps *processStatus,
|
||||||
appCfg *config.Config, cnrCli *cntClient.Client, nmCli *netmap.Client, q *quarantine, pk *ecdsa.PrivateKey,
|
appCfg *config.Config, cnrCli *cntClient.Client, nmCli *netmap.Client, q *quarantine, pk *ecdsa.PrivateKey, dryRun bool,
|
||||||
) error {
|
) error {
|
||||||
cc := cache.NewSDKClientCache(cache.ClientCacheOpts{
|
cc := cache.NewSDKClientCache(cache.ClientCacheOpts{
|
||||||
DialTimeout: apiclientconfig.DialTimeout(appCfg),
|
DialTimeout: apiclientconfig.DialTimeout(appCfg),
|
||||||
|
@ -166,6 +167,7 @@ func scanStorageEngine(ctx context.Context, batchSize uint32, storageEngine *eng
|
||||||
Key: pk,
|
Key: pk,
|
||||||
AllowExternal: apiclientconfig.AllowExternal(appCfg),
|
AllowExternal: apiclientconfig.AllowExternal(appCfg),
|
||||||
})
|
})
|
||||||
|
ctx := cmd.Context()
|
||||||
|
|
||||||
var cursor *engine.Cursor
|
var cursor *engine.Cursor
|
||||||
for {
|
for {
|
||||||
|
@ -197,30 +199,17 @@ func scanStorageEngine(ctx context.Context, batchSize uint32, storageEngine *eng
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
result, err := checkAddr(egCtx, cnrCli, nmCli, cc, addr.Address)
|
result, err := checkAddr(egCtx, cnrCli, nmCli, cc, addr.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("check object %s status: %w", addr, err)
|
return fmt.Errorf("check object %s status: %w", addr.Address, err)
|
||||||
}
|
}
|
||||||
ps.add(result)
|
ps.add(result)
|
||||||
|
|
||||||
|
if dryRun && result == statusQuarantine {
|
||||||
|
cmd.Println(addr)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
if result == statusQuarantine {
|
if result == statusQuarantine {
|
||||||
var getPrm engine.GetPrm
|
return moveToQuarantine(egCtx, storageEngine, q, addr.Address)
|
||||||
getPrm.WithAddress(addr.Address)
|
|
||||||
res, err := storageEngine.Get(egCtx, getPrm)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("get object %s from storage engine: %w", addr, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := q.Put(egCtx, res.Object()); err != nil {
|
|
||||||
return fmt.Errorf("put object %s to quarantine: %w", addr, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var delPrm engine.DeletePrm
|
|
||||||
delPrm.WithForceRemoval()
|
|
||||||
delPrm.WithAddress(addr.Address)
|
|
||||||
|
|
||||||
_, err = storageEngine.Delete(egCtx, delPrm)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("delete object %s from storage engine: %w", addr, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
@ -231,6 +220,29 @@ func scanStorageEngine(ctx context.Context, batchSize uint32, storageEngine *eng
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func moveToQuarantine(ctx context.Context, storageEngine *engine.StorageEngine, q *quarantine, addr oid.Address) error {
|
||||||
|
var getPrm engine.GetPrm
|
||||||
|
getPrm.WithAddress(addr)
|
||||||
|
res, err := storageEngine.Get(ctx, getPrm)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("get object %s from storage engine: %w", addr, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := q.Put(ctx, res.Object()); err != nil {
|
||||||
|
return fmt.Errorf("put object %s to quarantine: %w", addr, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var delPrm engine.DeletePrm
|
||||||
|
delPrm.WithForceRemoval()
|
||||||
|
delPrm.WithAddress(addr)
|
||||||
|
|
||||||
|
_, err = storageEngine.Delete(ctx, delPrm)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("delete object %s from storage engine: %w", addr, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type processStatus struct {
|
type processStatus struct {
|
||||||
guard sync.RWMutex
|
guard sync.RWMutex
|
||||||
statusCount map[status]uint64
|
statusCount map[status]uint64
|
||||||
|
|
Loading…
Add table
Reference in a new issue