Skip to content

Commit

Permalink
Adopt Multiboot Manager from Openatv
Browse files Browse the repository at this point in the history
  • Loading branch information
teamblue-e2 committed Apr 1, 2020
1 parent 0655b11 commit 8dc8de6
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 2 deletions.
5 changes: 3 additions & 2 deletions lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ install_PYTHON = \
ImageBackup.py \
PluginBackup.py \
PluginRestore.py \
Flash_online.py
Flash_online.py \
Multibootmgr.py

dist_install_DATA = \
restorewizard.xml \
Expand All @@ -25,7 +26,7 @@ dist_install_DATA = \
upgrade.png \
PluginBackup.sh \
PluginRestore.sh

install-data-hook:
chmod +x $(DESTDIR)$(installdir)/PluginBackup.sh; \
chmod +x $(DESTDIR)$(installdir)/PluginRestore.sh;
211 changes: 211 additions & 0 deletions lib/python/Plugins/SystemPlugins/SoftwareManager/Multibootmgr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
from Screens.Screen import Screen
from Screens.Standby import TryQuitMainloop
from Screens.MessageBox import MessageBox
from Screens.Console import Console
from boxbranding import getMachineBuild
from Components.ActionMap import ActionMap
from Components.ChoiceList import ChoiceList, ChoiceEntryComponent
from Components.config import config
from Components.Label import Label
from Components.Sources.StaticText import StaticText
from Components.SystemInfo import SystemInfo
from Components.Harddisk import Harddisk
from Tools.BoundFunction import boundFunction
from Tools.Directories import pathExists
from Tools.Multiboot import GetImagelist, GetCurrentImage, GetCurrentImageMode, EmptySlot

class MultiBootWizard(Screen):

skin = """
<screen name="MultiBoot Image Manager" position="center,center" size="750,900" flags="wfNoBorder" backgroundColor="transparent">
<eLabel name="b" position="0,0" size="750,700" backgroundColor="#00ffffff" zPosition="-2" />
<eLabel name="a" position="1,1" size="748,698" backgroundColor="#00000000" zPosition="-1" />
<widget source="Title" render="Label" position="60,10" foregroundColor="#00ffffff" size="480,50" halign="left" font="Regular; 28" backgroundColor="#00000000" />
<eLabel name="line" position="1,60" size="748,1" backgroundColor="#00ffffff" zPosition="1" />
<eLabel name="line2" position="1,250" size="748,4" backgroundColor="#00ffffff" zPosition="1" />
<widget name="config" position="2,280" size="730,380" halign="center" font="Regular; 22" backgroundColor="#00000000" foregroundColor="#00e5b243" />
<widget source="description" render="Label" position="2,80" size="730,30" halign="center" font="Regular; 22" backgroundColor="#00000000" foregroundColor="#00ffffff" />
<widget source="options" render="Label" position="2,130" size="730,60" halign="center" font="Regular; 22" backgroundColor="#00000000" foregroundColor="#00ffffff" />
<widget source="key_red" render="Label" position="30,200" size="150,30" noWrap="1" zPosition="1" valign="center" font="Regular; 20" halign="left" backgroundColor="#00000000" foregroundColor="#00ffffff" />
<widget source="key_green" render="Label" position="200,200" size="150,30" noWrap="1" zPosition="1" valign="center" font="Regular; 20" halign="left" backgroundColor="#00000000" foregroundColor="#00ffffff" />
<widget source="key_yellow" render="Label" position="370,200" size="150,30" noWrap="1" zPosition="1" valign="center" font="Regular; 20" halign="left" backgroundColor="#00000000" foregroundColor="#00ffffff" />
<eLabel position="20,200" size="6,40" backgroundColor="#00e61700" /> <!-- Should be a pixmap red -->
<eLabel position="190,200" size="6,40" backgroundColor="#0061e500" /> <!-- Should be a pixmap green -->
<eLabel position="360,200" size="6,40" backgroundColor="#ffff00" /> <!-- Should be a pixmap yellow-->
</screen>
"""

