add infra module (#754)

* hotfix(master): add infra module
This commit is contained in:
cuisongliu
2021-12-19 18:38:03 +08:00
committed by GitHub
parent 5fde3d32f7
commit 905ceada4d
83 changed files with 2685 additions and 628 deletions
+6 -10
View File
@@ -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
}
+195
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
-1
View File
@@ -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
-2
View File
@@ -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
+1 -1
View File
@@ -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 {
+33
View File
@@ -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)
}
+3 -3
View File
@@ -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)
}
+3 -1
View File
@@ -14,7 +14,9 @@
package ssh
import "time"
import (
"time"
)
type SSH struct {
User string
+12 -1
View File
@@ -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")
}
+30
View File
@@ -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
}