• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	"context"
20	"fmt"
21	"fotff/res"
22	"fotff/utils"
23	"github.com/sirupsen/logrus"
24	"os"
25	"path/filepath"
26)
27
28type BuildConfig struct {
29	Pkg           string
30	PreCompileCMD string
31	CompileCMD    string
32	ImgList       []string
33}
34
35func (m *Manager) Build(config BuildConfig, ctx context.Context) error {
36	if m.PkgAvailable(config) {
37		return nil
38	}
39	logrus.Infof("%s is not available", config.Pkg)
40	err := m.BuildNoRetry(config, false, ctx)
41	if err == nil {
42		return nil
43	}
44	logrus.Errorf("build pkg %s err: %v", config.Pkg, err)
45	logrus.Infof("rm out and build pkg %s again...", config.Pkg)
46	err = m.BuildNoRetry(config, true, ctx)
47	if err == nil {
48		return nil
49	}
50	logrus.Errorf("build pkg %s err: %v", config.Pkg, err)
51	return err
52}
53
54// PkgAvailable returns true if all necessary images are all available to flash.
55func (m *Manager) PkgAvailable(config BuildConfig) bool {
56	for _, img := range config.ImgList {
57		imgName := filepath.Base(img)
58		if _, err := os.Stat(filepath.Join(m.Workspace, config.Pkg, imgName)); err != nil {
59			return false
60		}
61	}
62	return true
63}
64
65// BuildNoRetry obtain an available server, download corresponding codes, and run compile commands
66// to build the corresponding package images, then transfer these images to the 'pkg' directory.
67func (m *Manager) BuildNoRetry(config BuildConfig, rm bool, ctx context.Context) error {
68	logrus.Infof("now Build %s", config.Pkg)
69	server := res.GetBuildServer()
70	defer res.ReleaseBuildServer(server)
71	cmd := fmt.Sprintf("mkdir -p %s && cd %s && repo init -u https://gitee.com/openharmony/manifest.git", server.WorkSpace, server.WorkSpace)
72	if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil {
73		return fmt.Errorf("remote: mkdir error: %w", err)
74	}
75	if err := utils.TransFileViaSSH(utils.Upload, server.Addr, server.User, server.Passwd,
76		fmt.Sprintf("%s/.repo/manifest.xml", server.WorkSpace), filepath.Join(m.Workspace, config.Pkg, "manifest_tag.xml")); err != nil {
77		return fmt.Errorf("upload and replace manifest error: %w", err)
78	}
79	// 'git lfs install' may fail due to some git hooks. Call 'git lfs update --force' before install to avoid this situation.
80	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)
81	if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil {
82		return fmt.Errorf("remote: repo sync error: %w", err)
83	}
84	cmd = fmt.Sprintf("cd %s && %s", server.WorkSpace, config.PreCompileCMD)
85	if err := utils.RunCmdViaSSHContextNoRetry(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil {
86		return fmt.Errorf("remote: pre-compile command error: %w", err)
87	}
88	if rm {
89		cmd = fmt.Sprintf("cd %s && rm -rf out", server.WorkSpace)
90		if err := utils.RunCmdViaSSHContext(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil {
91			return fmt.Errorf("remote: rm ./out command error: %w", err)
92		}
93	}
94	cmd = fmt.Sprintf("cd %s && %s", server.WorkSpace, config.CompileCMD)
95	if err := utils.RunCmdViaSSHContextNoRetry(ctx, server.Addr, server.User, server.Passwd, cmd); err != nil {
96		return fmt.Errorf("remote: compile command error: %w", err)
97	}
98	// has been built already, pitiful if canceled, so continue copying
99	for _, f := range config.ImgList {
100		imgName := filepath.Base(f)
101		if err := utils.TransFileViaSSH(utils.Download, server.Addr, server.User, server.Passwd,
102			fmt.Sprintf("%s/%s", server.WorkSpace, f), filepath.Join(m.Workspace, config.Pkg, imgName)); err != nil {
103			return fmt.Errorf("download file %s error: %w", f, err)
104		}
105	}
106	return nil
107}
108