예제 #1
0
    def __init__(self, events_in, request):
        self.events_in = events_in
        self.request = request

        self.parent = request.parent
        self.part = request.part
        self.partspec = request.partspec

        self.tools = DBusTools()
예제 #2
0
    def __init__(self, events_in):
        self.events_in = events_in

        DBusGMainLoop(set_as_default=True)

        self.systembus = dbus.SystemBus()
        self.systembus.add_signal_receiver(
            self.handler,
            dbus_interface="org.freedesktop.UDisks",
            path="/org/freedesktop/UDisks",
            sender_keyword="sender",
            destination_keyword="dest",
            interface_keyword="iface",
            member_keyword="member",
            path_keyword="path")

        # Assure the UDisks service runs
        self.tools = DBusTools()
        self.tools.get_device("/org/freedesktop/UDisks")

        self.drives = dict()
예제 #3
0
class FullDriveWriter:
    def __init__(self, events_in, request):
        self.events_in = events_in
        self.request = request

        self.drive = request.drive
        self.tools = DBusTools()

    def run(self):
        logging.info(_("FullDriveWriter starting {0}...").format(self.drive))
        self.events_in.put(
            StatusUpdate(
                self.drive, None, None, None,
                _("About to write an image on {0}...").format(self.drive)))

        try:
            cmd = [
                "dd", "bs=8M", "conv=fsync",
                "if={0}".format(self.request.config.fulldriveimage),
                "of={0}".format(self.tools.get_device_filename(self.drive))
            ]
            logging.debug(_("Executing copy command {0}...").format(cmd))
            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            for line in output.split('\n'):
                logging.debug(_("Command output: {0}").format(line))
        except subprocess.CalledProcessError as e:
            for line in e.output.split('\n'):
                logging.error(_("Command output: {0}").format(line))
            logging.error(_("Error executing copy command: {0}").format(e))
            self.events_in.put(
                StatusUpdate(
                    self.drive, DriveStatus.DRIVE_ERROR_DRV, None, None,
                    _("Error while writing image to {0}!").format(self.drive)))
            return

        return FullDriveDone(self.drive)
예제 #4
0
class DBusHandler:
    def __init__(self, events_in):
        self.events_in = events_in

        DBusGMainLoop(set_as_default=True)

        self.systembus = dbus.SystemBus()
        self.systembus.add_signal_receiver(
            self.handler,
            dbus_interface="org.freedesktop.UDisks",
            path="/org/freedesktop/UDisks",
            sender_keyword="sender",
            destination_keyword="dest",
            interface_keyword="iface",
            member_keyword="member",
            path_keyword="path")

        # Assure the UDisks service runs
        self.tools = DBusTools()
        self.tools.get_device("/org/freedesktop/UDisks")

        self.drives = dict()

    def handler(self, *args, **kwargs):
        member = kwargs['member']

        if len(args) >= 1:
            path = args[0]
        else:
            return

        if member == "DeviceAdded" and \
           self.tools.is_drive(path) and \
           self.tools.get_conn_interface(path) == "usb":
            driveid = self.tools.get_drive_id(path)
            port = self.tools.get_port(path)
            size = self.tools.get_device_size(path)
            logging.info(
                _("New drive {0} {1} (size={2}).").format(path, driveid, size))
            if size != 0:
                self.events_in.put(DriveAdded(path, port))
            self.drives[path] = size

        if member == "DeviceChanged" and \
           self.tools.is_drive(path) and \
           self.tools.get_conn_interface(path) == "usb":
            driveid = self.tools.get_drive_id(path)
            port = self.tools.get_port(path)
            size = self.tools.get_device_size(path)
            logging.info(
                _("Drive {0} {1} changed (size={2}).").format(
                    path, driveid, size))
            if path in self.drives and self.drives[path] == 0 and size != 0:
                self.events_in.put(DriveAdded(path, port))
            if path in self.drives and size == 0:
                self.events_in.put(DeviceRemoved(path))
            self.drives[path] = size

        if member == "DeviceAdded" and self.tools.is_partition(path):
            logging.debug(_("New partition {0}.").format(path))
            self.events_in.put(
                PartitionAdded(self.tools.get_parent(path), path))
        if member == "DeviceRemoved":
            logging.debug(_("Removed device {0}.").format(path))
            try:
                del self.drives[path]
            except KeyError:
                pass
            self.events_in.put(DeviceRemoved(path))
예제 #5
0
    def __init__(self, events_in, request):
        self.events_in = events_in
        self.request = request

        self.drive = request.drive
        self.tools = DBusTools()
