Package roslib :: Module os_detect
[frames] | no frames]

Source Code for Module roslib.os_detect

  1  #!/usr/bin/env python 
  2  # Copyright (c) 2009, Willow Garage, Inc. 
  3  # All rights reserved. 
  4  #  
  5  # Redistribution and use in source and binary forms, with or without 
  6  # modification, are permitted provided that the following conditions are met: 
  7  #  
  8  #     * Redistributions of source code must retain the above copyright 
  9  #       notice, this list of conditions and the following disclaimer. 
 10  #     * Redistributions in binary form must reproduce the above copyright 
 11  #       notice, this list of conditions and the following disclaimer in the 
 12  #       documentation and/or other materials provided with the distribution. 
 13  #     * Neither the name of the Willow Garage, Inc. nor the names of its 
 14  #       contributors may be used to endorse or promote products derived from 
 15  #       this software without specific prior written permission. 
 16  #  
 17  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 18  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 19  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 20  # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 21  # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 22  # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 23  # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 24  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 25  # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 26  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 27  # POSSIBILITY OF SUCH DAMAGE. 
 28   
 29  # Author Tully Foote/tfoote@willowgarage.com 
 30   
 31  """ 
 32  Library for detecting the current OS, including detecting specific 
 33  Linux distributions.  
 34   
 35  The APIs of this library are still very coupled with the rosdep  
 36  command-line tool. 
 37  """ 
 38   
 39  from __future__ import with_statement 
 40   
 41  import roslib.exceptions 
 42  import roslib.rospack 
 43  import roslib.stacks 
 44  import os 
 45  import sys 
 46  import subprocess 
 47  import types 
 48  import tempfile 
 49  import yaml 
 50   
 51  ####### Linux Helper Functions ##### 
