]> glassweightruler.freedombox.rocks Git - waydroid.git/blobdiff - tools/actions/initializer.py
user_manager: Respect user umask and use less code
[waydroid.git] / tools / actions / initializer.py
index 0d7755b34e1a6b208b59f4fea4b769fb358c78a1..41a0be38320bb2d01ad52b83f906b0a6fb805ade 100644 (file)
@@ -104,7 +104,7 @@ def init(args):
     if not is_initialized(args) or args.force:
         initializer_service = None
         try:
-            initializer_service = dbus.SystemBus().get_object("id.waydro.ContainerService", "/Initializer")
+            initializer_service = tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer")
         except dbus.DBusException:
             pass
         setup_config(args)
@@ -113,24 +113,42 @@ def init(args):
             status = helpers.lxc.status(args)
         if status != "STOPPED":
             logging.info("Stopping container")
-            helpers.lxc.stop(args)
-        helpers.images.umount_rootfs(args)
+            try:
+                container = tools.helpers.ipc.DBusContainerService()
+                args.session = container.GetSession()
+                container.Stop(False)
+            except Exception as e:
+                logging.debug(e)
+                tools.actions.container_manager.stop(args)
         if args.images_path not in tools.config.defaults["preinstalled_images_paths"]:
             helpers.images.get(args)
+        else:
+            helpers.images.remove_overlay(args)
         if not os.path.isdir(tools.config.defaults["rootfs"]):
             os.mkdir(tools.config.defaults["rootfs"])
+        if not os.path.isdir(tools.config.defaults["overlay"]):
+            os.mkdir(tools.config.defaults["overlay"])
+            os.mkdir(tools.config.defaults["overlay"]+"/vendor")
+        if not os.path.isdir(tools.config.defaults["overlay_rw"]):
+            os.mkdir(tools.config.defaults["overlay_rw"])
+            os.mkdir(tools.config.defaults["overlay_rw"]+"/system")
+            os.mkdir(tools.config.defaults["overlay_rw"]+"/vendor")
+        helpers.drivers.probeAshmemDriver(args)
         helpers.lxc.setup_host_perms(args)
         helpers.lxc.set_lxc_config(args)
         helpers.lxc.make_base_props(args)
         if status != "STOPPED":
             logging.info("Starting container")
-            helpers.images.mount_rootfs(args, args.images_path)
-            helpers.lxc.start(args)
+            try:
+                container.Start(args.session)
+            except Exception as e:
+                logging.debug(e)
+                logging.error("Failed to restart container. Please do so manually.")
 
         if "running_init_in_service" not in args or not args.running_init_in_service:
             try:
                 if initializer_service:
-                    initializer_service.Done(dbus_interface="id.waydro.Initializer")
+                    initializer_service.Done()
             except dbus.DBusException:
                 pass
     else:
@@ -139,26 +157,51 @@ def init(args):
 def wait_for_init(args):
     helpers.ipc.create_channel("remote_init_output")
 
-    name = dbus.service.BusName("id.waydro.ContainerService", dbus.SystemBus())
     mainloop = GLib.MainLoop()
     dbus_obj = DbusInitializer(mainloop, dbus.SystemBus(), '/Initializer', args)
     mainloop.run()
 
+    # After init
+    dbus_obj.remove_from_connection()
+
 class DbusInitializer(dbus.service.Object):
     def __init__(self, looper, bus, object_path, args):
         self.args = args
         self.looper = looper
         dbus.service.Object.__init__(self, bus, object_path)
 
-    @dbus.service.method("id.waydro.Initializer", in_signature='a{ss}', out_signature='')
-    def Init(self, params):
-        threading.Thread(target=remote_init_server, args=(self.args, params)).start()
+    @dbus.service.method("id.waydro.Initializer", in_signature='a{ss}', out_signature='', sender_keyword="sender", connection_keyword="conn")
+    def Init(self, params, sender=None, conn=None):
+        channels_cfg = tools.config.load_channels()
+        no_auth = params["system_channel"] == channels_cfg["channels"]["system_channel"] and \
+                  params["vendor_channel"] == channels_cfg["channels"]["vendor_channel"]
+        if no_auth or ensure_polkit_auth(sender, conn, "id.waydro.Initializer.Init"):
+            threading.Thread(target=remote_init_server, args=(self.args, params)).start()
+        else:
+            raise PermissionError("Polkit: Authentication failed")
 
     @dbus.service.method("id.waydro.Initializer", in_signature='', out_signature='')
     def Done(self):
         if is_initialized(self.args):
             self.looper.quit()
 
