github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/pipeline_lifecycle.go (about) 1 package db 2 3 import ( 4 "database/sql" 5 "fmt" 6 7 sq "github.com/Masterminds/squirrel" 8 "github.com/pf-qiu/concourse/v6/atc/db/lock" 9 ) 10 11 //go:generate counterfeiter . PipelineLifecycle 12 13 type PipelineLifecycle interface { 14 ArchiveAbandonedPipelines() error 15 RemoveBuildEventsForDeletedPipelines() error 16 } 17 18 func NewPipelineLifecycle(conn Conn, lockFactory lock.LockFactory) PipelineLifecycle { 19 return &pipelineLifecycle{ 20 conn: conn, 21 lockFactory: lockFactory, 22 } 23 } 24 25 type pipelineLifecycle struct { 26 conn Conn 27 lockFactory lock.LockFactory 28 } 29 30 func (pl *pipelineLifecycle) ArchiveAbandonedPipelines() error { 31 tx, err := pl.conn.Begin() 32 if err != nil { 33 return err 34 } 35 36 defer Rollback(tx) 37 38 rows, err := pipelinesQuery. 39 LeftJoin("jobs j ON j.id = p.parent_job_id"). 40 LeftJoin("pipelines p2 ON j.pipeline_id = p2.id"). 41 Where(sq.Or{ 42 // parent pipeline was destroyed 43 sq.And{ 44 sq.NotEq{"p.parent_build_id": nil}, 45 sq.Eq{"j.id": nil}, 46 }, 47 // pipeline was set by a job. The job was removed from the parent pipeline 48 sq.Eq{"j.active": false}, 49 // parent pipeline was archived 50 sq.Eq{"p2.archived": true}, 51 }). 52 RunWith(tx). 53 Query() 54 if err != nil { 55 return err 56 } 57 defer rows.Close() 58 59 err = archivePipelines(tx, pl.conn, pl.lockFactory, rows) 60 if err != nil { 61 return err 62 } 63 64 err = tx.Commit() 65 if err != nil { 66 return err 67 } 68 69 return nil 70 } 71 72 func archivePipelines(tx Tx, conn Conn, lockFactory lock.LockFactory, rows *sql.Rows) error { 73 var toArchive []pipeline 74 for rows.Next() { 75 p := newPipeline(conn, lockFactory) 76 if err := scanPipeline(p, rows); err != nil { 77 return err 78 } 79 80 toArchive = append(toArchive, *p) 81 } 82 83 for _, pipeline := range toArchive { 84 err := pipeline.archive(tx) 85 if err != nil { 86 return err 87 } 88 } 89 90 return nil 91 } 92 93 func (p *pipelineLifecycle) RemoveBuildEventsForDeletedPipelines() error { 94 rows, err := psql.Select("id"). 95 From("deleted_pipelines"). 96 RunWith(p.conn). 97 Query() 98 if err != nil { 99 return err 100 } 101 102 var idsToDelete []int 103 for rows.Next() { 104 var id int 105 if err := rows.Scan(&id); err != nil { 106 return err 107 } 108 idsToDelete = append(idsToDelete, id) 109 } 110 111 rows.Close() 112 113 if len(idsToDelete) == 0 { 114 return nil 115 } 116 117 for _, id := range idsToDelete { 118 _, err = p.conn.Exec(fmt.Sprintf("DROP TABLE IF EXISTS pipeline_build_events_%d", id)) 119 if err != nil { 120 return err 121 } 122 } 123 124 _, err = psql.Delete("deleted_pipelines"). 125 Where(sq.Eq{"id": idsToDelete}). 126 RunWith(p.conn). 127 Exec() 128 if err != nil { 129 return err 130 } 131 132 return nil 133 }