Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix:[#213] Rerun first setup in normal mode until all packages have been installed #226

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions debian/vanilla-first-setup.install
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
recipe.json usr/share/org.vanillaos.FirstSetup/
tests.json usr/share/org.vanillaos.FirstSetup/
__first_setup_reset_session usr/bin/
__first_setup_cleanup usr/bin/
first-setup.txt etc/vanilla/
Expand Down
9 changes: 9 additions & 0 deletions tests.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"current": {
"flatpak": ["/usr/bin/flatpak", "/usr/lib/x86_64-linux-gnu/gnome-software/plugins-20/libgs_plugin_flatpak.so"],
"appimage": ["/bin/fusermount", "/lib/x86_64-linux-gnu/libfuse3.so.3"],
"timeshift": ["/usr/bin/timeshift"],
"vm": ["/usr/bin/vmtoolsd", "/usr/bin/vmware-user"],
"codecs": ["/usr/share/doc/libavcodec-extra/copyright", "/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstlibav.so", "/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgsta52dec.so", "/usr/lib/x86_64-linux-gnu/gstreamer-1.0/libgstvaapi.so", "/usr/bin/unrar-nonfree"]
}
}
1 change: 1 addition & 0 deletions vanilla_first_setup/defaults/hostname.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def get_finals(self):
"if": "setHostname",
"type": "command",
"commands": ["hostnamectl set-hostname " + self.hostname],
"tests": []
}
],
}
Expand Down
2 changes: 1 addition & 1 deletion vanilla_first_setup/defaults/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def get_finals(self):
f'adduser --quiet --disabled-password --shell /bin/bash --gecos "{self.fullname}" {self.username}',
f'echo "{self.username}:{self.password_entry.get_text()}" | chpasswd',
f"usermod -a -G sudo,adm,lpadmin {self.username}",
],
]
}
],
}
Expand Down
4 changes: 3 additions & 1 deletion vanilla_first_setup/utils/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class Parser:
supported_types = ["command"]

@staticmethod
def parse(finals):
def parse(finals, tests):
commands = []
warps = []
all_vars = []
Expand Down Expand Up @@ -85,6 +85,8 @@ def parse(finals):
cmd = cmd.replace(f"exposed::{k}", v)
commands.append(cmd)

tests.append(_condition)

# set-up warps if any
for warp in warps:
_vars = warp["vars"]
Expand Down
51 changes: 51 additions & 0 deletions vanilla_first_setup/utils/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# tests.py
#
#
# This program 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 Foundationat version 3 of the License.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.

import os
import json


class Tests:

def __init__(self):
self.__selected_tests = [""]
self.__tests = {}
self.__tests_path = "/usr/share/org.vanillaos.FirstSetup/tests.json"
self.__selected_tests_path = "/home/$REAL_USER/.local/share/selected_tests.json"
muhdsalm marked this conversation as resolved.
Show resolved Hide resolved
self.__selected_tests_path = "/home/{}/.local/share/selected_tests.json".format(os.getenv("REAL_USER"))

def add_test(self, test):
self.__selected_tests.append(test)

def test(self):
for i, v in self.__tests["current"]:
if i in self.__selected_tests:
for j in v:
if not os.path.isfile(j):
return False
return True

def load(self):
with open(self.__tests_path, 'r') as f:
self.__tests = json.load(f)
with open(self.__selected_tests_path, 'r') as f:
self.__selected_tests = json.load(f)

def write(self):
with open(self.__selected_tests_path, 'w') as f:
json.dump(self.__selected_tests, f)

def remove(self):
os.remove(self.__selected_tests_path)
28 changes: 26 additions & 2 deletions vanilla_first_setup/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
from vanilla_first_setup.utils.builder import Builder
from vanilla_first_setup.utils.parser import Parser
from vanilla_first_setup.utils.processor import Processor
from vanilla_first_setup.utils.tests import Tests

from vanilla_first_setup.views.progress import VanillaProgress
from vanilla_first_setup.views.done import VanillaDone
from vanilla_first_setup.views.post_script import VanillaPostScript

from dialog import VanillaDialog


@Gtk.Template(resource_path="/org/vanillaos/FirstSetup/gtk/window.ui")
class VanillaWindow(Adw.ApplicationWindow):
Expand Down Expand Up @@ -56,13 +59,30 @@ def __init__(self, post_script: str, user: str, new_user: bool = False, **kwargs
# True/False = managed result
self.__last_result = None

# Create and run the tests to make sure the previous run installed
# all the packages properly
if self.__init_mode == 1:
self.__tests = Tests()
self.__tests.load()

# 0 = succeeded
# 1 = did not succeed
# -1 = did not test
self.__tests_succeeded = 0 if self.__tests.test() else 1
post_script = 0 if self.__tests_succeeded == 1 else 1
else:
self.__tests_succeeded = -1

# if a post_script is provided, we are in the post setup
# so we can skip the builder and just run the post script
# in the Vte terminal
if post_script:
# set the initialization mode to 1
self.__init_mode = 1

# delete the tests file
self.__tests.remove()

# system views
self.__view_done = VanillaDone(
self,
Expand Down Expand Up @@ -96,6 +116,9 @@ def __init__(self, post_script: str, user: str, new_user: bool = False, **kwargs
# connect system signals
self.__connect_signals()

if self.__tests_succeeded == 1:
dialog = VanillaDialog(self, "Previous setup failed", "The packages you installed in the previous boot of First Setup could not be installed. Therefore, you will have to go through the First Setup again.")

def __build_post_script_ui(self, post_script):
self.__view_post_script = VanillaPostScript(self, post_script)

Expand Down Expand Up @@ -168,16 +191,17 @@ def __on_page_changed(self, *args):

# this parses the finals to compatible commands, by replacing the
# placeholders with the actual values and generating shell commands
commands = Parser.parse(finals)
commands = Parser.parse(finals, self.__tests)

# process the commands
res = Processor.get_setup_commands(
self.recipe.get("log_file", "/tmp/vanilla_first_setup.log"),
self.recipe.get("pre_run", []),
self.recipe.get("post_run"),
commands,
commands
)

self.__tests.write()
self.__view_progress.start(res, Processor.hide_first_setup, self.__user)

def set_installation_result(self, result, terminal):
Expand Down