def __init__(self, session,menu_path=""):
Screen.__init__(self, session)
Screen.setTitle(self, _("MultiBoot Image Manager"))
if SystemInfo["HasSDmmc"] and not pathExists('/dev/sda4'):
self["key_red"] = StaticText(_("Cancel"))
self["description"] = StaticText(_("Press Init to format SDcard."))
self["options"] = StaticText("")
self["key_yellow"] = StaticText(_("Init SDcard"))
self["config"] = ChoiceList(list=[ChoiceEntryComponent('',((""), "Queued"))])
self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "KeyboardInputActions", "MenuActions"],
{
"red": boundFunction(self.close, None),
"yellow": self.format,
"ok": self.erase,
"cancel": boundFunction(self.close, None),
"up": self.keyUp,
"down": self.keyDown,
"left": self.keyLeft,
"right": self.keyRight,
"upRepeated": self.keyUp,
"downRepeated": self.keyDown,
"leftRepeated": self.keyLeft,
"rightRepeated": self.keyRight,
"menu": boundFunction(self.close, True),
}, -1)
else:
self["key_red"] = StaticText(_("Cancel"))
self["description"] = StaticText(_("Use the cursor keys to select an installed image and then Erase button."))
self["options"] = StaticText(_("Note: slot list does not show current image or empty slots."))
self["key_green"] = StaticText(_("Erase"))
if SystemInfo["HasSDmmc"]:
self["key_yellow"] = StaticText(_("Init SDcard"))
else:
self["key_yellow"] = StaticText("")
self["config"] = ChoiceList(list=[ChoiceEntryComponent('',((_("Retrieving image slots - Please wait...")), "Queued"))])
imagedict = []
self.getImageList = None
self.startit()

self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "KeyboardInputActions", "MenuActions"],
{
"red": boundFunction(self.close, None),
"green": self.erase,
"yellow": self.format,
"ok": self.erase,
"cancel": boundFunction(self.close, None),
"up": self.keyUp,
"down": self.keyDown,
"left": self.keyLeft,
"right": self.keyRight,
"upRepeated": self.keyUp,
"downRepeated": self.keyDown,
"leftRepeated": self.keyLeft,
"rightRepeated": self.keyRight,
"menu": boundFunction(self.close, True),
}, -1)
self.onLayoutFinish.append(self.layoutFinished)

def layoutFinished(self):
self.setTitle(self.title)

def startit(self):
self.getImageList = GetImagelist(self.ImageList)

def ImageList(self, imagedict):
list = []
mode = GetCurrentImageMode() or 0
currentimageslot = GetCurrentImage()
if SystemInfo["HasSDmmc"]:
currentimageslot += 1
for x in sorted(imagedict.keys()):
if imagedict[x]["imagename"] != _("Empty slot") and x != currentimageslot:
list.append(ChoiceEntryComponent('',((_("slot%s - %s ")) % (x, imagedict[x]['imagename']), x)))
self["config"].setList(list)

def erase(self):
self.currentSelected = self["config"].l.getCurrentSelection()
if self.currentSelected[0][1] != "Queued":
if SystemInfo["HasRootSubdir"]:
message = _("Removal of this slot will not show in %s Gui. Are you sure you want to delete image slot %s ?") %(getMachineBuild(), self.currentSelected[0][1])
ybox = self.session.openWithCallback(self.doErase, MessageBox, message, MessageBox.TYPE_YESNO, default=True)
ybox.setTitle(_("Remove confirmation"))
else:
message = _("Are you sure you want to delete image slot %s ?") %self.currentSelected[0][1]
ybox = self.session.openWithCallback(self.doErase, MessageBox, message, MessageBox.TYPE_YESNO, default=True)
ybox.setTitle(_("Remove confirmation"))

def doErase(self, answer):
if answer is True:
sloterase = EmptySlot(self.currentSelected[0][1], self.startit)

def format(self):
if SystemInfo["HasSDmmc"]:
self.TITLE = _("Init SDCARD")
f = open('/sys/firmware/devicetree/base/chosen/bootargs', 'r').read()
if "sda" in f:
self.session.open(MessageBox, _("Multiboot manager - Cannot initialize SDcard when running image on SDcard."), MessageBox.TYPE_INFO, timeout=10)
self.close
else:
sda ="sda"
size = Harddisk(sda).diskSize()

