github.com/google/osv-scalibr@v0.4.1/detector/endoflife/linuxdistro/ubuntu.go (about) 1 // Copyright 2025 Google LLC 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 linuxdistro 16 17 import ( 18 "bufio" 19 "time" 20 21 scalibrfs "github.com/google/osv-scalibr/fs" 22 ) 23 24 type ubuntuReleaseSupport struct { 25 standard time.Time 26 pro time.Time 27 legacy time.Time 28 } 29 30 func rdate(year int, month time.Month) time.Time { 31 return time.Date(year, month, 1, 0, 0, 0, 0, time.UTC) 32 } 33 34 // From https://ubuntu.com/about/release-cycle 35 var ubuntuReleases = map[string]ubuntuReleaseSupport{ 36 "25.04": { 37 standard: rdate(2026, time.January), 38 pro: time.Time{}, 39 legacy: time.Time{}, 40 }, 41 "24.10": { 42 standard: rdate(2025, time.July), 43 pro: time.Time{}, 44 legacy: time.Time{}, 45 }, 46 "24.04": { 47 standard: rdate(2029, time.April), 48 pro: rdate(2034, time.April), 49 legacy: rdate(2036, time.April), 50 }, 51 "22.04": { 52 standard: rdate(2027, time.April), 53 pro: rdate(2032, time.April), 54 legacy: rdate(2034, time.April), 55 }, 56 "20.04": { 57 standard: rdate(2025, time.May), 58 pro: rdate(2030, time.April), 59 legacy: rdate(2032, time.April), 60 }, 61 "18.04": { 62 standard: rdate(2023, time.May), 63 pro: rdate(2028, time.April), 64 legacy: rdate(2030, time.April), 65 }, 66 "16.04": { 67 standard: rdate(2021, time.April), 68 pro: rdate(2026, time.April), 69 legacy: rdate(2028, time.April), 70 }, 71 "14.04": { 72 standard: rdate(2019, time.April), 73 pro: rdate(2024, time.April), 74 legacy: rdate(2026, time.April), 75 }, 76 } 77 78 // See https://ubuntu.com/about/release-cycle 79 func ubuntuEOL(osRelease map[string]string, fs scalibrfs.FS) bool { 80 id, ok := osRelease["VERSION_ID"] 81 if !ok { 82 return false 83 } 84 if release, ok := ubuntuReleases[id]; ok { 85 if isUbuntuLegacy(fs) { 86 return release.legacy.Before(now()) 87 } 88 if isUbuntuPro(fs) { 89 return release.pro.Before(now()) 90 } 91 return release.standard.Before(now()) 92 } 93 return false 94 } 95 96 func isUbuntuPro(fs scalibrfs.FS) bool { 97 // We could also check '/var/lib/ubuntu-advantage/status.json' 98 f, err := fs.Open("/etc/apt/sources.list.d/ubuntu-esm-infra.sources") 99 if err != nil { 100 return false 101 } 102 defer f.Close() 103 scanner := bufio.NewScanner(f) 104 if scanner.Scan() { 105 return scanner.Text() == "# Written by ubuntu-pro-client" 106 } 107 return false 108 } 109 110 func isUbuntuLegacy(fs scalibrfs.FS) bool { 111 // TODO(#889): Implement. 112 return false 113 }