mirror of
https://gitdl.cn/https://github.com/chakralinux/core.git
synced 2025-02-10 16:34:35 +08:00
450 lines
15 KiB
Python
450 lines
15 KiB
Python
# page_medium.py - Handler for the project settings page
|
|
#
|
|
# (c) Copyright 2010 Michael Towers (larch42 at googlemail dot com)
|
|
#
|
|
# This file is part of the larch project.
|
|
#
|
|
# larch is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# larch is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with larch; if not, write to the Free Software Foundation, Inc.,
|
|
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
#
|
|
#----------------------------------------------------------------------------
|
|
# 2010.12.27
|
|
|
|
"""This page takes a directory processed by larchify. It produces a bootable
|
|
larch medium, or, in the case of CD/DVD, an iso image.
|
|
It also handles creation of a boot-iso for an existing larch medium (partition)
|
|
and can copy larch media to different devices.
|
|
"""
|
|
|
|
import os
|
|
from config import detection_methods, OKFS
|
|
|
|
|
|
class Medium:
|
|
def __init__(self):
|
|
self.medium = None
|
|
self.srcmedium = None
|
|
self.detectionmodes = detection_methods.split('|')
|
|
ui.widgetlist(fss('fetch_layout', 'page_medium.uim'))
|
|
|
|
ui.connectlist(
|
|
(':vlabelb*clicked', self.newlabel),
|
|
(':selectpart*clicked', self.choosedest),
|
|
(':selectsrc*clicked', self.choosesrc),
|
|
(':persist*toggled', self.persistence),
|
|
(':ovl_journal*toggled', self.journal),
|
|
(':mediumtype*changed', self.mediumtype),
|
|
(':srctype*changed', self.srctype),
|
|
(':make_medium*clicked', self.make),
|
|
(':nolarchboot*toggled', self.bootnosearch),
|
|
(':detection*changed', self.mediumsearch),
|
|
(':pformat*toggled', self.setpformat),
|
|
(':bootlines*clicked', self.editbootlines),
|
|
(':syslinuxtemplate*clicked', self.editsyslin),
|
|
(':cdroot*clicked', self.browsecdroot),
|
|
)
|
|
|
|
|
|
def enter(self):
|
|
"""This is called when the page is entered/selected/shown.
|
|
It performs initialisations which depend on the state.
|
|
"""
|
|
self.destinationpath = ''
|
|
self.fsok = None
|
|
self.source, ok = fss('testlarchify') # check the larchified installation
|
|
if not ok:
|
|
run_error(self.data('msg_med') % self.source)
|
|
self.source = ''
|
|
self.mediumtype(None)
|
|
if self.medium != 'medium-boot':
|
|
self.srctype(None)
|
|
detect = fss('getitem', 'medium_search')
|
|
ui.command(':detection.set',
|
|
[self.data('detectionmodes')[l] for l in self.detectionmodes],
|
|
self.detectionmodes.index(detect))
|
|
self.nlbenable(detect)
|
|
ui.command(':nolarchboot.set', fss('getbool', 'boot_nosearch'))
|
|
ui.command(':vlabele.text', fss('get_mediumlabel'))
|
|
ui.command(':ovl_journal.set', fss('getbool', 'journal'))
|
|
fmt = fss('getbool', 'do_format')
|
|
ui.command(':pformat.set', fmt )
|
|
ui.command(':ovl_journal.enable', fmt)
|
|
ui.command(':persist.set', fss('getbool', 'do_persist'))
|
|
|
|
ui.command(':larchpart.text') # clear the destination
|
|
docviewer.gohome('gui_medium.html')
|
|
|
|
|
|
def data(self, key):
|
|
return ui.command('medium_page_data.get', key)
|
|
|
|
|
|
def mediumtype(self, index):
|
|
if (index == None):
|
|
if self.medium == None:
|
|
self.medium = self.data('media')[0]
|
|
else:
|
|
self.medium = self.data('media')[index]
|
|
|
|
if self.medium == 'medium-boot':
|
|
label = fss('get_bootisolabel')
|
|
ui.command(':srctype.setindex', self.data('sources').index('device'))
|
|
ui.command(':srctype.enable', False)
|
|
ifile = fss('getbootisofile')
|
|
|
|
else:
|
|
label = fss('get_mediumlabel')
|
|
ui.command(':srctype.enable', True)
|
|
|
|
if self.medium == 'medium-iso':
|
|
ifile = fss('getisofile')
|
|
|
|
self.showlabel(label)
|
|
|
|
if self.medium == 'medium-w':
|
|
ui.command(':mediumopts.enable', True)
|
|
self.setdestinationpath('')
|
|
|
|
else:
|
|
ui.command(':mediumopts.enable', False)
|
|
idir = fss('getisosavedir')
|
|
if not fss('isdir', idir):
|
|
fss('setitem', 'isosavedir', '')
|
|
idir = fss('getisosavedir')
|
|
self.setdestinationpath(os.path.join(idir, ifile))
|
|
|
|
if index != None:
|
|
self.enableprofile()
|
|
self.enablemake()
|
|
|
|
|
|
def srctype(self, index):
|
|
if (index == None):
|
|
if self.srcmedium == None:
|
|
self.srcmedium = self.data('sources')[0]
|
|
else:
|
|
self.srcmedium = self.data('sources')[index]
|
|
|
|
if self.srcmedium == 'larchified':
|
|
self.setsourcepath(self.source)
|
|
ui.command(':selectsrc.enable', False)
|
|
|
|
elif self.srcmedium == 'device':
|
|
self.setsourcepath('') # clear source, it must be selected
|
|
ui.command(':selectsrc.enable', True)
|
|
|
|
elif self.srcmedium == 'isofile':
|
|
isof = fss('getisofile')
|
|
isod = fss('getisosavedir')
|
|
self.pendingpath = os.path.join(isod, isof)
|
|
ui.command(':selectsrc.enable', True)
|
|
self.setsourcepath('')
|
|
self.checklarchsource()
|
|
|
|
|
|
def setsourcepath(self, path):
|
|
self.sourcepath = path
|
|
ui.command(':srclocation.text', path)
|
|
self.enableprofile()
|
|
self.enablemake()
|
|
|
|
|
|
def choosesrc(self):
|
|
# 'larchified' should not be possible - it is set on the project page
|
|
if self.srcmedium == 'device':
|
|
self.devices = []
|
|
larchcall('*rootfn', self._cd_line, 'blkid -c dev/null -o list')
|
|
|
|
elif self.srcmedium == 'isofile':
|
|
# Pop up a file browser
|
|
self.pendingpath = self.isopath(mode='source')
|
|
self.checklarchsource()
|
|
|
|
else:
|
|
debug('page_medium: Medium.choosesrc / ' + self.srcmedium)
|
|
|
|
def _cd_line(self, line):
|
|
if line == None:
|
|
# Completed - pop up device chooser
|
|
ok, choice = ui.command('listDialog',
|
|
self.data('parts_src'),
|
|
self.data('parts_t'),
|
|
self.devices, len(self.devices) - 1)
|
|
if ok:
|
|
self.pendingpath = choice.split()[0]
|
|
ui.idle_add(self.checklarchsource)
|
|
|
|
else:
|
|
l = line.strip()
|
|
if l.startswith('/dev/'):
|
|
i = l.find('(not mounted)')
|
|
if i > 0:
|
|
ls = l[:i].split(None, 2)
|
|
if (ls[0] != self.destinationpath) and (len(ls) == 3):
|
|
self.devices.append('%-10s %s' % (ls[0], ls[2]))
|
|
|
|
|
|
def checklarchsource(self):
|
|
if self.pendingpath:
|
|
# check it is really a larch medium
|
|
self.larchok = False
|
|
larchcall('*larchmedium', self._cs_line, self.pendingpath)
|
|
|
|
def _cs_line(self, line):
|
|
if line == None:
|
|
# Completed
|
|
if self.larchok:
|
|
self.setsourcepath(self.pendingpath)
|
|
else:
|
|
l = line.strip()
|
|
if l.startswith('##--'):
|
|
if l.endswith('ok'):
|
|
self.larchok = True
|
|
|
|
|
|
def enableprofile(self):
|
|
"""Set the enabled state of the medium profile frame,
|
|
according to the state of the choices.
|
|
"""
|
|
ui.command(':mediumprofile.enable', (self.medium != 'medium-boot')
|
|
and (self.srcmedium == 'larchified'))
|
|
|
|
|
|
def enablemake(self):
|
|
on = bool(self.destinationpath) and bool(self.sourcepath)
|
|
if self.medium == 'medium-w':
|
|
formatting = fss('getbool', 'do_format')
|
|
self.enablepersist(formatting or (self.fsok in OKFS))
|
|
if (not formatting):
|
|
if (self.fsok not in OKFS) and (self.fsok != 'vfat'):
|
|
on = False
|
|
ui.command(':make_medium.enable', on)
|
|
|
|
|
|
def enablepersist(self, on):
|
|
ui.command(':persist.enable', on)
|
|
self.persist_enabled = on
|
|
|
|
|
|
def persistence(self, on):
|
|
fss('setbool', 'do_persist', on)
|
|
|
|
|
|
def journal(self, on):
|
|
fss('setbool', 'journal', on)
|
|
|
|
|
|
def mediumsearch(self, option):
|
|
choice = self.detectionmodes[option]
|
|
fss('setitem', 'medium_search', choice)
|
|
self.nlbenable(choice)
|
|
|
|
|
|
def nlbenable(self, choice):
|
|
ui.command(':nolarchboot.enable', choice != 'search')
|
|
|
|
|
|
def bootnosearch(self, on):
|
|
fss('setbool', 'boot_nosearch', on)
|
|
|
|
|
|
def setpformat(self, on):
|
|
fss('setbool', 'do_format', on)
|
|
ui.command(':ovl_journal.enable', on)
|
|
self.enablemake()
|
|
|
|
|
|
def editbootlines(self):
|
|
f0 = 'profile:cd-root/boot0/bootlines'
|
|
if not fss('isfile', f0):
|
|
f0 = 'base:cd-root/boot0/bootlines'
|
|
edit('profile:cd-root/boot/bootlines', 'base:cd-root/boot0/bootlines')
|
|
|
|
|
|
def editsyslin(self):
|
|
f0 = 'profile:cd-root/boot0/isolinux/isolinux.cfg'
|
|
if not fss('isfile', f0):
|
|
f0 = 'base:cd-root/boot0/isolinux/isolinux.cfg'
|
|
edit('profile:cd-root/boot/isolinux/isolinux.cfg', f0)
|
|
|
|
|
|
def browsecdroot(self):
|
|
fss('browse', 'profile:cd-root')
|
|
|
|
|
|
def newlabel(self):
|
|
labelsrc = 'bootiso' if self.medium == 'medium-boot' else 'medium'
|
|
ok, l = ui.command('textLineDialog',
|
|
self.data('prompt_label'),
|
|
None, fss('get_%slabel' % labelsrc))
|
|
if ok:
|
|
l = l.replace(' ', '_')
|
|
self.showlabel(fss('set_%slabel' % labelsrc, l))
|
|
|
|
|
|
def showlabel(self, l):
|
|
ui.command(':vlabele.text', l)
|
|
|
|
|
|
def choosedest(self):
|
|
if self.medium == 'medium-w':
|
|
# Present a list of unmounted partitions
|
|
self.devices = []
|
|
larchcall('*rootfn', self._sd_line, 'blkid -c /dev/null -o list')
|
|
|
|
elif self.medium == 'medium-iso':
|
|
# Pop up a file browser
|
|
path = self.isopath(mode='iso')
|
|
if path:
|
|
self.setdestinationpath(path)
|
|
|
|
elif self.medium == 'medium-boot':
|
|
# Pop up a file browser
|
|
path = self.isopath(mode='bootiso')
|
|
if path:
|
|
self.setdestinationpath(path)
|
|
|
|
def _sd_line(self, line):
|
|
if line == None:
|
|
if not self.devices:
|
|
return
|
|
nmdevices = []
|
|
for part in fss('get_partitions'): # ->(dev, size in MiB(int))
|
|
if part[0] == self.sourcepath:
|
|
continue
|
|
found = False
|
|
for partinfo in self.devices:
|
|
if partinfo[0] == part[0]:
|
|
if partinfo[2]:
|
|
nmdevices.append('%-12s %8d MiB %-10s %s'
|
|
% (part[0], part[1], partinfo[1], partinfo[2]))
|
|
found = True
|
|
break
|
|
if not found:
|
|
nmdevices.append('%-12s %-12d MiB' % (part[0], part[1]))
|
|
|
|
# Completed - pop up device chooser
|
|
ok, choice = ui.command('listDialog',
|
|
self.data('parts_dst'),
|
|
self.data('parts_t'),
|
|
nmdevices, len(nmdevices) - 1)
|
|
if ok:
|
|
ui.idle_add(self.setdestinationpath, choice.split()[0])
|
|
|
|
else:
|
|
l = line.strip()
|
|
if l.startswith('/dev/'):
|
|
i = l.find('(not mounted)')
|
|
if i > 0:
|
|
# Try to get label for unmounted devices only
|
|
ls = l[:i].split(None, 2)
|
|
if len(ls) < 3:
|
|
ls.append('-') # signifies 'no label'
|
|
else:
|
|
ls = l.split(None, 2)
|
|
try:
|
|
ls[2] = None # mark the partition as mounted
|
|
except:
|
|
#run_error("Bad device data: %s" % l)
|
|
while len(ls) < 3:
|
|
ls.append(None)
|
|
self.devices.append(ls)
|
|
|
|
|
|
def setdestinationpath(self, path):
|
|
ui.command(':larchpart.text', path)
|
|
self.destinationpath = path
|
|
if path.startswith('/dev/'):
|
|
# Check the file-system
|
|
self.fsok = None
|
|
larchcall('*rootfn', self._em_line,
|
|
'blkid -c /dev/null -o value -s TYPE %s' % path)
|
|
else:
|
|
self.enablemake()
|
|
|
|
def _em_line(self, line):
|
|
if line == None:
|
|
# Completed
|
|
self.enablemake()
|
|
else:
|
|
line = line.strip()
|
|
if line:
|
|
self.fsok = line
|
|
|
|
|
|
def isopath(self, mode='dest'):
|
|
sdir = fss('getisosavedir')
|
|
ifname = fss('getbootisofile' if mode=='bootiso' else 'getisofile')
|
|
path = ui.fileDialog(self.data('isoget' if mode=='source' else 'isopath'),
|
|
startdir=sdir, create=(mode!='source'),
|
|
file=ifname, filter=(self.data('iso_type'), '*.iso'))
|
|
if path:
|
|
f = os.path.basename(path)
|
|
d = os.path.dirname(path)
|
|
if d != sdir:
|
|
fss('setitem', 'isosavedir', d)
|
|
if f != ifname:
|
|
fss('setitem', 'bootisofile' if mode=='bootiso' else 'isofile', f)
|
|
return path
|
|
|
|
return None
|
|
|
|
|
|
def make(self):
|
|
"""Write the larch medium.
|
|
"""
|
|
if self.srcmedium == 'larchified':
|
|
source = None
|
|
else:
|
|
source = self.sourcepath
|
|
if not source:
|
|
debug("page_medium: make / null source")
|
|
return
|
|
|
|
args = ['-l', ui.command(':vlabele.get')]
|
|
|
|
if self.medium == 'medium-boot':
|
|
# Write a boot iso file
|
|
args += ['-b', '-o', self.destinationpath]
|
|
larchcall('writemedium', source, args)
|
|
|
|
elif self.medium == 'medium-iso':
|
|
# Write an 'iso' file
|
|
args += ['-o', self.destinationpath]
|
|
larchcall('writemedium', source, args)
|
|
|
|
else:
|
|
# Write to partition
|
|
# Medium detection options
|
|
detect = fss('getitem', 'medium_search')
|
|
args += ['-d', detect]
|
|
if (detect != 'search') and ui.command(':nolarchboot.active'):
|
|
args.append('-n')
|
|
# Formatting
|
|
if fss('getbool', 'do_format'):
|
|
# Journalling?
|
|
if not fss('getbool', 'journal'):
|
|
args.append('-j')
|
|
else:
|
|
args.append('-F')
|
|
# Set master boot record?
|
|
if ui.command(':nombr.active'):
|
|
args.append('-m')
|
|
# Persistence
|
|
if fss('getbool', 'do_persist') and self.persist_enabled:
|
|
args.append('-P')
|
|
# Add the medium to the argument list
|
|
args.append(self.destinationpath)
|
|
larchcall('writemedium', source, args)
|