cdrdao no-disc ejection & --eject (#93)

* cdrdao: eject empty disc while reading toc

- introduce EjectError
- move {eject,load,unmount}_device to program.utils

* remove duplicated eject

* remove unnecessary ejection

* add --eject option
This commit is contained in:
Samantha Baldwin
2017-01-01 13:41:23 -05:00
committed by JoeLametta
parent 17021a68f2
commit a1eb3377ea
7 changed files with 83 additions and 47 deletions

View File

@@ -1,8 +1,9 @@
import os
import re
import tempfile
from subprocess import check_call, Popen, PIPE, CalledProcessError
from subprocess import Popen, PIPE
from morituri.common.common import EjectError
from morituri.image.toc import TocFile
import logging
@@ -27,12 +28,18 @@ def read_toc(device, fast_toc=False):
cmd = [CDRDAO, 'read-toc'] + (['--fast-toc'] if fast_toc else []) + [
'--device', device, tocfile]
# PIPE is the closest to >/dev/null we can get
try:
check_call(cmd, stdout=PIPE, stderr=PIPE)
except CalledProcessError, e:
logger.warning('cdrdao read-toc failed: return code is non-zero: ' +
str(e.returncode))
raise e
logger.debug("executing %r", cmd)
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
_, stderr = p.communicate()
if p.returncode != 0:
msg = 'cdrdao read-toc failed: return code is non-zero: ' + \
str(p.returncode)
logger.critical(msg)
# Gracefully handle missing disc
if "ERROR: Unit not ready, giving up." in stderr:
raise EjectError(device, "no disc detected")
raise IOError(msg)
toc = TocFile(tocfile)
toc.parse()
os.unlink(tocfile)

35
morituri/program/utils.py Normal file
View File

@@ -0,0 +1,35 @@
import os
import logging
logger = logging.getLogger(__name__)
def eject_device(device):
"""
Eject the given device.
"""
logger.debug("ejecting device %s", device)
os.system('eject %s' % device)
def load_device(device):
"""
Load the given device.
"""
logger.debug("loading (eject -t) device %s", device)
os.system('eject -t %s' % device)
def unmount_device(device):
"""
Unmount the given device if it is mounted, as happens with automounted
data tracks.
If the given device is a symlink, the target will be checked.
"""
device = os.path.realpath(device)
logger.debug('possibly unmount real path %r' % device)
proc = open('/proc/mounts').read()
if device in proc:
print 'Device %s is mounted, unmounting' % device
os.system('umount %s' % device)