Skip to content

Instantly share code, notes, and snippets.

@laurelmay
Last active December 24, 2017 04:27
Show Gist options
  • Save laurelmay/8e8bc9f97514bcda6bfa813d7e7a6f72 to your computer and use it in GitHub Desktop.
Save laurelmay/8e8bc9f97514bcda6bfa813d7e7a6f72 to your computer and use it in GitHub Desktop.
#!/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