1ba991379Sopenharmony_ci/* 2ba991379Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3ba991379Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4ba991379Sopenharmony_ci * you may not use this file except in compliance with the License. 5ba991379Sopenharmony_ci * You may obtain a copy of the License at 6ba991379Sopenharmony_ci * 7ba991379Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8ba991379Sopenharmony_ci * 9ba991379Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10ba991379Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11ba991379Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12ba991379Sopenharmony_ci * See the License for the specific language governing permissions and 13ba991379Sopenharmony_ci * limitations under the License. 14ba991379Sopenharmony_ci */ 15ba991379Sopenharmony_ci 16ba991379Sopenharmony_cipackage gitee_common 17ba991379Sopenharmony_ci 18ba991379Sopenharmony_ciimport ( 19ba991379Sopenharmony_ci "context" 20ba991379Sopenharmony_ci "fmt" 21ba991379Sopenharmony_ci "fotff/res" 22ba991379Sopenharmony_ci "fotff/utils" 23ba991379Sopenharmony_ci "github.com/sirupsen/logrus" 24ba991379Sopenharmony_ci "os" 25ba991379Sopenharmony_ci "path/filepath" 26ba991379Sopenharmony_ci) 27ba991379Sopenharmony_ci 28ba991379Sopenharmony_citype BuildConfig struct { 29ba991379Sopenharmony_ci Pkg string 30ba991379Sopenharmony_ci PreCompileCMD string 31ba991379Sopenharmony_ci CompileCMD string 32ba991379Sopenharmony_ci ImgList []string 33ba991379Sopenharmony_ci} 34ba991379Sopenharmony_ci 35ba991379Sopenharmony_cifunc (m *Manager) Build(config BuildConfig, ctx context.Context) error { 36ba991379Sopenharmony_ci if m.PkgAvailable(config) { 37ba991379Sopenharmony_ci return nil 38ba991379Sopenharmony_ci } 39ba991379Sopenharmony_ci logrus.Infof("%s is not available", config.Pkg) 40ba991379Sopenharmony_ci err := m.BuildNoRetry(config, false, ctx) 41ba991379Sopenharmony_ci if err == nil { 42ba991379Sopenharmony_ci return nil 43ba991379Sopenharmony_ci } 44ba991379Sopenharmony_ci logrus.Errorf("build pkg %s err: %v", config.Pkg, err) 45ba991379Sopenharmony_ci logrus.Infof("rm out and build pkg %s again...", config.Pkg) 46ba991379Sopenharmony_ci err = m.BuildNoRetry(config, true, ctx) 47ba991379Sopenharmony_ci if err == nil { 48ba991379Sopenharmony_ci return nil 49ba991379Sopenharmony_ci } 50ba991379Sopenharmony_ci logrus.Errorf("build pkg %s err: %v", config.Pkg, err) 51ba991379Sopenharmony_ci return err 52ba991379Sopenharmony_ci} 53ba991379Sopenharmony_ci 54ba991379Sopenharmony_ci// PkgAvailable returns true if all necessary images are all available to flash. 55ba991379Sopenharmony_cifunc (m *Manager) PkgAvailable(config BuildConfig) bool { 56ba991379Sopenharmony_ci for _, img := range config.ImgList { 57ba991379Sopenharmony_ci imgName := filepath.Base(img) 58ba991379Sopenharmony_ci if _, err := os.Stat(filepath.Join(m.Workspace, config.Pkg, imgName)); err != nil { 59ba991379Sopenharmony_ci return false 60ba991379Sopenharmony_ci } 61ba991379Sopenharmony_ci } 62ba991379Sopenharmony_ci return true 63ba991379Sopenharmony_ci} 64ba991379Sopenharmony_ci 65ba991379Sopenharmony_ci// BuildNoRetry obtain an available server, download corresponding codes, and run compile commands 66ba991379Sopenharmony_ci// to build the corresponding package images, then transfer these images to the 'pkg' directory. 67ba991379Sopenharmony_cifunc (m *Manager) BuildNoRetry(config BuildConfig, rm bool, ctx context.Context) error { 68ba991379Sopenharmony_ci logrus.Infof("now Build %s", config.Pkg) 69ba991379Sopenharmony_ci server := res.GetBuildServer() 70ba991379Sopenharmony_ci defer res.ReleaseBuildServer(server) 71ba991379Sopenharmony_ci cmd := fmt.Sprintf("mkdir -p %s && cd %s && repo init -u https://gitee.com/openharmony/manifest.git", server.WorkSpace, server.WorkSpace) 72ba991379Sopenharmony_ci if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil { 73ba991379Sopenharmony_ci return fmt.Errorf("remote: mkdir error: %w", err) 74ba991379Sopenharmony_ci } 75ba991379Sopenharmony_ci if err := utils.TransFileViaSSH(utils.Upload, server.Addr, server.User, server.Passwd, 76ba991379Sopenharmony_ci fmt.Sprintf("%s/.repo/manifest.xml", server.WorkSpace), filepath.Join(m.Workspace, config.Pkg, "manifest_tag.xml")); err != nil { 77ba991379Sopenharmony_ci return fmt.Errorf("upload and replace manifest error: %w", err) 78ba991379Sopenharmony_ci } 79ba991379Sopenharmony_ci // 'git lfs install' may fail due to some git hooks. Call 'git lfs update --force' before install to avoid this situation. 80ba991379Sopenharmony_ci cmd = fmt.Sprintf("cd %s && repo sync -c --no-tags --force-remove-dirty && repo forall -c 'git reset --hard && git clean -dfx && git lfs update --force && git lfs install && git lfs pull'", server.WorkSpace) 81ba991379Sopenharmony_ci if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil { 82ba991379Sopenharmony_ci return fmt.Errorf("remote: repo sync error: %w", err) 83ba991379Sopenharmony_ci } 84ba991379Sopenharmony_ci cmd = fmt.Sprintf("cd %s && %s", server.WorkSpace, config.PreCompileCMD) 85ba991379Sopenharmony_ci if err := utils.RunCmdViaSSHContextNoRetry(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil { 86ba991379Sopenharmony_ci return fmt.Errorf("remote: pre-compile command error: %w", err) 87ba991379Sopenharmony_ci } 88ba991379Sopenharmony_ci if rm { 89ba991379Sopenharmony_ci cmd = fmt.Sprintf("cd %s && rm -rf out", server.WorkSpace) 90ba991379Sopenharmony_ci if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil { 91ba991379Sopenharmony_ci return fmt.Errorf("remote: rm ./out command error: %w", err) 92ba991379Sopenharmony_ci } 93ba991379Sopenharmony_ci } 94ba991379Sopenharmony_ci cmd = fmt.Sprintf("cd %s && %s", server.WorkSpace, config.CompileCMD) 95ba991379Sopenharmony_ci if err := utils.RunCmdViaSSHContextNoRetry(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil { 96ba991379Sopenharmony_ci return fmt.Errorf("remote: compile command error: %w", err) 97ba991379Sopenharmony_ci } 98ba991379Sopenharmony_ci // has been built already, pitiful if canceled, so continue copying 99ba991379Sopenharmony_ci for _, f := range config.ImgList { 100ba991379Sopenharmony_ci imgName := filepath.Base(f) 101ba991379Sopenharmony_ci if err := utils.TransFileViaSSH(utils.Download, server.Addr, server.User, server.Passwd, 102ba991379Sopenharmony_ci fmt.Sprintf("%s/%s", server.WorkSpace, f), filepath.Join(m.Workspace, config.Pkg, imgName)); err != nil { 103ba991379Sopenharmony_ci return fmt.Errorf("download file %s error: %w", f, err) 104ba991379Sopenharmony_ci } 105ba991379Sopenharmony_ci } 106ba991379Sopenharmony_ci return nil 107ba991379Sopenharmony_ci} 108