package makecmd import ( "encoding/json" "fmt" "io" "net/http" "os" "os/exec" "path/filepath" "github.com/spf13/cobra" "yizhisec.com/hsv2/forge/internal/controller/maker" "yizhisec.com/hsv2/forge/internal/opt" "yizhisec.com/hsv2/forge/pkg/logger" tc "yizhisec.com/hsv2/forge/pkg/tool/client" ) func Client() *cobra.Command { _cmd := &cobra.Command{ Use: "client", Short: "make client pkg", } _cmd.AddCommand( clientMac(), clientWin(), clientLinux(), clientBaseImage(), ) return _cmd } func clientWin() *cobra.Command { var ( _version string _pkg bool ) _cmd := &cobra.Command{ Use: "win", Short: "make client-win pkg", RunE: func(cmd *cobra.Command, args []string) error { const ( ZIP_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_client-csgElink/release/2.1.0-std/hs_client_csgElink.zip" VERSION_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_client-csgElink/release/2.1.0-std/windows_version.json" RC_JSON_URL = "https://artifactory.yizhisec.com:443/artifactory/filestore/hsv2/win/win-rc.json" ) var ( err error version string ) if version, err = clientVersion(VERSION_URL); err != nil { return err } if _version != "" { logger.InfoCtx(cmd.Context(), "clientWin: using manual version: %s => %s", version, _version) version = _version } mk := maker.NewMaker(opt.Cfg.Make.Dir) return mk.ClientPKG( cmd.Context(), "win", version, "/api/v2_2/_client/win", maker.WithClientPkgMakePkg(_pkg), maker.WithClientPKGDownload(ZIP_URL, "hs_client.zip"), maker.WithClientPKGDownload(RC_JSON_URL, "rc.json"), maker.WithClientPKGCMDs("unzip /data/hs_client.zip"), maker.WithClientPKGCMDs("mv resources/app.7z /data/app.7z"), maker.WithClientPKGCMDs("7z x /data/app.7z -o/tmp/app"), maker.WithClientPKGCMDs("rm -rf /data/app.7z"), maker.WithClientPKGCMDs("cp /data/version.json /tmp/app/x64/config/windows_version.json"), maker.WithClientPKGCMDs("cp resources/hybridscope-client-setup-zh.exe /tmp/app/x64/hybridscope-client-setup.exe"), maker.WithClientPKGCMDs("7z a /data/app.7z /tmp/app/x64"), maker.WithClientPKGCMDs("rm -rf /tmp/app"), maker.WithClientPKGCMDs("md5sum /data/app.7z | awk '{print $1}' > /data/app.7z.md5"), maker.WithClientPKGCMDs(`sh -c 'echo "{\"url\":\"/api/v2_2/_client/win/app.7z\",\"md5\":\"$(cat /data/app.7z.md5)\"}" > /data/check.json'`), maker.WithClientPKGCMDs("mv resources/hybridscope_offline_installer.exe /data/hybridscope_offline_installer.exe"), maker.WithClientPKGCMDs("mv resources/hybridscope-client-setup-zh.exe /data/hybridscope-client-setup-zh.exe"), maker.WithClientPKGCMDs("mv resources/hybridscope-client-setup-en.exe /data/hybridscope-client-setup-en.exe"), maker.WithClientPKGCMDs("rm -rf /data/hs_client.zip"), maker.WithClientPKGCMDs("rm -rf resources"), ) }, } _cmd.Flags().StringVar(&_version, "version", "", "手动指定版本") _cmd.Flags().BoolVar(&_pkg, "pkg", false, "是否生成升级 pkg") return _cmd } func clientMac() *cobra.Command { var ( _version string _pkg bool ) _cmd := &cobra.Command{ Use: "mac", Aliases: []string{"macos"}, Short: "make client-mac pkg", RunE: func(cmd *cobra.Command, args []string) error { const ( DMG_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_appleclient-csgElink/release/2.1.0-std/hybridscope-client-mac.dmg" PKG_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_appleclient-csgElink/release/2.1.0-std/hybridscope-client-mac.pkg" VERSION_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_appleclient-csgElink/release/2.1.0-std/mac_version.json" // std: VERSION_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/hs_appleclient/release/2.1.0-std/mac_version.json" ) var ( err error version string ) if version, err = clientVersion(VERSION_URL); err != nil { return err } if _version != "" { logger.InfoCtx(cmd.Context(), "clientMac: using manual version: %s => %s", version, _version) version = _version } mk := maker.NewMaker(opt.Cfg.Make.Dir) return mk.ClientPKG( cmd.Context(), "mac", version, "/api/v2_2/_client/mac", maker.WithClientPkgMakePkg(_pkg), maker.WithClientPKGDownload(DMG_URL, "hybridscope-client-mac.dmg"), maker.WithClientPKGDownload(PKG_URL, "hybridscope-client-mac.pkg"), ) }, } _cmd.Flags().StringVar(&_version, "version", "", "手动指定版本") _cmd.Flags().BoolVar(&_pkg, "pkg", false, "是否生成升级 pkg") return _cmd } func clientLinux() *cobra.Command { var ( _version string _pkg bool ) _cmd := &cobra.Command{ Use: "linux", Short: "make client-linux pkg", RunE: func(cmd *cobra.Command, args []string) error { const ( DEB_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/universal-hsclient-linux/release/2.1.0/hscore-linux-2.1.0-csgElink-amd64.deb" VERSION_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/universal-hsclient-linux/release/2.1.0/hscore-linux-2.1.0-csgElink-amd64.json" // std: VERSION_URL = "https://artifactory.yizhisec.com/artifactory/yizhisec-release/universal-hsclient-linux/release/2.1.0/hscore-linux-2.1.0-std-amd64.json" ) var ( err error version string ) if version, err = clientVersion(VERSION_URL); err != nil { return err } if _version != "" { logger.InfoCtx(cmd.Context(), "clientLinux: using manual version: %s => %s", version, _version) version = _version } mk := maker.NewMaker(opt.Cfg.Make.Dir) return mk.ClientPKG( cmd.Context(), "linux", version, "/api/v2_2/_client/linux", maker.WithClientPkgMakePkg(_pkg), maker.WithClientPKGDownload(DEB_URL, "hybridscope-client-linux.deb"), ) }, } _cmd.Flags().StringVar(&_version, "version", "", "手动指定版本") _cmd.Flags().BoolVar(&_pkg, "pkg", false, "是否生成升级 pkg") return _cmd } func clientVersion(_url string) (string, error) { type Res struct { Version string `json:"version"` } var ( err error rr *http.Response res Res bs []byte ) logger.Debug("clientVersion: getting client version with url = %s", _url) if rr, err = tc.HttpClient().Get(_url); err != nil { return "", err } defer rr.Body.Close() if bs, err = io.ReadAll(rr.Body); err != nil { return "", err } logger.Debug("clientVersion: got client version body raw: %s, url = %s", string(bs), _url) if err = json.Unmarshal(bs, &res); err != nil { return "", err } if res.Version == "" { return "", fmt.Errorf("get version empty, url = %s", _url) } return res.Version, nil } func clientBaseImage() *cobra.Command { const ( dbs = ` FROM %s RUN sed -i 's#https\?://dl-cdn.alpinelinux.org/alpine#https://mirrors.tuna.tsinghua.edu.cn/alpine#g' /etc/apk/repositories RUN apk update && apk add curl wget tzdata unzip p7zip ENV TZ=Asia/Shanghai ` _command = "docker build -f Dockerfile -t hub.yizhisec.com/hsv2/base/nginx:latest ." ) var ( _push bool ) _cmd := &cobra.Command{ Use: "base", Short: "make client base image", RunE: func(cmd *cobra.Command, args []string) error { var ( err error tmpDir = filepath.Join(os.TempDir(), "hsv2-client-base") output []byte ) if err = os.MkdirAll(tmpDir, 0755); err != nil { return err } defer os.RemoveAll(tmpDir) dockerfile := filepath.Join(tmpDir, "Dockerfile") if err = os.WriteFile(dockerfile, []byte(fmt.Sprintf(dbs, opt.IMAGE_NGINX)), 0644); err != nil { return err } rc := exec.CommandContext(cmd.Context(), "sh", "-c", _command) rc.Dir = tmpDir if output, err = rc.CombinedOutput(); err != nil { logger.Debug("❌ clientBaseImage: build image failed, output = %s, err = %v", string(output), err) return err } logger.Debug("☑️ clientBaseImage: build image output = %s", string(output)) if _push { rc = exec.CommandContext(cmd.Context(), "sh", "-c", "docker push hub.yizhisec.com/hsv2/base/nginx:latest") if output, err = rc.CombinedOutput(); err != nil { logger.Debug("❌ clientBaseImage: push image failed, output = %s, err = %v", string(output), err) return err } logger.Debug("☑️ clientBaseImage: push image output = %s", string(output)) } logger.Info("️✅ clientBaseImage: build image success!!!") return nil }, } _cmd.Flags().BoolVar(&_push, "push", false, "push image") return _cmd }