管理端全部功能跑通
This commit is contained in:
230
EdgeAPI/internal/installers/installer_httpdns_node.go
Normal file
230
EdgeAPI/internal/installers/installer_httpdns_node.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package installers
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/TeaOSLab/EdgeAPI/internal/db/models"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
)
|
||||
|
||||
type HTTPDNSNodeInstaller struct {
|
||||
BaseInstaller
|
||||
}
|
||||
|
||||
func (i *HTTPDNSNodeInstaller) Install(dir string, params interface{}, installStatus *models.NodeInstallStatus) error {
|
||||
if params == nil {
|
||||
return errors.New("'params' required for node installation")
|
||||
}
|
||||
nodeParams, ok := params.(*NodeParams)
|
||||
if !ok {
|
||||
return errors.New("'params' should be *NodeParams")
|
||||
}
|
||||
err := nodeParams.Validate()
|
||||
if err != nil {
|
||||
return fmt.Errorf("params validation: %w", err)
|
||||
}
|
||||
|
||||
installRootDir, appDir := resolveHTTPDNSInstallPaths(dir)
|
||||
|
||||
_, err = i.client.Stat(installRootDir)
|
||||
if err != nil {
|
||||
err = i.client.MkdirAll(installRootDir)
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "CREATE_ROOT_DIRECTORY_FAILED"
|
||||
return fmt.Errorf("create directory '%s' failed: %w", installRootDir, err)
|
||||
}
|
||||
}
|
||||
|
||||
env, err := i.InstallHelper(installRootDir, nodeconfigs.NodeRoleHTTPDNS)
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "INSTALL_HELPER_FAILED"
|
||||
return err
|
||||
}
|
||||
|
||||
filePrefix := "edge-httpdns-" + env.OS + "-" + env.Arch
|
||||
zipFile, err := i.LookupLatestInstallerForTarget(filePrefix, env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(zipFile) == 0 {
|
||||
return errors.New("can not find installer file for " + env.OS + "/" + env.Arch + ", expected '" + filePrefix + "-v*.zip' or distro-specific '" + filePrefix + "-{ubuntu22.04|amzn2023}-v*.zip'")
|
||||
}
|
||||
|
||||
targetZip, err := i.copyZipToRemote(installRootDir, zipFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !nodeParams.IsUpgrading {
|
||||
_, stderr, testErr := i.client.Exec(env.HelperPath + " -cmd=test")
|
||||
if testErr != nil {
|
||||
return fmt.Errorf("test failed: %w", testErr)
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
return errors.New("test failed: " + stderr)
|
||||
}
|
||||
}
|
||||
|
||||
exePath := appDir + "/bin/edge-httpdns"
|
||||
if nodeParams.IsUpgrading {
|
||||
_, err = i.client.Stat(exePath)
|
||||
if err == nil {
|
||||
_, _, _ = i.client.Exec(exePath + " stop")
|
||||
removeErr := i.client.Remove(exePath)
|
||||
if removeErr != nil && removeErr != os.ErrNotExist {
|
||||
return fmt.Errorf("remove old file failed: %w", removeErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, stderr, err := i.client.Exec(env.HelperPath + " -cmd=unzip -zip=\"" + targetZip + "\" -target=\"" + installRootDir + "\"")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
return errors.New("unzip installer failed: " + stderr)
|
||||
}
|
||||
|
||||
certFile := appDir + "/configs/tls/server.crt"
|
||||
keyFile := appDir + "/configs/tls/server.key"
|
||||
err = i.writeTLSCertificate(certFile, keyFile, nodeParams.TLSCertData, nodeParams.TLSKeyData)
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "WRITE_TLS_CERT_FAILED"
|
||||
return err
|
||||
}
|
||||
|
||||
configFile := appDir + "/configs/api_httpdns.yaml"
|
||||
if i.client.sudo {
|
||||
_, _, _ = i.client.Exec("chown " + i.client.User() + " " + filepath.Dir(configFile))
|
||||
}
|
||||
|
||||
configData := []byte(`rpc.endpoints: [ ${endpoints} ]
|
||||
nodeId: "${nodeId}"
|
||||
secret: "${nodeSecret}"
|
||||
|
||||
https.listenAddr: ":443"
|
||||
https.cert: "${certFile}"
|
||||
https.key: "${keyFile}"`)
|
||||
certFileClean := strings.ReplaceAll(certFile, "\\", "/")
|
||||
keyFileClean := strings.ReplaceAll(keyFile, "\\", "/")
|
||||
|
||||
configData = bytes.ReplaceAll(configData, []byte("${endpoints}"), []byte(nodeParams.QuoteEndpoints()))
|
||||
configData = bytes.ReplaceAll(configData, []byte("${nodeId}"), []byte(nodeParams.NodeId))
|
||||
configData = bytes.ReplaceAll(configData, []byte("${nodeSecret}"), []byte(nodeParams.Secret))
|
||||
configData = bytes.ReplaceAll(configData, []byte("${certFile}"), []byte(certFileClean))
|
||||
configData = bytes.ReplaceAll(configData, []byte("${keyFile}"), []byte(keyFileClean))
|
||||
|
||||
_, err = i.client.WriteFile(configFile, configData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write '%s': %w", configFile, err)
|
||||
}
|
||||
|
||||
err = i.SetupFluentBit(nodeconfigs.NodeRoleHTTPDNS)
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "SETUP_FLUENT_BIT_FAILED"
|
||||
return fmt.Errorf("setup fluent-bit failed: %w", err)
|
||||
}
|
||||
|
||||
startCmdPrefix := "cd " + shQuote(appDir+"/configs") + " && ../bin/edge-httpdns "
|
||||
|
||||
stdout, stderr, err := i.client.Exec(startCmdPrefix + "test")
|
||||
if err != nil {
|
||||
installStatus.ErrorCode = "TEST_FAILED"
|
||||
return fmt.Errorf("test edge-httpdns failed: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
if regexp.MustCompile(`(?i)rpc`).MatchString(stderr) || regexp.MustCompile(`(?i)rpc`).MatchString(stdout) {
|
||||
installStatus.ErrorCode = "RPC_TEST_FAILED"
|
||||
}
|
||||
return errors.New("test edge-httpdns failed, stdout: " + stdout + ", stderr: " + stderr)
|
||||
}
|
||||
|
||||
stdout, stderr, err = i.client.Exec(startCmdPrefix + "start")
|
||||
if err != nil {
|
||||
return fmt.Errorf("start edge-httpdns failed: %w, stdout: %s, stderr: %s", err, stdout, stderr)
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
return errors.New("start edge-httpdns failed, stdout: " + stdout + ", stderr: " + stderr)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resolveHTTPDNSInstallPaths(rawDir string) (installRootDir string, appDir string) {
|
||||
dir := strings.TrimSpace(rawDir)
|
||||
dir = strings.TrimRight(dir, "/")
|
||||
if len(dir) == 0 {
|
||||
return rawDir, rawDir + "/edge-httpdns"
|
||||
}
|
||||
|
||||
if strings.HasSuffix(dir, "/edge-httpdns") {
|
||||
root := strings.TrimSuffix(dir, "/edge-httpdns")
|
||||
if len(root) == 0 {
|
||||
root = "/"
|
||||
}
|
||||
return root, dir
|
||||
}
|
||||
|
||||
return dir, dir + "/edge-httpdns"
|
||||
}
|
||||
|
||||
func (i *HTTPDNSNodeInstaller) copyZipToRemote(dir string, zipFile string) (string, error) {
|
||||
targetZip := ""
|
||||
var firstCopyErr error
|
||||
zipName := filepath.Base(zipFile)
|
||||
for _, candidate := range []string{
|
||||
dir + "/" + zipName,
|
||||
i.client.UserHome() + "/" + zipName,
|
||||
"/tmp/" + zipName,
|
||||
} {
|
||||
err := i.client.Copy(zipFile, candidate, 0777)
|
||||
if err != nil {
|
||||
if firstCopyErr == nil {
|
||||
firstCopyErr = err
|
||||
}
|
||||
continue
|
||||
}
|
||||
targetZip = candidate
|
||||
firstCopyErr = nil
|
||||
break
|
||||
}
|
||||
if firstCopyErr != nil {
|
||||
return "", fmt.Errorf("upload httpdns file failed: %w", firstCopyErr)
|
||||
}
|
||||
return targetZip, nil
|
||||
}
|
||||
|
||||
func (i *HTTPDNSNodeInstaller) writeTLSCertificate(certFile string, keyFile string, certData []byte, keyData []byte) error {
|
||||
if len(certData) == 0 || len(keyData) == 0 {
|
||||
return errors.New("cluster tls certificate is empty")
|
||||
}
|
||||
certDir := filepath.Dir(certFile)
|
||||
_, stderr, err := i.client.Exec("mkdir -p " + shQuote(certDir))
|
||||
if err != nil {
|
||||
return fmt.Errorf("create tls directory failed: %w, stderr: %s", err, stderr)
|
||||
}
|
||||
if i.client.sudo {
|
||||
_, _, _ = i.client.Exec("chown " + i.client.User() + " " + shQuote(certDir))
|
||||
}
|
||||
|
||||
_, err = i.client.WriteFile(certFile, certData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write cert file failed: %w", err)
|
||||
}
|
||||
_, err = i.client.WriteFile(keyFile, keyData)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write key file failed: %w", err)
|
||||
}
|
||||
|
||||
_, stderr, err = i.client.Exec("chmod 0644 " + shQuote(certFile) + " && chmod 0600 " + shQuote(keyFile))
|
||||
if err != nil {
|
||||
return fmt.Errorf("chmod tls files failed: %w, stderr: %s", err, stderr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user