52 -def lsb_get_os():
53 """ 54 Linux: wrapper around lsb_release to get the current OS 55 """ 56 try: 57 cmd = ['lsb_release', '-si'] 58 pop = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 59 (std_out, std_err) = pop.communicate() 60 return std_out.strip() 61 except: 62 return None
63
64 -def lsb_get_codename():
65 """ 66 Linux: wrapper around lsb_release to get the current OS codename 67 """ 68 try: 69 cmd = ['lsb_release', '-sc'] 70 pop = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 71 (std_out, std_err) = pop.communicate() 72 return std_out.strip() 73 except: 74 return None
75
76 -def lsb_get_version():
77 """ 78 Linux: wrapper around lsb_release to get the current OS version 79 """ 80 try: 81 cmd = ['lsb_release', '-sr'] 82 pop = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 83 (std_out, std_err) = pop.communicate() 84 return std_out.strip() 85 except: 86 return None
87 88 #### Override class for debugging and unsupported OSs ###########
89 -class OSOverride:
90 - def __init__(self):
91 self._os_name = "uninitialized from ROS_OS_OVERRIDE=name:version" 92 self._os_version = "uninitialized from ROS_OS_OVERRIDE=name:version"
93
94 - def check_presence(self):
95 try: 96 (self._os_name, self._os_version) = os.environ["ROS_OS_OVERRIDE"].split(':') 97 print >> sys.stderr, "Using environment variable ROS_OS_OVERRIDE name = %s version = %s"%(self._os_name, self._os_version) 98 return True 99 except: 100 return False
101
102 - def get_version(self):
103 return self._os_version
104
105 - def get_name(self):
106 return self._os_name
107 108
109 -class OSDetectException(roslib.exceptions.ROSLibException): pass
110
111 -class OSBase:
112 """ 113 This defines the API used for OS detection within the os_detect 114 module for roslib. All OS specific instantiantions must inherit 115 and override these methods. 116 """
117 - def check_presence(self):
118 """ 119 Return if the specific OS which this class is designed to 120 detect is present. Only one version of this class should return for 121 any version. 122 """ 123 raise OSDetectException("check_presence unimplemented")
124
125 - def get_name(self):
126 """ 127 Return the standardized name for this OS. (ala Ubuntu Hardy Heron = "ubuntu") 128 """ 129 raise OSDetectException("get_name unimplemented")
130
131 - def get_version(self):
132 """ 133 Return the standardized version for this OS. (ala Ubuntu Hardy Heron = "8.04") 134 """ 135 raise OSDetectException("get_version unimplemented")
136 137 138 ###### Debian SPECIALIZATION #########################
139 -class Debian(OSBase):
140 """ 141 Detect Debian OS. 142 """
143 - def check_presence(self):
144 if "Debian" == lsb_get_os(): 145 return True 146 return False
147
148 - def get_version(self):
149 return lsb_get_codename()
150 - def get_name(self):
151 return "debian"
152 153 ###### END Debian SPECIALIZATION ######################## 154 155 156 ###### UBUNTU SPECIALIZATION #########################
157 -class Ubuntu(Debian):
158 """ This is an implementation of a standard interface for 159 interacting with rosdep. This defines all Ubuntu sepecific 160 methods, including detecting the OS/Version number. As well as 161 how to check for and install packages."""
162 - def check_presence(self):
163 if "Ubuntu" == lsb_get_os(): 164 return True 165 return False
166
167 - def get_version(self):
168 return lsb_get_version()
169 - def get_name(self):
170 return "ubuntu"
171 172 ###### END UBUNTU SPECIALIZATION ######################## 173 174 ###### Mint SPECIALIZATION #########################
175 -class Mint(OSBase):
176 """ 177 Detect Mint variants of Debian. 178 """
179 - def check_presence(self):
180 if "LinuxMint" == lsb_get_os(): 181 return True 182 return False
183
184 - def get_version(self):
185 return lsb_get_version()
186
187 - def get_name(self):
188 return "mint"
189 ###### END Mint SPECIALIZATION ######################## 190 191 ###### OpenSuse SPECIALIZATION #########################
192 -class OpenSuse(OSBase):
193 """ 194 Detect OpenSuse OS. 195 """
196 - def check_presence(self):
197 try: 198 filename = "/etc/SuSE-brand" 199 if os.path.exists(filename): 200 with open(filename, 'r') as fh: 201 os_list = fh.read().split() 202 if len(os_list) > 0 and os_list[0] == "openSUSE": 203 return True 204 except: 205 pass 206 return False
207
208 - def get_version(self):
209 try: 210 filename = "/etc/SuSE-brand" 211 if os.path.exists(filename): 212 with open(filename, 'r') as fh: 213 os_list = fh.read().strip().split('\n') 214 if len(os_list) == 2: 215 os_list = os_list[1].split(' = ') 216 if os_list[0] == "VERSION": 217 return os_list[1] 218 except: 219 return False 220 221 return False
222
223 - def get_name(self):
224 return "opensuse"
225 226 ###### END OpenSuse SPECIALIZATION ######################## 227 228 229 ###### Fedora SPECIALIZATION #########################
230 -class Fedora(OSBase):
231 """ 232 Detect Fedora OS. 233 """
234 - def check_presence(self):
235 try: 236 filename = "/etc/redhat-release" 237 if os.path.exists(filename): 238 with open(filename, 'r') as fh: 239 os_list = fh.read().split() 240 if os_list and os_list[0] == "Fedora" and os_list[1] == "release": 241 return True 242 except: 243 pass 244 return False
245
246 - def get_version(self):
247 try: 248 filename = "/etc/issue" 249 if os.path.exists(filename): 250 with open(filename, 'r') as fh: 251 os_list = fh.read().split() 252 if os_list[0] == "Fedora" and os_list[1] == "release": 253 return os_list[2] 254 except: 255 print "Fedora failed to get version" 256 return False 257 258 return False
259
260 - def get_name(self):
261 return "fedora"
262 263 ###### END Fedora SPECIALIZATION ######################## 264 265 ###### Rhel SPECIALIZATION #########################
266 -class Rhel(Fedora):
267 """ 268 Detect Redhat OS. 269 """
270 - def check_presence(self):
271 try: 272 filename = "/etc/redhat-release" 273 if os.path.exists(filename): 274 with open(filename, 'r') as fh: 275 os_list = fh.read().split() 276 if os_list and os_list[2] == "Enterprise": 277 return True 278 except: 279 pass 280 return False
281
282 - def get_version(self):
283 try: 284 filename = "/etc/issue" 285 if os.path.exists(filename): 286 with open(filename, 'r') as fh: 287 os_list = fh.read().split() 288 if os_list and os_list[2] == "Enterprise": 289 return os_list[6] 290 except: 291 print "Rhel failed to get version" 292 return False 293 294 return False
295
296 - def get_name(self):
297 return "rhel"
298 299 ###### END Rhel SPECIALIZATION ######################## 300 301 ###### Macports SPECIALIZATION #########################
302 -def port_detect(p):
303 """ 304 Detect presence of Macports by running "port installed" command. 305 """ 306 cmd = ['port', 'installed', p] 307 pop = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 308 (std_out, std_err) = pop.communicate() 309 310 return (std_out.count("(active)") > 0)
311
312 -class Macports(OSBase):
313 """ 314 Detect OS X and Macports. 315 """
316 - def check_presence(self):
317 filename = "/usr/bin/sw_vers" 318 if os.path.exists(filename): 319 return True 320 return False
321
322 - def get_version(self):
323 return "macports" # macports is a rolling release and isn't versionsed
324
325 - def get_name(self):
326 return "macports"
327 328 ###### END Macports SPECIALIZATION ######################## 329 330 ###### Arch SPECIALIZATION #########################
331 -class Arch(OSBase):
332 """ 333 Detect Arch Linux. 334 """ 335
336 - def check_presence(self):
337 filename = "/etc/arch-release" 338 if os.path.exists(filename): 339 return True 340 return False
341
342 - def get_version(self):
343 return "" 344 # arch didn't have a version parsing in cpp version 345 try: 346 filename = "/etc/issue" 347 if os.path.exists(filename): 348 with open(filename, 'r') as fh: 349 os_list = fh.read().split() 350 if os_list[0] == "Linux" and os_list[1] == "Arch": 351 return os_list[2] 352 except: 353 print "Arch failed to get version" 354 return False 355 356 return False
357
358 - def get_name(self):
359 return "arch"
360 361 ###### END Arch SPECIALIZATION ######################## 362 363 364 ###### Cygwin SPECIALIZATION #########################
365 -class Cygwin(OSBase):
366 """ 367 Detect Cygwin presence on Windows OS. 368 """
369 - def check_presence(self):
370 filename = "/usr/bin/cygwin1.dll" 371 if os.path.exists(filename): 372 return True 373 return False
374
375 - def get_version(self):
376 cmd = ['uname','-r']; 377 pop = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 378 (std_out, std_err) = pop.communicate() 379 return std_out.strip()
380
381 - def get_name(self):
382 return "cygwin"
383 384 ###### END Cygwin SPECIALIZATION ######################## 385 386 ###### Gentoo Sepcialization ###############################
387 -class Gentoo(OSBase):
388 """ 389 Detect Gentoo OS. 390 """
391 - def check_presence(self):
392 try: 393 filename = "/etc/gentoo-release" 394 if os.path.exists(filename): 395 with open(filename, 'r') as fh: 396 os_list = fh.read().split() 397 if os_list and os_list[0] == "Gentoo" and os_list[1] == "Base": 398 return True 399 except: 400 pass#print >> sys.stderr, "Gentoo failed to detect OS" 401 return False
402
403 - def get_version(self):
404 try: 405 filename = "/etc/gentoo-release" 406 if os.path.exists(filename): 407 with open(filename, 'r') as fh: 408 os_list = fh.read().split() 409 if os_list[0] == "Gentoo" and os_list[1] == "Base": 410 return os_list[4] 411 except: 412 print >> sys.stderr, "Gentoo failed to get version" 413 return False 414 415 return False
416
417 - def get_name(self):
418 return "gentoo"
419 420 ###### END Gentoo Sepcialization ############################### 421 422 ###### FreeBSD SPECIALIZATION #########################
423 -class FreeBSD(OSBase):
424 """ 425 Detect FreeBSD OS. 426 """
427 - def check_presence(self):
428 try: 429 filename = "/usr/bin/uname" 430 if os.path.exists(filename): 431 pop = subprocess.Popen([filename], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 432 (std_out, std_err) = pop.communicate() 433 if std_out.strip() == "FreeBSD": 434 return True 435 else: 436 return False 437 except: 438 pass#print >> sys.stderr, "FreeBSD failed to detect OS" 439 return False
440
441 - def get_version(self):
442 try: 443 filename = "/usr/bin/uname" 444 if os.path.exists(filename): 445 pop = subprocess.Popen([filename, "-r"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 446 (std_out, std_err) = pop.communicate() 447 return std_out.strip() 448 else: 449 return False 450 except: 451 print >> sys.stderr, "FreeBSD failed to get version" 452 return False 453 454 return False
455
456 - def get_name(self):
457 return "freebsd"
458 459 ###### FreeBSD SPECIALIZATION ######################### 460 461 462 463 464 465
466 -class OSDetect:
467 """ This class will iterate over registered classes to lookup the 468 active OS and version"""
469 - def __init__(self, os_list = [Debian(), Ubuntu(), Mint(), Macports(), Arch(), OpenSuse(), Fedora(), Rhel(), Gentoo(), Cygwin(), FreeBSD()]):
470 self._os_list = os_list 471 for o in self._os_list: 472 if not isinstance(o, OSBase): 473 raise OSDetectException("Class [%s] not derived from OSBase"%o.__class__.__name__) 474 475 self._os_class = None 476 self._os_name = None 477 self._os_version = None 478 479 self.detect_os()
480
481 - def add_os(self, class_ref):
482 self._os_list.append(class_ref)
483 484 # \TODO look at throwing here
485 - def detect_os(self):
486 override = OSOverride() 487 if override.check_presence(): 488 for os_class in self._os_list: 489 if os_class.get_name() == override.get_name(): 490 self._os_name = override.get_name() 491 self._os_version = override.get_version() 492 self._os_class = os_class 493 return True 494 495 for os_class in self._os_list: 496 if os_class.check_presence(): 497 self._os_name = os_class.get_name() 498 self._os_version = os_class.get_version() 499 self._os_class = os_class 500 return True 501 502 # No solution found 503 attempted_oss = [o.get_name() for o in self._os_list] 504 raise OSDetectException("Could not detect OS, tried %s"%attempted_oss) 505 return False
506
507 - def get_os(self):
508 if not self._os_class: 509 self.detect_os() 510 return self._os_class
511
512 - def get_name(self):
513 if not self._os_name: 514 self.detect_os() 515 return self._os_name
516
517 - def get_version(self):
518 if not self._os_version: 519 not self.detect_os() 520 return self._os_version
521