github.com/sealerio/sealer@v0.11.1-0.20240507115618-f4f89c5853ae/utils/ssh/platform.go (about) 1 // Copyright © 2022 Alibaba Group Holding Ltd. 2 // 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 package ssh 16 17 import ( 18 "bufio" 19 "fmt" 20 "net" 21 "strings" 22 23 v1 "github.com/sealerio/sealer/types/api/v1" 24 utilsnet "github.com/sealerio/sealer/utils/net" 25 "github.com/sealerio/sealer/utils/platform" 26 27 "github.com/pkg/errors" 28 "github.com/sirupsen/logrus" 29 ) 30 31 func (s *SSH) GetPlatform(host net.IP) (v1.Platform, error) { 32 if utilsnet.IsLocalIP(host, s.LocalAddress) { 33 return platform.GetDefaultPlatform(), nil 34 } 35 36 p := v1.Platform{} 37 archResult, err := s.CmdToString(host, nil, "uname -m", "") 38 if err != nil { 39 return p, err 40 } 41 osResult, err := s.CmdToString(host, nil, "uname", "") 42 if err != nil { 43 return p, err 44 } 45 p.OS = strings.ToLower(strings.TrimSpace(osResult)) 46 switch strings.ToLower(strings.TrimSpace(archResult)) { 47 case "x86_64": 48 p.Architecture = platform.AMD 49 case "aarch64": 50 p.Architecture = platform.ARM64 51 case "armv7l": 52 p.Architecture = "arm-v7" 53 case "armv6l": 54 p.Architecture = "arm-v6" 55 default: 56 return p, fmt.Errorf("unrecognized architecture: %s", archResult) 57 } 58 if p.Architecture != platform.AMD { 59 p.Variant, err = s.getCPUVariant(p.OS, p.Architecture, host) 60 if err != nil { 61 return p, err 62 } 63 } 64 remotePlatform, err := platform.Parse(platform.Format(p)) 65 if err != nil { 66 return p, err 67 } 68 return platform.Normalize(remotePlatform), nil 69 } 70 71 func (s *SSH) getCPUInfo(host net.IP, pattern string) (info string, err error) { 72 sftpClient, err := s.sftpConnect(host) 73 if err != nil { 74 return "", fmt.Errorf("failed to new sftp client: %v", err) 75 } 76 77 // open remote source file 78 srcFile, err := sftpClient.Open("/proc/cpuinfo") 79 if err != nil { 80 return "", fmt.Errorf("failed to open /proc/cpuinfo: %v", err) 81 } 82 defer func() { 83 if err := srcFile.Close(); err != nil { 84 logrus.Warnf("failed to close file: %v", err) 85 } 86 }() 87 scanner := bufio.NewScanner(srcFile) 88 for scanner.Scan() { 89 newline := scanner.Text() 90 list := strings.Split(newline, ":") 91 92 if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { 93 return strings.TrimSpace(list[1]), nil 94 } 95 } 96 // Check whether the scanner encountered errors 97 err = scanner.Err() 98 if err != nil { 99 return "", err 100 } 101 return "", errors.Wrapf(platform.ErrNotFound, "getCPUInfo for pattern: %s", pattern) 102 } 103 104 func (s *SSH) getCPUVariant(os, arch string, host net.IP) (string, error) { 105 variant, err := s.getCPUInfo(host, "Cpu architecture") 106 if err != nil { 107 return "", err 108 } 109 model, err := s.getCPUInfo(host, "model name") 110 if err != nil { 111 if !strings.Contains(err.Error(), platform.ErrNotFound.Error()) { 112 return "", err 113 } 114 } 115 variant, model = platform.NormalizeArch(variant, model) 116 return platform.GetCPUVariantByInfo(os, arch, variant, model), nil 117 }