mirror of
https://github.com/labring/sealos.git
synced 2026-09-24 15:46:19 +08:00
+6
-10
@@ -17,13 +17,11 @@ package utils
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/fanux/sealos/pkg/utils/logger"
|
||||
)
|
||||
|
||||
const md5sumCmd = "md5sum %s | cut -d\" \" -f1"
|
||||
|
||||
func FromLocal(localPath string) string {
|
||||
func Md5File(localPath string) string {
|
||||
cmd := fmt.Sprintf(md5sumCmd, localPath)
|
||||
return BashEval(cmd)
|
||||
}
|
||||
@@ -37,13 +35,11 @@ func UserHomeDir() string {
|
||||
return home
|
||||
}
|
||||
|
||||
func FileExist(filename string) bool {
|
||||
_, err := os.Stat(filename)
|
||||
if !os.IsNotExist(err) {
|
||||
if err == nil {
|
||||
return true
|
||||
}
|
||||
logger.Warn(err)
|
||||
func FileExist(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil || os.IsExist(err) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
// Copyright © 2021 sealos.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/fanux/sealos/pkg/utils/logger"
|
||||
)
|
||||
|
||||
type HostFile struct {
|
||||
Path string
|
||||
Hosts map[string]*Hostname
|
||||
}
|
||||
|
||||
type Hostname struct {
|
||||
Comment string
|
||||
Domain string
|
||||
IP string
|
||||
}
|
||||
|
||||
func NewHostname(comment string, domain string, ip string) *Hostname {
|
||||
return &Hostname{comment, domain, ip}
|
||||
}
|
||||
func (h *HostFile) Add(host *Hostname) {
|
||||
if h.Hosts == nil {
|
||||
h.Hosts = make(map[string]*Hostname)
|
||||
}
|
||||
h.Hosts[host.Domain] = host
|
||||
}
|
||||
|
||||
func (h *HostFile) Delete(host string) {
|
||||
delete(h.Hosts, host)
|
||||
}
|
||||
|
||||
func getHostPath() string {
|
||||
path := os.Getenv("GOHOST_FILE")
|
||||
if path == "" {
|
||||
path = "/etc/hosts"
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
func (h *Hostname) toString() string {
|
||||
if len(h.Comment) > 0 {
|
||||
h.Comment += "\n"
|
||||
}
|
||||
return h.Comment + h.IP + " " + h.Domain + "\n"
|
||||
}
|
||||
func appendToFile(filePath string, hostname *Hostname) {
|
||||
fp, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
logger.Warn("failed opening file %s : %s\n", filePath, err)
|
||||
return
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
_, err = fp.WriteString(hostname.toString())
|
||||
if err != nil {
|
||||
logger.Warn("failed append string: %s: %s\n", filePath, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HostFile) ParseHostFile(path string) (map[string]*Hostname, error) {
|
||||
if !FileExist(path) {
|
||||
logger.Warn("path %s is not exists", path)
|
||||
return nil, errors.New("path %s is not exists")
|
||||
}
|
||||
|
||||
fp, fpErr := os.Open(path)
|
||||
if fpErr != nil {
|
||||
logger.Warn("open file '%s' failed\n", path)
|
||||
return nil, fmt.Errorf("open file '%s' failed ", path)
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
br := bufio.NewReader(fp)
|
||||
hostnameMap := make(map[string]*Hostname)
|
||||
curComment := ""
|
||||
for {
|
||||
str, rErr := br.ReadString('\n')
|
||||
if rErr == io.EOF {
|
||||
break
|
||||
}
|
||||
if len(str) == 0 || str == "\r\n" || IsEmptyLine(str) {
|
||||
continue
|
||||
}
|
||||
|
||||
if str[0] == '#' {
|
||||
// 处理注释
|
||||
curComment += str
|
||||
continue
|
||||
}
|
||||
tmpHostnameArr := strings.Fields(str)
|
||||
curDomain := TrimWS(tmpHostnameArr[1])
|
||||
if !CheckDomain(curDomain) {
|
||||
return hostnameMap, errors.New(" file contain error domain" + curDomain)
|
||||
}
|
||||
curIP := TrimWS(tmpHostnameArr[0])
|
||||
checkIP := CheckIP(curIP)
|
||||
if !checkIP {
|
||||
return hostnameMap, nil
|
||||
}
|
||||
tmpHostname := NewHostname(curComment, curDomain, curIP)
|
||||
hostnameMap[tmpHostname.Domain] = tmpHostname
|
||||
|
||||
curComment = ""
|
||||
}
|
||||
|
||||
return hostnameMap, nil
|
||||
}
|
||||
|
||||
func (h *HostFile) AppendHost(domain string, ip string) {
|
||||
if domain == "" || ip == "" {
|
||||
return
|
||||
}
|
||||
|
||||
hostname := NewHostname("", domain, ip)
|
||||
appendToFile(getHostPath(), hostname)
|
||||
}
|
||||
|
||||
func (h *HostFile) writeToFile(hostnameMap map[string]*Hostname, path string) {
|
||||
if !FileExist(path) {
|
||||
logger.Warn("path %s is not exists", path)
|
||||
return
|
||||
}
|
||||
|
||||
fp, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
logger.Warn("open file '%s' failed: %v", path, err)
|
||||
return
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
for _, mapVal := range hostnameMap {
|
||||
_, writeErr := fp.WriteString(mapVal.toString())
|
||||
if writeErr != nil {
|
||||
logger.Warn(writeErr)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HostFile) DeleteDomain(domain string) {
|
||||
if domain == "" {
|
||||
return
|
||||
}
|
||||
|
||||
currHostsMap, parseErr := h.ParseHostFile(getHostPath())
|
||||
if parseErr != nil {
|
||||
logger.Warn("parse file failed" + parseErr.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if len(currHostsMap) == 0 || currHostsMap[domain] == nil {
|
||||
logger.Warn("domain %s not exist\n", domain)
|
||||
return
|
||||
}
|
||||
|
||||
delete(currHostsMap, domain)
|
||||
h.writeToFile(currHostsMap, getHostPath())
|
||||
}
|
||||
|
||||
func (h *HostFile) ListCurrentHosts() {
|
||||
currHostsMap, parseErr := h.ParseHostFile(getHostPath())
|
||||
if parseErr != nil {
|
||||
logger.Warn("parse file failed" + parseErr.Error())
|
||||
return
|
||||
}
|
||||
if len(currHostsMap) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
for _, mapVal := range currHostsMap {
|
||||
fmt.Println(mapVal.toString())
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@ func DownloadFile(location string) (filePATH, md5 string) {
|
||||
location = absPATH
|
||||
}
|
||||
//file md5
|
||||
md5 = FromLocal(location)
|
||||
md5 = Md5File(location)
|
||||
return location, md5
|
||||
}
|
||||
|
||||
|
||||
+28
-13
@@ -20,7 +20,7 @@ import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net"
|
||||
"os"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/fanux/sealos/pkg/utils/logger"
|
||||
@@ -87,24 +87,34 @@ func AssemblyIPList(args *string) error {
|
||||
*args = result
|
||||
return nil
|
||||
}
|
||||
func CheckIP(i string) bool {
|
||||
if !strings.Contains(i, ":") {
|
||||
return net.ParseIP(i) != nil
|
||||
}
|
||||
if _, err := net.ResolveTCPAddr("tcp", i); err != nil {
|
||||
func CheckIP(ipStr string) bool {
|
||||
host, _, err := net.SplitHostPort(ipStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
ip := net.ParseIP(host)
|
||||
if _, err = net.ResolveTCPAddr("tcp", ipStr); err != nil {
|
||||
return false
|
||||
}
|
||||
return ip != nil
|
||||
}
|
||||
|
||||
//IPFormat is
|
||||
func IPFormat(host string) string {
|
||||
ipAndPort := strings.Split(host, ":")
|
||||
if len(ipAndPort) != 2 {
|
||||
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22", host)
|
||||
os.Exit(1)
|
||||
func IPFormat(ipStr string) string {
|
||||
ip := net.ParseIP(ipStr)
|
||||
if ip == nil {
|
||||
host, _, err := net.SplitHostPort(ipStr)
|
||||
if err != nil {
|
||||
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22.error: %s", ipStr, err)
|
||||
return ""
|
||||
}
|
||||
ip = net.ParseIP(host)
|
||||
}
|
||||
return ipAndPort[0]
|
||||
if ip == nil {
|
||||
logger.Error("invalied host fomat [%s], must like 172.0.0.2:22", ipStr)
|
||||
return ""
|
||||
}
|
||||
return ip.String()
|
||||
}
|
||||
|
||||
func HostnameAndIP(node []string) ([]string, []string) {
|
||||
@@ -166,3 +176,8 @@ func RemoveDeduplicate(a []string) []string {
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func CheckDomain(domain string) bool {
|
||||
_, errURL := url.Parse(domain)
|
||||
return errURL == nil
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@ func (c *connLogger) Init(jsonConfig string) error {
|
||||
if len(jsonConfig) == 0 {
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("consoleWriter Init:%s\n", jsonConfig)
|
||||
err := json.Unmarshal([]byte(jsonConfig), c)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -16,7 +16,6 @@ package logger
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
@@ -59,7 +58,6 @@ func (c *consoleLogger) Init(jsonConfig string) error {
|
||||
if len(jsonConfig) == 0 {
|
||||
return nil
|
||||
}
|
||||
fmt.Printf("consoleWriter Init:%s\n", jsonConfig)
|
||||
err := json.Unmarshal([]byte(jsonConfig), c)
|
||||
if runtime.GOOS == "windows" {
|
||||
c.Colorful = false
|
||||
|
||||
@@ -153,7 +153,7 @@ func (r *LocalLogger) SetLogger(adapterName string, configs ...string) error {
|
||||
}
|
||||
|
||||
config := append(configs, "{}")[0]
|
||||
var num int = -1
|
||||
var num = -1
|
||||
var i int
|
||||
var l *nameLogger
|
||||
for i, l = range r.outputs {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright © 2021 Alibaba Group Holding Ltd.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Retry(tryTimes int, trySleepTime time.Duration, action func() error) error {
|
||||
var err error
|
||||
for i := 0; i < tryTimes; i++ {
|
||||
err = action()
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(trySleepTime * time.Duration(2*i+1))
|
||||
}
|
||||
return fmt.Errorf("retry action timeout: %v", err)
|
||||
}
|
||||
@@ -39,7 +39,7 @@ func (ss *SSH) CopyForMD5(host, localFilePath, remoteFilePath, md5 string) bool
|
||||
//如果有md5则可以验证
|
||||
//如果没有md5则拿到本地数据后验证
|
||||
if md5 == "" {
|
||||
md5 = utils.FromLocal(localFilePath)
|
||||
md5 = utils.Md5File(localFilePath)
|
||||
}
|
||||
logger.Debug("[ssh]source file md5 value is %s", md5)
|
||||
ss.Copy(host, localFilePath, remoteFilePath)
|
||||
@@ -362,7 +362,7 @@ func (ss *SSH) copyLocalFileToRemote(host string, sshClient *ssh.Client, sftpCli
|
||||
|
||||
func (ss *SSH) isCopyMd5Success(sshClient *ssh.Client, localFile, remoteFile string) bool {
|
||||
cmd := fmt.Sprintf("md5sum %s | cut -d\" \" -f1", remoteFile)
|
||||
localMd5 := utils.FromLocal(localFile)
|
||||
localMd5 := utils.Md5File(localFile)
|
||||
sshSession, err := sshClient.NewSession()
|
||||
if err != nil {
|
||||
return false
|
||||
@@ -399,7 +399,7 @@ func (ss *SSH) isCopyMd5Success(sshClient *ssh.Client, localFile, remoteFile str
|
||||
}
|
||||
|
||||
func (ss *SSH) ValidateMd5sumLocalWithRemote(host, localFile, remoteFile string) bool {
|
||||
localMd5 := utils.FromLocal(localFile)
|
||||
localMd5 := utils.Md5File(localFile)
|
||||
return localMd5 == ss.Md5Sum(host, remoteFile)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
|
||||
package ssh
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type SSH struct {
|
||||
User string
|
||||
|
||||
+12
-1
@@ -20,6 +20,7 @@ import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"net"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -110,7 +111,7 @@ func ContainList(list []string, toComplete string) (containerList []string) {
|
||||
|
||||
// RandString 生成随机字符串
|
||||
func RandString(len int) string {
|
||||
var r *rand.Rand = rand.New(rand.NewSource(time.Now().Unix()))
|
||||
var r = rand.New(rand.NewSource(time.Now().Unix()))
|
||||
bytes := make([]byte, len)
|
||||
for i := 0; i < len; i++ {
|
||||
b := r.Intn(26) + 65
|
||||
@@ -118,3 +119,13 @@ func RandString(len int) string {
|
||||
}
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
func IsEmptyLine(str string) bool {
|
||||
re := regexp.MustCompile(`^\s*$`)
|
||||
|
||||
return re.MatchString(str)
|
||||
}
|
||||
|
||||
func TrimWS(str string) string {
|
||||
return strings.Trim(str, " \n\t")
|
||||
}
|
||||
|
||||
@@ -108,3 +108,33 @@ func VersionToIntAll(version string) int {
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
//VersionCompare is version compare
|
||||
// if v1 >= v2 return true, else return false
|
||||
func VersionCompare(v1, v2 string) bool {
|
||||
v1 = strings.Replace(v1, "v", "", -1)
|
||||
v2 = strings.Replace(v2, "v", "", -1)
|
||||
v1 = strings.Split(v1, "-")[0]
|
||||
v2 = strings.Split(v2, "-")[0]
|
||||
v1List := strings.Split(v1, ".")
|
||||
v2List := strings.Split(v2, ".")
|
||||
|
||||
if len(v1List) != 3 || len(v2List) != 3 {
|
||||
logger.Error("error version format %s %s", v1, v2)
|
||||
return false
|
||||
}
|
||||
if v1List[0] > v2List[0] {
|
||||
return true
|
||||
} else if v1List[0] < v2List[0] {
|
||||
return false
|
||||
}
|
||||
if v1List[1] > v2List[1] {
|
||||
return true
|
||||
} else if v1List[1] < v2List[1] {
|
||||
return false
|
||||
}
|
||||
if v1List[2] > v2List[2] {
|
||||
return true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user