+def ensure_polkit_auth(sender, conn, privilege):
+    dbus_info = dbus.Interface(conn.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus/Bus", False), "org.freedesktop.DBus")
+    pid = dbus_info.GetConnectionUnixProcessID(sender)
+    polkit = dbus.Interface(dbus.SystemBus().get_object("org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", False), "org.freedesktop.PolicyKit1.Authority")
+    try:
+        (is_auth, _, _) = polkit.CheckAuthorization(
+            ("unix-process", {
+                "pid": dbus.UInt32(pid, variant_level=1),
+                "start-time": dbus.UInt64(0, variant_level=1)}),
+            privilege, {"AllowUserInteraction": "true"},
+            dbus.UInt32(1),
+            "",
+            timeout=300)
+        return is_auth
+    except dbus.DBusException:
+        raise PermissionError("Polkit: Authentication timed out")
+
 def background_remote_init_process(args):
     with helpers.ipc.open_channel("remote_init_output", "wb") as channel_out:
         class StdoutRedirect(logging.StreamHandler):
@@ -231,7 +274,7 @@ def remote_init_client(args):
 
     if is_initialized(args):
         try:
-            bus.get_object("id.waydro.ContainerService", "/Initializer").Done(dbus_interface="id.waydro.Initializer")
+            tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Done()
         except dbus.DBusException:
             pass
         return
@@ -239,7 +282,7 @@ def remote_init_client(args):
     def notify_and_quit(caller):
         if is_initialized(args):
             try:
-                bus.get_object("id.waydro.ContainerService", "/Initializer").Done(dbus_interface="id.waydro.Initializer")
+                tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Done()
             except dbus.DBusException:
                 pass
         GLib.idle_add(Gtk.main_quit)
@@ -247,8 +290,10 @@ def remote_init_client(args):
     class WaydroidInitWindow(Gtk.Window):
         def __init__(self):
             super().__init__(title="Initialize Waydroid")
+            channels_cfg = tools.config.load_channels()
+
             self.set_default_size(600, 250)
-            self.set_icon_from_file(tools.config.tools_src + "/data/AppIcon.png")
+            self.set_icon_name("waydroid")
 
             grid = Gtk.Grid(row_spacing=6, column_spacing=6, margin=10, column_homogeneous=True)
             grid.set_hexpand(True)
@@ -257,14 +302,14 @@ def remote_init_client(args):
 
             sysOtaLabel = Gtk.Label("System OTA")
             sysOtaEntry = Gtk.Entry()
-            sysOtaEntry.set_text(tools.config.channels_defaults["system_channel"])
+            sysOtaEntry.set_text(channels_cfg["channels"]["system_channel"])
             grid.attach(sysOtaLabel, 0, 0, 1, 1)
             grid.attach_next_to(sysOtaEntry ,sysOtaLabel, Gtk.PositionType.RIGHT, 2, 1)
             self.sysOta = sysOtaEntry.get_buffer()
 
             vndOtaLabel = Gtk.Label("Vendor OTA")
             vndOtaEntry = Gtk.Entry()
-            vndOtaEntry.set_text(tools.config.channels_defaults["vendor_channel"])
+            vndOtaEntry.set_text(channels_cfg["channels"]["vendor_channel"])
             grid.attach(vndOtaLabel, 0, 1, 1, 1)
             grid.attach_next_to(vndOtaEntry, vndOtaLabel, Gtk.PositionType.RIGHT, 2, 1)
             self.vndOta = vndOtaEntry.get_buffer()
@@ -340,9 +385,12 @@ def remote_init_client(args):
                     "vendor_channel": self.vndOta.get_text(),
                     "system_type": self.sysType.get_active_text()
                 }
-                bus.get_object("id.waydro.ContainerService", "/Initializer").Init(params, dbus_interface="id.waydro.Initializer")
-            except:
-                draw("The waydroid container service is not listening\n")
+                tools.helpers.ipc.DBusContainerService("/Initializer", "id.waydro.Initializer").Init(params, timeout=310)
+            except dbus.DBusException as e:
+                if e.get_dbus_name() == "org.freedesktop.DBus.Python.PermissionError":
+                    draw(e.get_dbus_message().splitlines()[-1] + "\n")
+                else:
+                    draw("The waydroid container service is not listening\n")
                 GLib.idle_add(self.downloadBtn.set_sensitive, True)
                 return