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