github.com/chenbh/concourse/v6@v6.4.2/atc/gc/volume_collector.go (about)

     1  package gc
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/lager"
     8  	"code.cloudfoundry.org/lager/lagerctx"
     9  	"github.com/chenbh/concourse/v6/atc/db"
    10  	"github.com/chenbh/concourse/v6/atc/metric"
    11  	multierror "github.com/hashicorp/go-multierror"
    12  )
    13  
    14  type volumeCollector struct {
    15  	volumeRepository         db.VolumeRepository
    16  	missingVolumeGracePeriod time.Duration
    17  }
    18  
    19  func NewVolumeCollector(
    20  	volumeRepository db.VolumeRepository,
    21  	missingVolumeGracePeriod time.Duration,
    22  ) *volumeCollector {
    23  	return &volumeCollector{
    24  		volumeRepository:         volumeRepository,
    25  		missingVolumeGracePeriod: missingVolumeGracePeriod,
    26  	}
    27  }
    28  
    29  func (vc *volumeCollector) Run(ctx context.Context) error {
    30  	logger := lagerctx.FromContext(ctx).Session("volume-collector")
    31  
    32  	logger.Debug("start")
    33  	defer logger.Debug("done")
    34  
    35  	start := time.Now()
    36  	defer func() {
    37  		metric.VolumeCollectorDuration{
    38  			Duration: time.Since(start),
    39  		}.Emit(logger)
    40  	}()
    41  
    42  	var errs error
    43  
    44  	err := vc.cleanupFailedVolumes(logger.Session("failed-volumes"))
    45  	if err != nil {
    46  		errs = multierror.Append(errs, err)
    47  		logger.Error("failed-to-clean-up-failed-volumes", err)
    48  	}
    49  
    50  	err = vc.markOrphanedVolumesAsDestroying(logger.Session("mark-volumes"))
    51  	if err != nil {
    52  		errs = multierror.Append(errs, err)
    53  		logger.Error("failed-to-transition-created-volumes-to-destroying", err)
    54  	}
    55  
    56  	_, err = vc.volumeRepository.RemoveMissingVolumes(vc.missingVolumeGracePeriod)
    57  	if err != nil {
    58  		errs = multierror.Append(errs, err)
    59  		logger.Error("failed-to-clean-up-missing-volumes", err)
    60  	}
    61  
    62  	return errs
    63  }
    64  
    65  func (vc *volumeCollector) cleanupFailedVolumes(logger lager.Logger) error {
    66  	failedVolumesLen, err := vc.volumeRepository.DestroyFailedVolumes()
    67  	if err != nil {
    68  		logger.Error("failed-to-get-failed-volumes", err)
    69  		return err
    70  	}
    71  
    72  	if failedVolumesLen > 0 {
    73  		logger.Debug("found-failed-volumes", lager.Data{
    74  			"failed": failedVolumesLen,
    75  		})
    76  	}
    77  
    78  	metric.FailedVolumesToBeGarbageCollected{
    79  		Volumes: failedVolumesLen,
    80  	}.Emit(logger)
    81  
    82  	return nil
    83  }
    84  
    85  func (vc *volumeCollector) markOrphanedVolumesAsDestroying(logger lager.Logger) error {
    86  	orphanedVolumesHandles, err := vc.volumeRepository.GetOrphanedVolumes()
    87  	if err != nil {
    88  		logger.Error("failed-to-get-orphaned-volumes", err)
    89  		return err
    90  	}
    91  
    92  	if len(orphanedVolumesHandles) > 0 {
    93  		logger.Debug("found-orphaned-volumes", lager.Data{
    94  			"destroying": len(orphanedVolumesHandles),
    95  		})
    96  	}
    97  
    98  	metric.CreatedVolumesToBeGarbageCollected{
    99  		Volumes: len(orphanedVolumesHandles),
   100  	}.Emit(logger)
   101  
   102  	for _, orphanedVolume := range orphanedVolumesHandles {
   103  		// queue
   104  		vLog := logger.Session("mark-created-as-destroying", lager.Data{
   105  			"volume": orphanedVolume.Handle(),
   106  			"worker": orphanedVolume.WorkerName(),
   107  		})
   108  
   109  		_, err = orphanedVolume.Destroying()
   110  		if err != nil {
   111  			vLog.Error("failed-to-transition", err)
   112  			continue
   113  		}
   114  
   115  	}
   116  
   117  	return nil
   118  }