1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package gitee_common 17 18import ( 19 "code.cloudfoundry.org/archiver/extractor" 20 "context" 21 "fmt" 22 "fotff/utils" 23 "github.com/sirupsen/logrus" 24 "os" 25 "path/filepath" 26 "strings" 27 "time" 28) 29 30type Manager struct { 31 Component string 32 Branch string 33 ManifestBranch string 34 ArchiveDir string 35 Workspace string 36 WatchCI bool 37} 38 39func NewManager(component string, branch string, manifestBranch string, archiveDir string, workspace string, watchCI bool) *Manager { 40 var ret = Manager{ 41 Component: component, 42 Branch: branch, 43 ManifestBranch: manifestBranch, 44 ArchiveDir: archiveDir, 45 Workspace: workspace, 46 WatchCI: watchCI, 47 } 48 go ret.cleanupOutdated() 49 return &ret 50} 51 52func (m *Manager) cleanupOutdated() { 53 t := time.NewTicker(24 * time.Hour) 54 for { 55 <-t.C 56 es, err := os.ReadDir(m.Workspace) 57 if err != nil { 58 logrus.Errorf("can not read %s: %v", m.Workspace, err) 59 continue 60 } 61 for _, e := range es { 62 if !e.IsDir() { 63 continue 64 } 65 path := filepath.Join(m.Workspace, e.Name()) 66 info, err := e.Info() 67 if err != nil { 68 logrus.Errorf("can not read %s info: %v", path, err) 69 continue 70 } 71 if time.Now().Sub(info.ModTime()) > 7*24*time.Hour { 72 logrus.Warnf("%s outdated, cleanning up its contents...", path) 73 m.cleanupPkgFiles(path) 74 } 75 } 76 } 77} 78 79func (m *Manager) cleanupPkgFiles(path string) { 80 es, err := os.ReadDir(path) 81 if err != nil { 82 logrus.Errorf("can not read %s: %v", path, err) 83 return 84 } 85 for _, e := range es { 86 if e.Name() == "manifest_tag.xml" || e.Name() == "__last_issue__" { 87 continue 88 } 89 if err := os.RemoveAll(filepath.Join(path, e.Name())); err != nil { 90 logrus.Errorf("remove %s fail: %v", filepath.Join(path, e.Name()), err) 91 } 92 } 93} 94 95// Flash function implements pkg.Manager. Flash images in the 'pkg' directory to the given device. 96func (m *Manager) Flash(device string, pkg string, ctx context.Context) error { 97 logrus.Warnf("not implemented yet") 98 return nil 99} 100 101func (m *Manager) Steps(from, to string) (pkgs []string, err error) { 102 if from == to { 103 return nil, fmt.Errorf("steps err: 'from' %s and 'to' %s are the same", from, to) 104 } 105 if c, found := utils.CacheGet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to); found { 106 logrus.Infof("steps from %s to %s are cached", from, to) 107 logrus.Infof("steps: %v", c.([]string)) 108 return c.([]string), nil 109 } 110 if pkgs, err = m.stepsFromGitee(from, to); err != nil { 111 logrus.Errorf("failed to gen steps from gitee, err: %v", err) 112 logrus.Warnf("fallback to getting steps from CI...") 113 if pkgs, err = m.stepsFromCI(from, to); err != nil { 114 return pkgs, err 115 } 116 return pkgs, nil 117 } 118 utils.CacheSet(fmt.Sprintf("%s_steps", m.Component), from+"__to__"+to, pkgs) 119 return pkgs, nil 120} 121 122func (m *Manager) LastIssue(pkg string) (string, error) { 123 data, err := os.ReadFile(filepath.Join(m.Workspace, pkg, "__last_issue__")) 124 return string(data), err 125} 126 127func (m *Manager) GetNewer(cur string) (string, error) { 128 var newFile string 129 if m.WatchCI { 130 newFile = m.getNewerFromCI(cur + ".tar.gz") 131 } else { 132 newFile = m.getNewerFileFromDir(cur+".tar.gz", func(files []os.DirEntry, i, j int) bool { 133 ti, _ := parseTime(files[i].Name()) 134 tj, _ := parseTime(files[j].Name()) 135 return ti.Before(tj) 136 }) 137 } 138 ex := extractor.NewTgz() 139 dirName := strings.TrimSuffix(newFile, ".tar.gz") 140 dir := filepath.Join(m.Workspace, dirName) 141 if _, err := os.Stat(dir); err == nil { 142 return dirName, nil 143 } 144 logrus.Infof("extracting %s to %s...", filepath.Join(m.ArchiveDir, newFile), dir) 145 if err := ex.Extract(filepath.Join(m.ArchiveDir, newFile), dir); err != nil { 146 return dirName, err 147 } 148 return dirName, nil 149} 150 151func (m *Manager) PkgDir(pkg string) string { 152 return filepath.Join(m.Workspace, pkg) 153} 154