Last active
December 24, 2017 04:27
-
-
Save laurelmay/8e8bc9f97514bcda6bfa813d7e7a6f72 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| import gi | |
| gi.require_version('Gtk', '3.0') | |
| gi.require_version('Vte', '2.91') | |
| from gi.repository import Gtk, Vte | |
| from gi.repository import GLib | |
| import os | |
| import platform | |
| import re | |
| import subprocess | |
| import sys | |
| # Common should always run, but put it in the list | |
| tags = ["common"] | |
| user_config_path = os.environ['HOME'] + "/.config/vm_config" | |
| user_config = {} | |
| class CheckboxWindow(Gtk.Window): | |
| def __init__(self): | |
| Gtk.Window.__init__(self, title="JMU CS VM Configuration") | |
| self.set_border_width(10) | |
| vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing = 6) | |
| self.add(vbox) | |
| label = Gtk.Label("Select the courses you need to configure your VM for") | |
| vbox.pack_start(label, True, True, 0) | |
| cs101 = Gtk.CheckButton("CS 101") | |
| cs101.connect("toggled", self.on_button_toggled, "cs101") | |
| vbox.pack_start(cs101, True, True, 0) | |
| cs149 = Gtk.CheckButton("CS 149") | |
| cs149.connect("toggled", self.on_button_toggled, "cs149") | |
| vbox.pack_start(cs149, True, True, 0) | |
| cs159 = Gtk.CheckButton("CS 159") | |
| cs159.connect("toggled", self.on_button_toggled, "cs159") | |
| vbox.pack_start(cs159, True, True, 0) | |
| cs261 = Gtk.CheckButton("CS 261") | |
| cs261.connect("toggled", self.on_button_toggled, "cs261") | |
| vbox.pack_start(cs261, True, True, 0) | |
| cs354 = Gtk.CheckButton("CS 354") | |
| cs354.connect("toggled", self.on_button_toggled, "cs354") | |
| vbox.pack_start(cs354, True, True, 0) | |
| button_box = Gtk.Box(spacing=6) | |
| self.run_button = Gtk.Button.new_with_label("Run") | |
| self.run_button.connect("clicked", self.on_run_clicked) | |
| button_box.pack_start(self.run_button, True, True, 0) | |
| self.cancel_button = Gtk.Button.new_with_mnemonic("_Cancel") | |
| self.cancel_button.connect("clicked", Gtk.main_quit) | |
| button_box.pack_end(self.cancel_button, True, True, 0) | |
| vbox.pack_end(button_box, True, True, 0) | |
| self.terminal = Vte.Terminal() | |
| self.terminal.connect("child-exited", self.sub_command_exited) | |
| vbox.pack_end(self.terminal, True, True, 0) | |
| def on_button_toggled(self, button, name): | |
| if button.get_active(): | |
| tags.append(name) | |
| else: | |
| tags.remove(name) | |
| def sub_command_exited(self, widget, exit_status): | |
| self.cancel_button.set_sensitive(True) | |
| if exit_status == 0: | |
| dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.INFO, | |
| Gtk.ButtonsType.OK, "Complete") | |
| dialog.format_secondary_text("Your machine has been configured for: " + | |
| ",".join(tags) + "\nPress OK to exit.") | |
| dialog.run() | |
| dialog.destroy() | |
| Gtk.main_quit() | |
| elif exit_status == 65280: | |
| dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, | |
| Gtk.ButtonsType.OK, "Unable to authenticate") | |
| dialog.format_secondary_text("Either an incorrect password was" | |
| " entered or the password dialog was closed. Please try" | |
| " again") | |
| dialog.run() | |
| dialog.destroy() | |
| else: | |
| dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, | |
| Gtk.ButtonsType.OK, "Error") | |
| dialog.set_markup("There was an error while running the" | |
| " configuration tasks. Please try again.\n If this issue" | |
| " continues to occur, copy the newest log from" | |
| " /opt/vmtools/logs and " | |
| "<a href='https://github.com/jmunixusers/cs-vm-build/issues'>" | |
| "create an issue</a>") | |
| dialog.run() | |
| dialog.destroy() | |
| def on_run_clicked(self, button): | |
| try: | |
| release = get_distro_release_name() | |
| except: | |
| dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.ERROR, | |
| Gtk.ButtonsType.YES_NO, "OS Detection error") | |
| dialog.format_secondary_text("The version of your OS could not" \ | |
| " be determined. Use master? This is very dangerous.") | |
| response = dialog.run() | |
| dialog.destroy() | |
| if response is not Gtk.ResponseType.YES: | |
| Gtk.main_quit() | |
| sys.exit(1) | |
| else: | |
| release = "master" | |
| url = get_remote_url() | |
| if not validate_branch(release, url): | |
| invalid_branch(self, release, url) | |
| gksudo_msg = "<b>Enter your password to configure your VM</b>\n" \ | |
| "To configure your virtual machine, administrator" \ | |
| " privileges are required." | |
| self.cancel_button.set_sensitive(False) | |
| os.environ['ANSIBLE_LOG_PATH'] = "/opt/vmtools/logs/log.txt" | |
| self.terminal.env = os.environ.copy() | |
| self.terminal.spawn_sync( | |
| Vte.PtyFlags.DEFAULT, | |
| os.environ['HOME'], | |
| ["/usr/bin/gksudo", "--message", gksudo_msg, "--", | |
| "ansible-pull", "-U", url, | |
| "-C", release, | |
| "--purge", "-i", "hosts", "-t", ",".join(tags)], | |
| [], | |
| GLib.SpawnFlags.DO_NOT_REAP_CHILD, | |
| None, | |
| None, | |
| ) | |
| def parse_user_config(): | |
| try: | |
| with open(user_config_path, "r") as config: | |
| for line in config: | |
| (key, val) = line.split("=") | |
| user_config[key] = val.strip() | |
| except: | |
| pass | |
| def get_distro_release_name(): | |
| release = "" | |
| linux_distribution = platform.linux_distribution()[2] | |
| release = linux_distribution | |
| if (release == ""): | |
| try: | |
| os_release = open("/etc/os-release", "r") | |
| for line in os_release: | |
| version = re.search(r'VERSION_CODENAME=(\w+)', line).group(1) | |
| if version != "": | |
| release = version | |
| break | |
| except: | |
| pass | |
| if "FORCE_BRANCH" in user_config: | |
| release = user_config['FORCE_BRANCH'] | |
| if release == "" or release == " " or release == None: | |
| raise ValueError("Version could not be detected") | |
| return release | |
| def get_remote_url(): | |
| if 'FORCE_GIT_URL' in user_config: | |
| return user_config['FORCE_GIT_URL'] | |
| else: | |
| return "https://github.com/jmunixusers/cs-vm-build" | |
| def validate_branch(branch, remote): | |
| output = subprocess.run(["git", "ls-remote", remote], | |
| stdout=subprocess.PIPE) | |
| branches = output.stdout.decode("utf-8") | |
| return branch in branches | |
| def invalid_branch(parent, release, url): | |
| dialog = Gtk.MessageDialog(parent, 0, Gtk.MessageType.ERROR, | |
| Gtk.ButtonsType.CANCEL, "Invalid release") | |
| dialog.format_secondary_text("This release chosen does not exist" \ | |
| " at the project URL. Please check your settings and try" \ | |
| " again" "\nRelease: " + release + "\nUrl: " + url) | |
| dialog.run() | |
| dialog.destroy() | |
| Gtk.main_quit() | |
| parse_user_config() | |
| win = CheckboxWindow() | |
| win.connect("delete-event", Gtk.main_quit) | |
| win.show_all() | |
| Gtk.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment