go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/packages/packages.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package packages 5 6 import ( 7 "github.com/cockroachdb/errors" 8 "go.mondoo.com/cnquery/providers/os/connection/shared" 9 ) 10 11 type Package struct { 12 Name string `json:"name"` 13 Version string `json:"version"` 14 Arch string `json:"arch"` 15 Status string `json:"status,omitempty"` 16 Description string `json:"description"` 17 18 // this may be the source package or an origin 19 // e.g. on alpine it is used for parent packages 20 // o Package Origin - https://wiki.alpinelinux.org/wiki/Apk_spec 21 Origin string `json:"origin"` 22 Format string `json:"format"` 23 } 24 25 // extends Package to store available version 26 type PackageUpdate struct { 27 Name string `json:"name"` 28 Version string `json:"version"` 29 Arch string `json:"arch"` 30 Available string `json:"available"` 31 Repo string `json:"repo"` 32 } 33 34 type OperatingSystemPkgManager interface { 35 Name() string 36 List() ([]Package, error) 37 Available() (map[string]PackageUpdate, error) 38 } 39 40 // this will find the right package manager for the operating system 41 func ResolveSystemPkgManager(conn shared.Connection) (OperatingSystemPkgManager, error) { 42 var pm OperatingSystemPkgManager 43 44 asset := conn.Asset() 45 if asset == nil || asset.Platform == nil { 46 return nil, errors.New("cannot find OS information for package detection") 47 } 48 49 switch { 50 case asset.Platform.IsFamily("arch"): // arch family 51 pm = &PacmanPkgManager{conn: conn} 52 case asset.Platform.IsFamily("debian"): // debian family 53 pm = &DebPkgManager{conn: conn} 54 case asset.Platform.Name == "amazonlinux" || asset.Platform.Name == "photon" || asset.Platform.Name == "wrlinux": 55 fallthrough 56 case asset.Platform.IsFamily("redhat"): // rhel family 57 pm = &RpmPkgManager{conn: conn, platform: asset.Platform} 58 case asset.Platform.IsFamily("suse"): // suse handling 59 pm = &SusePkgManager{RpmPkgManager{conn: conn, platform: asset.Platform}} 60 case asset.Platform.Name == "alpine": // alpine 61 pm = &AlpinePkgManager{conn: conn} 62 case asset.Platform.Name == "macos": // mac os family 63 pm = &MacOSPkgManager{conn: conn} 64 case asset.Platform.Name == "windows": 65 pm = &WinPkgManager{conn: conn, platform: asset.Platform} 66 case asset.Platform.Name == "scratch" || asset.Platform.Name == "coreos": 67 pm = &ScratchPkgManager{conn: conn} 68 case asset.Platform.Name == "openwrt": 69 pm = &OpkgPkgManager{conn: conn} 70 case asset.Platform.Name == "solaris": 71 pm = &SolarisPkgManager{conn: conn} 72 case asset.Platform.Name == "cos": 73 pm = &CosPkgManager{conn: conn} 74 case asset.Platform.Name == "freebsd": 75 pm = &FreeBSDPkgManager{conn: conn} 76 case asset.Platform.Name == "aix": 77 pm = &AixPkgManager{conn: conn} 78 case asset.Platform.IsFamily("linux"): 79 // no clear package manager for linux platform found 80 // most likely we land here if we have a yocto-based system 81 opkgPaths := []string{"/bin/opkg", "/usr/bin/opkg"} 82 for i := range opkgPaths { 83 if _, err := conn.FileSystem().Stat(opkgPaths[i]); err == nil { 84 pm = &OpkgPkgManager{conn: conn} 85 break 86 } 87 } 88 } 89 90 if pm == nil { 91 return nil, errors.New("could not detect suitable package manager for platform: " + asset.Platform.Name) 92 } 93 94 return pm, nil 95 }