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 }