github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/platform/lambda/prune.go (about)

     1  package lambda
     2  
     3  import (
     4  	"sort"
     5  	"time"
     6  
     7  	"github.com/apex/log"
     8  	"github.com/apex/up/platform/event"
     9  	"github.com/aws/aws-sdk-go/aws"
    10  	"github.com/aws/aws-sdk-go/aws/session"
    11  	"github.com/aws/aws-sdk-go/service/s3"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  // Prune implementation.
    16  func (p *Platform) Prune(region, stage string, versions int) error {
    17  	p.events.Emit("prune", nil)
    18  
    19  	if err := p.createRole(); err != nil {
    20  		return errors.Wrap(err, "creating iam role")
    21  	}
    22  
    23  	s := s3.New(session.New(aws.NewConfig().WithRegion(region)))
    24  	b := aws.String(p.getS3BucketName(region))
    25  	prefix := p.config.Name + "/" + stage + "/"
    26  
    27  	params := &s3.ListObjectsInput{
    28  		Bucket: b,
    29  		Prefix: &prefix,
    30  	}
    31  
    32  	start := time.Now()
    33  	var objects []*s3.Object
    34  	var count int
    35  	var size int64
    36  
    37  	// fetch objects
    38  	err := s.ListObjectsPages(params, func(page *s3.ListObjectsOutput, lastPage bool) bool {
    39  		for _, o := range page.Contents {
    40  			objects = append(objects, o)
    41  		}
    42  		return *page.IsTruncated
    43  	})
    44  
    45  	if err != nil {
    46  		return errors.Wrap(err, "listing s3 objects")
    47  	}
    48  
    49  	// sort by time descending
    50  	sort.Slice(objects, func(i int, j int) bool {
    51  		a := objects[i]
    52  		b := objects[j]
    53  		return (*b).LastModified.Before(*a.LastModified)
    54  	})
    55  
    56  	// remove old versions
    57  	for i, o := range objects {
    58  		ctx := log.WithFields(log.Fields{
    59  			"index":         i,
    60  			"key":           *o.Key,
    61  			"size":          *o.Size,
    62  			"last_modified": *o.LastModified,
    63  		})
    64  
    65  		if i < versions {
    66  			ctx.Debug("retain")
    67  			continue
    68  		}
    69  
    70  		ctx.Debug("remove")
    71  		size += *o.Size
    72  		count++
    73  
    74  		_, err := s.DeleteObject(&s3.DeleteObjectInput{
    75  			Bucket: b,
    76  			Key:    o.Key,
    77  		})
    78  
    79  		if err != nil {
    80  			return errors.Wrap(err, "removing object")
    81  		}
    82  	}
    83  
    84  	p.events.Emit("prune.complete", event.Fields{
    85  		"duration": time.Since(start),
    86  		"size":     size,
    87  		"count":    count,
    88  	})
    89  
    90  	return nil
    91  }