go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/detector/platform_resolver.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package detector 5 6 import ( 7 "github.com/rs/zerolog/log" 8 "go.mondoo.com/cnquery/providers-sdk/v1/inventory" 9 "go.mondoo.com/cnquery/providers/os/connection" 10 "go.mondoo.com/cnquery/providers/os/connection/shared" 11 ) 12 13 type detect func(r *PlatformResolver, pf *inventory.Platform, conn shared.Connection) (bool, error) 14 15 type PlatformResolver struct { 16 Name string 17 IsFamily bool 18 Children []*PlatformResolver 19 Detect detect 20 } 21 22 func (r *PlatformResolver) Resolve(conn shared.Connection) (*inventory.Platform, bool) { 23 // prepare detect info object 24 di := &inventory.Platform{} 25 di.Family = make([]string, 0) 26 27 // start recursive platform resolution 28 pi, resolved := r.resolvePlatform(di, conn) 29 30 // if we have a container image use the architecture specified in the transport as it is resolved 31 // using the container image properties 32 tarConn, ok := conn.(*connection.TarConnection) 33 if resolved && ok { 34 pi.Arch = tarConn.PlatformArchitecture 35 di.Runtime = "docker-image" 36 di.Kind = "container-image" 37 38 // if the platform name is not set, we should fallback to the scratch operating system 39 if len(pi.Name) == 0 { 40 di.Name = "scratch" 41 di.Arch = tarConn.PlatformArchitecture 42 return di, true 43 } 44 } 45 46 containerConn, ok := conn.(*connection.DockerContainerConnection) 47 if resolved && ok { 48 pi.Arch = containerConn.PlatformArchitecture 49 di.Runtime = string(containerConn.Type()) 50 di.Kind = "container" 51 52 // if the platform name is not set, we should fallback to the scratch operating system 53 if len(pi.Name) == 0 { 54 di.Name = "scratch" 55 di.Arch = pi.Arch 56 return di, true 57 } 58 } 59 60 log.Debug().Str("platform", pi.Name).Strs("family", pi.Family).Msg("platform> detected os") 61 return pi, resolved 62 } 63 64 // Resolve tries to find recursively all 65 // platforms until a leaf (operating systems) detect 66 // mechanism is returning true 67 func (r *PlatformResolver) resolvePlatform(pf *inventory.Platform, conn shared.Connection) (*inventory.Platform, bool) { 68 detected, err := r.Detect(r, pf, conn) 69 if err != nil { 70 return pf, false 71 } 72 73 // if detection is true but we have a family 74 if detected == true && r.IsFamily == true { 75 // we are a family and we may have children to try 76 for _, c := range r.Children { 77 detected, resolved := c.resolvePlatform(pf, conn) 78 if resolved { 79 // add family hieracy 80 detected.Family = append(pf.Family, r.Name) 81 return detected, resolved 82 } 83 } 84 85 // we reached this point, we know it is the platfrom but we could not 86 // identify the system 87 // TODO: add generic platform instance 88 // TODO: should we return an error? 89 } 90 91 // return if the detect is true and we have a leaf 92 if detected && r.IsFamily == false { 93 return pf, true 94 } 95 96 // could not find it 97 return pf, false 98 }