if ((float(size) / 1024) / 1024) >= 1:
des = _("Size: ") + str(round(((float(size) / 1024) / 1024), 2)) + _("TB")
elif (size / 1024) >= 1:
des = _("Size: ") + str(round((float(size) / 1024), 2)) + _("GB")
if "GB" in des:
print "Multibootmgr1", des, "%s" %des[6], size
if size/1024 < 6:
print "Multibootmgr2", des, "%s" %des[6], size/1024
self.session.open(MessageBox, _("Multiboot manager - The SDcard must be at least 8MB."), MessageBox.TYPE_INFO, timeout=10)
self.close
else:
IMAGE_ALIGNMENT=1024
KERNEL_PARTITION_SIZE=32768
ROOTFS_PARTITION_SIZE=2097152
PARTED_START_KERNEL2 = IMAGE_ALIGNMENT
PARTED_END_KERNEL2 = int(PARTED_START_KERNEL2) + int(KERNEL_PARTITION_SIZE)
PARTED_START_ROOTFS2 = PARTED_END_KERNEL2
PARTED_END_ROOTFS2 = int(PARTED_END_KERNEL2) + int(ROOTFS_PARTITION_SIZE)
PARTED_START_KERNEL3 = PARTED_END_ROOTFS2
PARTED_END_KERNEL3 = int(PARTED_END_ROOTFS2) + int(KERNEL_PARTITION_SIZE)
PARTED_START_ROOTFS3 = PARTED_END_KERNEL3
PARTED_END_ROOTFS3 = int(PARTED_END_KERNEL3) + int(ROOTFS_PARTITION_SIZE)

self.session.open(MessageBox, _("Multiboot manager - SDcard initialization run, please restart your Image."), MessageBox.TYPE_INFO, timeout=10)
cmdlist = []
cmdlist.append("for n in /dev/%s* ; do umount $n > /dev/null 2>&1 ; done"%sda)
cmdlist.append("for n in /dev/%s* ; do parted -s /dev/%s rm ${n:8} > /dev/null 2>&1; done"%(sda,sda))
cmdlist.append("dd if=/dev/zero of=/dev/%s bs=512 count=10240 conv=notrunc"%sda)
cmdlist.append("partprobe /dev/%s"%sda)
cmdlist.append("parted -s /dev/%s mklabel gpt"%sda)
cmdlist.append("parted -s /dev/%s unit KiB mkpart kernel2 ext2 %s %s"%(sda,PARTED_START_KERNEL2,PARTED_END_KERNEL2))
cmdlist.append("parted -s /dev/%s unit KiB mkpart rootfs2 ext2 %s %s "%(sda,PARTED_START_ROOTFS2,PARTED_END_ROOTFS2))
cmdlist.append("parted -s /dev/%s unit KiB mkpart kernel3 ext2 %s %s"%(sda,PARTED_START_KERNEL3,PARTED_END_KERNEL3))
cmdlist.append("parted -s /dev/%s unit KiB mkpart rootfs3 ext2 %s %s "%(sda,PARTED_START_ROOTFS3,PARTED_END_ROOTFS3))
cmdlist.append("parted -s /dev/%s unit KiB mkpart userdata ext2 %s 100%% "%(sda,PARTED_END_ROOTFS3)) ### Tech note: should be 95% for new mSD cards with discard"

cmdlist.append("for n in /dev/%s{1..5} ; do mkfs.ext4 $n ; done"%sda) ### we should do kernels in ext2, but ok for small kernel partitions

# cmdlist.append("dd if=/dev/zero of=/dev/%s bs=512 count=1 conv=notrunc"%sda)
# cmdlist.append("rm -f /tmp/init.sh")
# cmdlist.append("echo -e 'sfdisk /dev/%s <<EOF' >> /tmpp/init.sh"%sda)
# cmdlist.append("echo -e ',8M' >> /tmpp/init.sh")
# cmdlist.append("echo -e ',2048M' >> /tmpp/init.sh")
# cmdlist.append("echo -e ',8M' >> /tmpp/init.sh")
# cmdlist.append("echo -e ',2048M' >> /tmpp/init.sh")
# cmdlist.append("echo -e 'EOF' >> /tmpp/init.sh")
# cmdlist.append("chmod +x /tmp/init.sh")
# cmdlist.append("/tmp/init.sh")

cmdlist.append("partprobe /dev/%s"%sda)
self.session.open(Console, title = self.TITLE, cmdlist = cmdlist, closeOnSuccess = True)
else:
self.close()

def selectionChanged(self):
pass

def keyLeft(self):
self["config"].instance.moveSelection(self["config"].instance.moveUp)
self.selectionChanged()

def keyRight(self):
self["config"].instance.moveSelection(self["config"].instance.moveDown)
self.selectionChanged()

def keyUp(self):
self["config"].instance.moveSelection(self["config"].instance.moveUp)
self.selectionChanged()

