go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/yum/yum.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package yum 5 6 // To support static analysis, we need to extend the current implementation: 7 // 8 // - read repo info from file system as is 9 // - read variables from file system as is 10 11 // https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-using_yum_variables 12 // /etc/yum.conf 13 // /etc/yum.repos.d/*.repo 14 15 // References: 16 // - https://unix.stackexchange.com/questions/19701/yum-how-can-i-view-variables-like-releasever-basearch-yum0 17 // - https://docs.centos.org/en-US/8-docs/managing-userspace-components/assembly_using-appstream/ 18 19 import ( 20 "bufio" 21 "encoding/json" 22 "io" 23 "regexp" 24 "strings" 25 ) 26 27 const ( 28 RhelYumRepoListCommand = "yum -v repolist all" 29 DnfVarsCommand = "%s -c 'import dnf, json; db = dnf.dnf.Base(); print(json.dumps(db.conf.substitutions))'" 30 PythonRhel = "/usr/libexec/platform-python" 31 Python3 = "python3" 32 Rhel6VarsCommand = "python -c 'import yum, json; yb = yum.YumBase(); print json.dumps(yb.conf.yumvar)'" 33 ) 34 35 type YumRepo struct { 36 Id string 37 Name string 38 Status string 39 Revision string 40 Updated string 41 Pkgs string 42 Size string 43 Mirrors string 44 Expire string 45 Filename string 46 Baseurl []string 47 Filter string 48 } 49 50 var ( 51 yumrepoline = regexp.MustCompile(`^\s*([^:\s]*)(?:\s)*:\s(.*)$`) 52 yumbaseurl = regexp.MustCompile(`^(.*?)(?:\(.*\))*$`) 53 ) 54 55 const ( 56 Id = "Repo-id" 57 Name = "Repo-name" 58 Status = "Repo-status" 59 Revision = "Repo-revision" 60 Updated = "Repo-updated" 61 Pkgs = "Repo-pkgs" 62 Size = "Repo-size" 63 Mirrors = "Repo-mirrors" 64 Baseurl = "Repo-baseurl" 65 Expire = "Repo-expire" 66 Filter = "Filter" 67 Filename = "Repo-filename" 68 ) 69 70 func ParseVariables(r io.Reader) (map[string]string, error) { 71 content, err := io.ReadAll(r) 72 if err != nil { 73 return nil, err 74 } 75 76 data := map[string]string{} 77 err = json.Unmarshal(content, &data) 78 if err != nil { 79 return nil, err 80 } 81 return data, nil 82 } 83 84 // Parses the output of yum -v repolist all 85 // It requires yum to be installed 86 func ParseRepos(r io.Reader) ([]*YumRepo, error) { 87 res := []*YumRepo{} 88 89 var entry *YumRepo 90 add := func(new *YumRepo) { 91 if entry == nil { 92 return 93 } 94 res = append(res, new) 95 } 96 scanner := bufio.NewScanner(r) 97 for scanner.Scan() { 98 line := scanner.Text() 99 m := yumrepoline.FindStringSubmatch(line) 100 if len(m) == 3 { 101 key := strings.TrimSpace(m[1]) 102 value := strings.TrimSpace(m[2]) 103 104 switch key { 105 case Id: 106 add(entry) 107 entry = &YumRepo{Id: value} 108 case Name: 109 entry.Name = value 110 case Status: 111 entry.Status = value 112 case Revision: 113 entry.Revision = value 114 case Updated: 115 entry.Updated = value 116 case Pkgs: 117 entry.Pkgs = value 118 case Size: 119 entry.Size = value 120 case Mirrors: 121 entry.Mirrors = value 122 case Baseurl: 123 // remove (0 more) 124 // split by , 125 m := yumbaseurl.FindStringSubmatch(value) 126 if m != nil && len(m) >= 2 { 127 entries := strings.Split(m[1], ",") 128 entry.Baseurl = []string{} 129 for i := range entries { 130 entry.Baseurl = append(entry.Baseurl, strings.TrimSpace(entries[i])) 131 } 132 } 133 case Expire: 134 entry.Expire = value 135 case Filter: 136 entry.Filter = value 137 case Filename: 138 entry.Filename = value 139 } 140 } 141 } 142 143 // add last entry 144 add(entry) 145 146 return res, nil 147 }