예제 #6
0
class MBRWriter:
    def __init__(self, events_in, request):
        self.events_in = events_in
        self.request = request

        self.drive = request.drive
        self.tools = DBusTools()

    def run(self):
        # Creating MBR...
        logging.info(_("Creating MBR for {0}...").format(self.drive))
        self.events_in.put(
            StatusUpdate(self.drive, None, None, None,
                         _("Creating MBR for {0}...").format(self.drive)))

        try:
            self.tools.create_mbr(self.drive)

        except dbus.DBusException:
            logging.error(
                _("Error while creating MBR on {0}!").format(self.drive))
            self.events_in.put(
                StatusUpdate(
                    self.drive, DriveStatus.DRIVE_PTERROR, None, None,
                    _("Error while creating MBR on {0}!").format(self.drive)))
            return

        self.events_in.put(MBRCreated(self.drive))

        # Adjusting partitions alignment...
        adjusted_specs = self.tools.adjust_partspecs_to_geometry(
            self.drive, self.request.partspecs)

        events = []

        for p in adjusted_specs:
            try:
                # Create partition (via MBR)
                part_path = self.tools.create_partition(
                    self.drive, adjusted_specs[p])
                # Create FS (if specified)
                created = self.tools.create_fs(part_path, adjusted_specs[p])
                if created:
                    # FS created
                    logging.info(
                        _("Filesystem created on {0}").format(part_path))
                    events.append(
                        FSCreated(self.drive, "{0}{1}".format(self.drive, p)))
                else:
                    logging.info(_("Partition {0} done.").format(part_path))
                    # Partition for which mkfs is omitted
                    events.append(
                        StatusUpdate(
                            self.drive, None, part_path, PartitionStatus.DONE,
                            _("Partition {0} done.").format(part_path)))

            except dbus.DBusException, e:
                logging.error(
                    _("Error while creating partition {0} on {1}: {2}").format(
                        p, self.drive, e))
                self.events_in.put(
                    StatusUpdate(
                        self.drive, DriveStatus.DRIVE_PTERROR, None, None,
                        _("Error while creating partition {0} on {1}!").format(
                            p, self.drive)))
                return

        # Post-creation script
        if self.request.config.postscript:
            try:
                cmd = [
                    self.request.config.postscript,
                    self.tools.get_device_filename(self.drive)
                ]
                logging.debug(
                    _("Executing post-MBR script {0}...").format(cmd))
                output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
                for line in output.split('\n'):
                    logging.debug(_("Command output: {0}").format(line))
            except subprocess.CalledProcessError as e:
                for line in e.output.split('\n'):
                    logging.error(_("Command output: {0}").format(line))
                logging.error(
                    _("Error executing postscript for {0}: {1}!").format(
                        self.drive, e))
                self.events_in.put(
                    StatusUpdate(
                        self.drive, DriveStatus.DRIVE_PTERROR, None, None,
                        _("Error executing postscript for {0}!").format(
                            self.drive)))
                return

        # Signal all partitions have been created
        for ev in events:
            self.events_in.put(ev)

        return PartitionsCreated(self.drive)
예제 #7
0
class PartitionWriter:
    def __init__(self, events_in, request):
        self.events_in = events_in
        self.request = request

        self.parent = request.parent
        self.part = request.part
        self.partspec = request.partspec

        self.tools = DBusTools()

    def run(self):
        # Overall status
        success = True

        # Mount...
        if self.partspec["method"] == "copy-files":
            logging.info(_("Mounting {0}...").format(self.part))
            self.events_in.put(
                StatusUpdate(self.parent, None, self.part,
                             PartitionStatus.IN_PROGRESS,
                             _("Mounting {0}...").format(self.part)))
            try:
                mountpoint = self.tools.mount(self.part)
            except dbus.DBusException, e:
                logging.error(
                    _("Error while mounting {0}: {1}").format(self.part, e))
                self.events_in.put(
                    StatusUpdate(
                        self.parent, None, self.part, PartitionStatus.FAILED,
                        _("Error while mounting {0}!").format(self.part)))
                return

        # Copying data...
        logging.info(_("Copying to {0}...").format(self.part))
        self.events_in.put(
            StatusUpdate(self.parent, None, self.part,
                         PartitionStatus.IN_PROGRESS,
                         _("Copying to {0}...").format(self.part)))

        try:
            cmd = []
            if self.partspec["method"] == "copy-files":
                cmd = [
                    "rsync", "-rI", "--delete", "--", self.partspec["path"],
                    os.path.join(mountpoint, self.partspec["dest_prefix"])
                ]
            if self.partspec["method"] == "copy-image":
                cmd = [
                    "dd", "bs=8M", "conv=fsync",
                    "if={0}".format(self.partspec["path"]),
                    "of={0}".format(self.tools.get_device_filename(self.part))
                ]
            logging.debug(_("Executing copy command {0}...").format(cmd))
            output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
            for line in output.split('\n'):
                logging.debug(_("Command output: {0}").format(line))
        except subprocess.CalledProcessError as e:
            for line in e.output.split('\n'):
                logging.error(_("Command output: {0}").format(line))
            # Continue for unmounting...
            logging.error(_("Error executing copy command: {0}").format(e))
            success = False

        # Postcreation
        if self.partspec["method"] == "copy-files" and \
           self.partspec["postscript"]:
            try:
                cmd = [self.partspec["postscript"], mountpoint]
                logging.debug(
                    _("Executing post-partition script {0}...").format(cmd))
                output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
                for line in output.split('\n'):
                    logging.debug(_("Command output: {0}").format(line))
            except subprocess.CalledProcessError as e:
                for line in e.output.split('\n'):
                    logging.error(_("Command output: {0}").format(line))
                # Continue for unmounting...
                logging.error(_("Error executing postscript: {0}").format(e))
                success = False

        # Unmounting...
        if self.partspec["method"] == "copy-files":
            logging.info(_("Unmounting {0}...").format(self.part))
            self.events_in.put(
                StatusUpdate(self.parent, None, self.part,
                             PartitionStatus.IN_PROGRESS,
                             _("Unmounting {0}...").format(self.part)))

            try:
                self.tools.unmount_retry(self.part)
            except dbus.DBusException:
                logging.error(
                    _("Error while unmounting {0}!").format(self.part))
                self.events_in.put(
                    StatusUpdate(
                        self.parent, None, self.part, PartitionStatus.FAILED,
                        _("Error while unmounting {0}!").format(self.part)))
                return

        # Report overall status
        if success:
            logging.info(_("Partition {0} done.").format(self.part))
            self.events_in.put(
                StatusUpdate(self.parent, None, self.part,
                             PartitionStatus.DONE,
                             _("Partition {0} done.").format(self.part)))
        else:
            logging.error(_("Error while copying {0}!").format(self.part))
            self.events_in.put(
                StatusUpdate(self.parent, None, self.part,
                             PartitionStatus.FAILED,
                             _("Error while copying {0}!").format(self.part)))