def keyDown(self):
self["config"].instance.moveSelection(self["config"].instance.moveDown)
self.selectionChanged()
5 changes: 5 additions & 0 deletions lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from ImageBackup import ImageBackup
from Flash_online import FlashOnline
from RestoreWizard import RestoreWizard
from Multibootmgr import MultiBootWizard
from PluginBackup import PluginBackup
from PluginRestore import PluginRestore
from BackupRestore import BackupSelection, RestoreMenu, BackupScreen, RestoreScreen, getBackupPath, getOldBackupPath, getBackupFilename
Expand Down Expand Up @@ -148,6 +149,8 @@ def __init__(self, session, args = 0):
self.list.append(("flash-online", _("Flash Online"), _("Flash on the fly your your Receiver software.") + self.oktext, None))
self.list.append(("software-restore", _("Software restore"), _("Restore your Receiver with a new firmware." ) + self.oktext, None))
self.list.append(("backup-image", _("Backup Image"), _("Backup your running Receiver image to HDD or USB." ) + self.oktext, None))
if SystemInfo["canMultiBoot"]:
self.list.append(("multiboot-manager", _("Multiboot Manager"), _("\nMaintain your multiboot device.") + self.oktext, None))
self.list.append(("system-backup", _("Backup system settings"), _("Backup your Receiver settings." ) + self.oktext + "\n\n" + self.infotext, None))
self.list.append(("system-restore",_("Restore system settings"), _("Restore your Receiver settings." ) + self.oktext, None))
# self.list.append(("plugin-backup",_("Backup Plugins"), _("Backup your installed plugins." ) + self.oktext, None))
Expand Down Expand Up @@ -284,6 +287,8 @@ def go(self, num = None):
self.session.open(PluginManager, self.skin_path)
elif (currentEntry == "flash-online"):
self.session.open(FlashOnline)
elif (currentEntry == "multiboot-manager"):
self.session.open(MultiBootWizard)
elif (currentEntry == "backup-image"):
self.session.open(ImageBackup)
elif (currentEntry == "system-backup"):
Expand Down
23 changes: 23 additions & 0 deletions po/de.po
Original file line number Diff line number Diff line change
Expand Up @@ -3845,6 +3845,9 @@ msgstr "Gleich wie"
msgid "Equatorial Guinea"
msgstr "Equatorial Guinea"

msgid "Erase"
msgstr "Löschen"

msgid "Eritrea"
msgstr "Eritrea"

Expand Down Expand Up @@ -5109,6 +5112,9 @@ msgstr "Informationen"
msgid "Init"
msgstr "Initialisieren"

msgid "Init SDcard"
msgstr "Init SDcard"

msgid "Initial fast forward speed"
msgstr "Initiale Schnellvorlauf-Geschwindigkeit"

Expand Down Expand Up @@ -5708,6 +5714,13 @@ msgstr "Hauptmenü"
msgid "Maintain old EPG data for"
msgstr "Behalte abgelaufene EPG-Daten (in Minuten)"

msgid ""
"\n"
"Maintain your multiboot device."
msgstr ""
"\n"
"Verwalten Sie Ihr Multiboot-Gerät."

msgid "Make File Commander accessible from the Extensions menu."
msgstr ""

Expand Down Expand Up @@ -6149,6 +6162,10 @@ msgstr "Multi-Boot auswählen"
msgid "MultiType"
msgstr "MultiType"

#
msgid "MultiBoot Image Manager"
msgstr "Multiboot-Image-Manager"

#, python-format
msgid "Multiboot ERROR! - no %s in boot partition."
msgstr ""
Expand Down Expand Up @@ -6627,6 +6644,9 @@ msgstr "Nicht geprüft:"
msgid "Not-Associated"
msgstr "Nicht verbunden"

msgid "Note: slot list does not show current image or empty slots."
msgstr "Hinweis: Die Slotliste zeigt kein aktuelles Image oder leere Slots an."

msgid "Note: when enabled, and you do want standby mode after wake up, set option 'Startup to Standby' as 'No, except Wakeup timer'."
msgstr "Hinweis: wenn aktiviert und Sie möchten nach dem Einschalten direkt in den Standby, dann setzen Sie die Option 'Einschalten in den Standby' als 'Nein, ausser Einschalt Timer'."

Expand Down Expand Up @@ -11503,6 +11523,9 @@ msgstr "Benutze originale Teletext Position"
msgid "Use power measurement"
msgstr "Stromaufnahme messen"

msgid "Use the cursor keys to select an installed image and then Erase button."
msgstr "Ein installiertes Image auswählen und danach die Taste GRÜN drücken, um es zu löschen."

msgid "Use the cursor keys to select an installed image and then Reboot button."
msgstr ""

Expand Down

0 comments on commit 8dc8de6

Please sign in to comment.