in internal/guestcollector/linux_guestcollector.go [105:288]
func NewLinuxCollector(disks []*instanceinfo.Disks, ipAddr, username, privateKeyPath string, isRemote bool, port int32, usageMetricsLogger agentstatus.AgentStatus) *LinuxCollector {
c := LinuxCollector{
ipaddr: ipAddr,
username: username,
privateKeyPath: privateKeyPath,
disks: disks,
guestRuleCommandMap: map[string]commandExecutor{},
physicalDriveToDiskMap: map[string]string{},
lshwRegexMapping: map[string]*regexp.Regexp{},
remote: isRemote,
port: port,
usageMetricsLogger: usageMetricsLogger,
}
if c.remote {
c.remoteRunner = remote.NewRemote(c.ipaddr, c.username, c.port, c.usageMetricsLogger)
c.setUpRegex()
if err := c.remoteRunner.SetupKeys(c.privateKeyPath); err != nil {
log.Logger.Error(err)
c.usageMetricsLogger.Error(agentstatus.SetupSSHKeysError)
c.remoteRunner = nil
} else if err := c.remoteRunner.CreateClient(); err != nil {
log.Logger.Error(err)
c.usageMetricsLogger.Error(agentstatus.SSHDialError)
c.remoteRunner = nil
}
}
c.guestRuleCommandMap[internal.LocalSSDRule] = commandExecutor{
command: localSSDCommand,
isRule: false,
runCommand: func(ctx context.Context, command string) (string, error) {
// LocalSSDRule is collected differently, check DiskToDiskType method
return "", nil
},
runRemoteCommand: func(ctx context.Context, command string, r remote.Executor) (string, error) {
var isLinuxSuse bool
lshwResult, err := remote.RunCommandWithPipes(command, r)
if err != nil {
lshwResult, err = remote.RunCommandWithPipes(localSSDCommandForSuse, r)
if err != nil {
return "", err
}
log.Logger.Debugw("Fetched the disk info by using hwinfo.")
isLinuxSuse = true
}
var lshwFields lshwEntry
if !isLinuxSuse {
lshwFields, err = c.findLshwFields(lshwResult)
} else {
lshwFields, err = c.findHwinfoFields(lshwResult)
}
if err != nil {
return "", err
}
diskType := internal.Other.String()
if lshwFields.Product == persistentDisk {
diskType = internal.PersistentSSD.String()
} else if lshwFields.Product == ephemeralDisk && lshwFields.Size%402653184000 == 0 {
diskType = internal.LocalSSD.String()
}
c.physicalDriveToDiskMap[lshwFields.LogicalName] = diskType
res, errMar := json.Marshal(c.physicalDriveToDiskMap)
if errMar != nil {
return "", errMar
}
return string(res), nil
},
}
c.guestRuleCommandMap[internal.PowerProfileSettingRule] = commandExecutor{
command: powerPlanCommand,
isRule: true,
runCommand: func(ctx context.Context, command string) (string, error) {
res, err := internal.CommandLineExecutorWrapper(ctx, "/bin/sh", fmt.Sprintf(" -c '%s'", command), commandlineexecutor.ExecuteCommand)
if err != nil {
return "", fmt.Errorf("Check help docs, tuned package not installed or no power profile set. " + err.Error())
}
return findPowerProfile(res)
},
runRemoteCommand: func(ctx context.Context, command string, r remote.Executor) (string, error) {
s, err := r.CreateSession("")
if err != nil {
return "", err
}
defer s.Close()
res, err := r.Run(command, s)
if err != nil {
return "", fmt.Errorf("Check help docs, tuned package not installed or no power profile set. " + err.Error())
}
return findPowerProfile(res)
},
}
c.guestRuleCommandMap[internal.DataDiskAllocationUnitsRule] = commandExecutor{
command: dataDiskAllocationUnitsCommand,
isRule: true,
runCommand: func(ctx context.Context, command string) (string, error) {
if c.disks == nil || len(c.disks) == 0 {
return "", fmt.Errorf("data disk allocation failed. no disks found")
}
type resultEle struct {
BlockSize string
Caption string
}
var result []resultEle
for _, disk := range c.disks {
if disk.Mapping == "" {
continue
}
fullCommand := command + disk.Mapping
blockSize, err := internal.CommandLineExecutorWrapper(ctx, "/bin/sh", fmt.Sprintf(" -c '%s'", fullCommand), commandlineexecutor.ExecuteCommand)
if err != nil {
return "", err
}
result = append(result, resultEle{BlockSize: blockSize, Caption: disk.Mapping})
}
res, err := json.Marshal(result)
if err != nil {
return "", err
}
return string(res), nil
},
runRemoteCommand: func(ctx context.Context, command string, r remote.Executor) (string, error) {
if c.physicalDriveToDiskMap == nil || len(c.physicalDriveToDiskMap) == 0 {
return "", fmt.Errorf("data disk allocation failed. no disks found")
}
type resultEle struct {
BlockSize string
Caption string
}
var result []resultEle
for physicalDrive := range c.physicalDriveToDiskMap {
fullCommand := command + physicalDrive
s, err := r.CreateSession("")
if err != nil {
return "", err
}
blockSize, err := r.Run(fullCommand, s)
s.Close()
if err != nil || blockSize == "" {
blockSize = "unknown"
}
result = append(result, resultEle{BlockSize: blockSize, Caption: physicalDrive})
}
res, err := json.Marshal(result)
if err != nil {
return "", err
}
return string(res), nil
},
}
c.guestRuleCommandMap[internal.GCBDRAgentRunning] = commandExecutor{
command: gcbdrAgentRunningCommand,
isRule: true,
runCommand: func(ctx context.Context, command string) (string, error) {
res, err := internal.CommandLineExecutorWrapper(ctx, "/bin/sh", fmt.Sprintf(" -c '%s'", command), commandlineexecutor.ExecuteCommand)
if err != nil || res == "" {
return "false", nil
}
return c.gcbdrAgentRunning(res)
},
runRemoteCommand: func(ctx context.Context, command string, r remote.Executor) (string, error) {
s, err := r.CreateSession("")
if err != nil {
return "", err
}
defer s.Close()
res, err := r.Run(command, s)
if err != nil || res == "" {
return "false", nil
}
return c.gcbdrAgentRunning(res)
},
}
return &c
}