Antonio Mika
·
08 Oct 24
clean.go
1package main
2
3import (
4 "log/slog"
5 "os"
6 "strings"
7
8 "github.com/picosh/pico/db"
9 "github.com/picosh/pico/db/postgres"
10 "github.com/picosh/pico/pgs"
11 "github.com/picosh/pico/shared"
12 "github.com/picosh/pico/shared/storage"
13 "github.com/picosh/utils"
14)
15
16func bail(err error) {
17 if err != nil {
18 panic(err)
19 }
20}
21
22type RmProject struct {
23 user *db.User
24 name string
25}
26
27// this script will find any objects stored within Store that does not
28// have a corresponding project inside our database.
29func main() {
30 // to actually commit changes, set to true
31 writeEnv := utils.GetEnv("WRITE", "0")
32 write := false
33 if writeEnv == "1" {
34 write = true
35 }
36 logger := slog.Default()
37
38 picoCfg := shared.NewConfigSite()
39 picoCfg.Logger = logger
40 picoCfg.DbURL = os.Getenv("DATABASE_URL")
41 picoCfg.MinioURL = os.Getenv("MINIO_URL")
42 picoCfg.MinioUser = os.Getenv("MINIO_ROOT_USER")
43 picoCfg.MinioPass = os.Getenv("MINIO_ROOT_PASSWORD")
44 picoDb := postgres.NewDB(picoCfg.DbURL, picoCfg.Logger)
45
46 var st storage.StorageServe
47 var err error
48 st, err = storage.NewStorageMinio(picoCfg.MinioURL, picoCfg.MinioUser, picoCfg.MinioPass)
49 bail(err)
50
51 logger.Info("fetching all users")
52 users, err := picoDb.FindUsers()
53 bail(err)
54
55 logger.Info("fetching all buckets")
56 buckets, err := st.ListBuckets()
57 bail(err)
58
59 rmProjects := []RmProject{}
60
61 for _, bucketName := range buckets {
62 // only care about pgs
63 if !strings.HasPrefix(bucketName, "static-") {
64 continue
65 }
66
67 bucket, err := st.GetBucket(bucketName)
68 bail(err)
69 bucketProjects, err := st.ListObjects(bucket, "/", false)
70 bail(err)
71
72 userID := strings.Replace(bucketName, "static-", "", 1)
73 user := &db.User{
74 ID: userID,
75 Name: userID,
76 }
77 for _, u := range users {
78 if u.ID == userID {
79 user = u
80 break
81 }
82 }
83 projects, err := picoDb.FindProjectsByUser(userID)
84 bail(err)
85 for _, bucketProject := range bucketProjects {
86 found := false
87 for _, project := range projects {
88 // ignore links
89 if project.Name != project.ProjectDir {
90 continue
91 }
92 if project.Name == bucketProject.Name() {
93 found = true
94 }
95 }
96 if !found {
97 logger.Info("marking for removal", "bucket", bucketName, "project", bucketProject.Name())
98 rmProjects = append(rmProjects, RmProject{
99 name: bucketProject.Name(),
100 user: user,
101 })
102 }
103 }
104 }
105
106 session := &utils.CmdSessionLogger{
107 Log: logger,
108 }
109
110 for _, project := range rmProjects {
111 opts := &pgs.Cmd{
112 Session: session,
113 User: project.user,
114 Store: st,
115 Log: logger,
116 Dbpool: picoDb,
117 Write: write,
118 }
119 err := opts.RmProjectAssets(project.name)
120 bail(err)
121 }
122
123 logger.Info("store projects marked for deletion", "length", len(rmProjects))
124 for _, project := range rmProjects {
125 logger.Info("removing project", "user", project.user.Name, "project", project.name)
126 }
127 if !write {
128 logger.Info("WARNING: changes not committed, need env var WRITE=1")
129 }
130}