View Javadoc
1   package emissary.util.os;
2   
3   import org.apache.commons.exec.OS;
4   import org.apache.commons.lang3.StringUtils;
5   
6   import java.io.IOException;
7   import java.nio.file.Files;
8   import java.nio.file.Path;
9   import java.util.Optional;
10  import java.util.stream.Stream;
11  
12  public class OSReleaseUtil {
13  
14      private static final Path OS_RELEASE_PATH = Path.of("/etc/os-release");
15  
16      private OSReleaseUtil() {}
17  
18      /**
19       * Finds and parses the VERSION_ID entry in the /etc/os-release file
20       *
21       * @return the VERSION_ID value
22       */
23      public static String getVersionId() {
24          return getVersionId(OS_RELEASE_PATH);
25      }
26  
27      static String getVersionId(Path osReleasePath) {
28          String versionId = "UNKNOWN";
29  
30          if (Files.exists(osReleasePath)) {
31              try (Stream<String> lines = Files.lines(osReleasePath)) {
32                  Optional<String> versionIdOptional = lines.filter(line -> StringUtils.startsWith(line, "VERSION_ID")).findFirst();
33                  if (versionIdOptional.isPresent()) {
34                      String versionIdLine = versionIdOptional.get().replace("\"", "");
35                      versionId = versionIdLine.substring(versionIdLine.indexOf("=") + 1);
36                  }
37              } catch (Exception ignored) {
38                  // ignore
39              }
40          } else {
41              // fallback to the os.version system property for mac support
42              versionId = StringUtils.defaultIfBlank(System.getProperty("os.version"), versionId);
43          }
44          return versionId;
45      }
46  
47      /**
48       * Uses the VERSION_ID entry in the /etc/os-release file to determine the major OS version
49       *
50       * @return the major OS version
51       */
52      public static String getMajorReleaseVersion() {
53          return getMajorReleaseVersion(OS_RELEASE_PATH);
54      }
55  
56      static String getMajorReleaseVersion(Path osReleasePath) {
57          try {
58              return String.format("%.0f", Float.parseFloat(getVersionId(osReleasePath)));
59          } catch (NumberFormatException e) {
60              // support x.y.z format
61              return StringUtils.substringBefore(getVersionId(osReleasePath), ".");
62          }
63      }
64  
65      /**
66       * Use the /etc/os-release file to determine if the OS is Ubuntu
67       *
68       * @return true if ubuntu is found, false otherwise
69       */
70      public static boolean isUbuntu() {
71          return isUbuntu(OS_RELEASE_PATH);
72      }
73  
74      static boolean isUbuntu(Path osReleasePath) {
75          return isOsName(osReleasePath, "ubuntu") || isOsLike(osReleasePath, "ubuntu");
76      }
77  
78      /**
79       * Use the /etc/os-release file to determine if the OS is CentOS
80       *
81       * @return true if CentOS is found, false otherwise
82       */
83      public static boolean isCentOs() {
84          return isCentOs(OS_RELEASE_PATH);
85      }
86  
87      static boolean isCentOs(Path osReleasePath) {
88          return isOsName(osReleasePath, "centos");
89      }
90  
91      /**
92       * Use the /etc/os-release file to determine if the OS is RHEL
93       *
94       * @return true if RHEL is found, false otherwise
95       */
96      public static boolean isRhel() {
97          return isRhel(OS_RELEASE_PATH);
98      }
99  
100     static boolean isRhel(Path osReleasePath) {
101         return isOsName(osReleasePath, "rhel");
102     }
103 
104     /**
105      * Determine if the OS is macos
106      *
107      * @return true if mac, false otherwise
108      */
109     public static boolean isMac() {
110         return OS.isFamilyMac();
111     }
112 
113     // checks against ID in /etc/os-release
114     private static boolean isOsName(Path osReleasePath, String osName) {
115         if (Files.exists(osReleasePath)) {
116             try (Stream<String> lines = Files.lines(osReleasePath)) {
117                 return lines.filter(line -> line.startsWith("ID=")).anyMatch(entry -> StringUtils.containsIgnoreCase(entry, osName));
118             } catch (IOException ignored) {
119                 // ignore
120             }
121         }
122         return false;
123     }
124 
125     // checks against ID_LIKE in /etc/os-release
126     private static boolean isOsLike(Path osReleasePath, String osName) {
127         if (Files.exists(osReleasePath)) {
128             try (Stream<String> lines = Files.lines(osReleasePath)) {
129                 return lines.filter(line -> line.startsWith("ID_LIKE=")).anyMatch(entry -> StringUtils.containsIgnoreCase(entry, osName));
130             } catch (IOException ignored) {
131                 // ignore
132             }
133         }
134         return false;
135     }
136 }