diff --git a/scripts/welcome.py b/scripts/welcome.py
new file mode 100644
index 00000000..23f101cc
--- /dev/null
+++ b/scripts/welcome.py
@@ -0,0 +1,439 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2015 GNS3 Technologies Inc.
+#
+# 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 Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# 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 .
+
+import locale
+import re
+import os
+import sys
+import time
+import subprocess
+import configparser
+import urllib.request
+from dialog import Dialog, PythonDialogBug
+
+try:
+ locale.setlocale(locale.LC_ALL, '')
+except locale.Error:
+ # Not supported via SSH
+ pass
+
+def get_ip():
+ """
+ Return the IP of the eth0
+ """
+ my_ip = subprocess.Popen(['ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1'], stdout=subprocess.PIPE, shell=True)
+ (IP,errors) = my_ip.communicate()
+ my_ip.stdout.close()
+ if len(IP) == 0:
+ return None
+ return IP.decode().strip()
+
+
+def get_config():
+ """
+ Read the config
+ """
+ config = configparser.RawConfigParser()
+ path = os.path.expanduser("~/.config/GNS3/gns3_server.conf")
+ config.read([path], encoding="utf-8")
+ return config
+
+
+def write_config(config):
+ """
+ Write the config file
+ """
+
+ with open(os.path.expanduser("~/.config/GNS3/gns3_server.conf"), 'w') as f:
+ config.write(f)
+
+
+def gns3_major_version():
+ """
+ Returns the GNS3 major server version
+ """
+
+ version = gns3_version()
+ if version:
+ match = re.search(r"\d+.\d+", version)
+ return match.group(0)
+ return ""
+
+
+def gns3_version():
+ """
+ Return the GNS3 server version
+ """
+ try:
+ return subprocess.check_output(["gns3server", "--version"]).strip().decode()
+ except (subprocess.CalledProcessError, FileNotFoundError):
+ return None
+
+
+def gns3vm_version():
+ """
+ Return the GNS3 VM version
+ """
+ with open('/home/gns3/.config/GNS3/gns3vm_version') as f:
+ return f.read().strip()
+
+
+d = Dialog(dialog="dialog", autowidgetsize=True)
+if gns3_version() is None:
+ d.set_background_title("GNS3")
+else:
+ d.set_background_title("GNS3 {}".format(gns3_version()))
+
+
+def mode():
+ if d.yesno("This feature is for testers only. You may break your GNS3 installation. Are you REALLY sure you want to continue?", yes_label="Exit (Safe option)", no_label="Continue") == d.OK:
+ return
+ code, tag = d.menu("Select the GNS3 version",
+ choices=[("2.1", "Stable release for this GNS3 VM (RECOMMENDED)"),
+ ("2.1dev", "Development version for stable release"),
+ ("2.2", "Latest stable release")])
+ d.clear()
+ if code == Dialog.OK:
+ os.makedirs(os.path.expanduser("~/.config/GNS3"), exist_ok=True)
+ with open(os.path.expanduser("~/.config/GNS3/gns3_release"), "w+") as f:
+ f.write(tag)
+
+ update(force=True)
+
+
+def get_release():
+ try:
+ with open(os.path.expanduser("~/.config/GNS3/gns3_release")) as f:
+ content = f.read()
+
+ # Support old VM versions
+ if content == "stable":
+ content = "1.5"
+ elif content == "testing":
+ content = "1.5"
+ elif content == "unstable":
+ content = "1.5dev"
+
+ return content
+ except OSError:
+ return "1.5"
+
+
+def update(force=False):
+ if not force:
+ if d.yesno("PLEASE SNAPSHOT THE VM BEFORE RUNNING THE UPGRADE IN CASE OF FAILURE. The server will reboot at the end of the upgrade process. Continue?") != d.OK:
+ return
+ release = get_release()
+ if release == "2.2":
+ if d.yesno("It is recommended to run GNS3 version 2.2 with lastest GNS3 VM based on Ubuntu 18.04 LTS, please download this VM from our website or continue at your own risk!") != d.OK:
+ return
+ if release.endswith("dev"):
+ ret = os.system("curl -Lk https://raw.githubusercontent.com/GNS3/gns3-vm/unstable/scripts/update_{}.sh > /tmp/update.sh && bash -x /tmp/update.sh".format(release))
+ else:
+ ret = os.system("curl -Lk https://raw.githubusercontent.com/GNS3/gns3-vm/master/scripts/update_{}.sh > /tmp/update.sh && bash -x /tmp/update.sh".format(release))
+ if ret != 0:
+ print("ERROR DURING UPGRADE PROCESS PLEASE TAKE A SCREENSHOT IF YOU NEED SUPPORT")
+ time.sleep(15)
+
+
+def migrate():
+ """
+ Migrate GNS3 VM data.
+ """
+
+ code, option = d.menu("Select an option",
+ choices=[("Setup", "Configure this VM to send data to another GNS3 VM"),
+ ("Send", "Send images and projects to another GNS3 VM")])
+ d.clear()
+ if code == Dialog.OK:
+ (answer, destination) = d.inputbox("What is IP address or hostname of the other GNS3 VM?", init="172.16.1.128")
+ if answer != d.OK:
+ return
+ if destination == get_ip():
+ d.msgbox("The destination cannot be the same as this VM IP address ({})".format(destination))
+ return
+ if option == "Send":
+ # first make sure they are no files belonging to root
+ os.system("sudo chown -R gns3:gns3 /opt/gns3")
+ # then rsync the data
+ command = r"rsync -az --progress -e 'ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /home/gns3/.ssh/gns3-vm-key' /opt/gns3 gns3@{}:/opt".format(destination)
+ ret = os.system('bash -c "{}"'.format(command))
+ time.sleep(10)
+ if ret != 0:
+ d.msgbox("Could not send data to the other GNS3 VM located at {}".format(destination))
+ else:
+ d.msgbox("Images and projects have been successfully sent to the other GNS3 VM located at {}".format(destination))
+ elif option == "Setup":
+ script = """
+if [ ! -f ~/.ssh/gns3-vm-key ]
+then
+ ssh-keygen -f ~/.ssh/gns3-vm-key -N '' -C gns3@{}
+fi
+ssh-copy-id -i ~/.ssh/gns3-vm-key gns3@{}
+""".format(get_ip(), destination)
+ ret = os.system('bash -c "{}"'.format(script))
+ time.sleep(10)
+ if ret != 0:
+ d.msgbox("Error while setting up the migrate feature")
+ else:
+ d.msgbox("Configuration successful, you can now send data to the GNS3 VM located at {} without password".format(destination))
+
+
+def shrink_disk():
+
+ ret = os.system("lspci | grep -i vmware")
+ if ret != 0:
+ d.msgbox("Shrinking the disk is only supported when running inside VMware")
+ return
+
+ if d.yesno("Would you like to shrink the VM disk? The VM will reboot at the end of the process. Continue?") != d.OK:
+ return
+
+ os.system("sudo service gns3 stop")
+ os.system("sudo service docker stop")
+ os.system("sudo vmware-toolbox-cmd disk shrink /opt")
+ os.system("sudo vmware-toolbox-cmd disk shrink /")
+
+ d.msgbox("The GNS3 VM will reboot")
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+
+def vm_information():
+ """
+ Show IP, SSH settings....
+ """
+
+ content = "Welcome to GNS3 appliance\n\n"
+
+ version = gns3_version()
+ if version is None:
+ content += "GNS3 is not installed please install it with sudo pip3 install gns3-server. Or download a preinstalled VM.\n\n"
+ else:
+ content = "GNS3 version: {gns3_version}\nVM version: {gns3vm_version}\nKVM support available: {kvm}\n\n".format(
+ gns3vm_version=gns3vm_version(),
+ gns3_version=version,
+ kvm=kvm_support())
+
+ ip = get_ip()
+
+ if ip:
+ content += "IP: {ip}\n\nTo log in using SSH:\nssh gns3@{ip}\nPassword: gns3\n\nImages and projects are located in /opt/gns3""".format(ip=ip)
+ else:
+ content += "eth0 is not configured. Please manually configure it via the Networking menu."
+
+ content += "\n\nRelease channel: " + get_release()
+
+ try:
+ d.msgbox(content)
+ # If it's an scp command or any bugs
+ except:
+ os.execvp("bash", ['/bin/bash'])
+
+
+def check_internet_connectivity():
+ d.pause("Please wait...\n\n")
+ try:
+ response = urllib.request.urlopen('http://pypi.python.org/', timeout=5)
+ except urllib.request.URLError as err:
+ d.infobox("Can't connect to Internet (pypi.python.org): {}".format(str(err)))
+ time.sleep(15)
+ return
+ d.infobox("Connection to Internet: OK")
+ time.sleep(2)
+
+
+def keyboard_configuration():
+ """
+ Allow user to change the keyboard layout
+ """
+ os.system("/usr/bin/sudo dpkg-reconfigure keyboard-configuration")
+
+
+def set_security():
+ config = get_config()
+ if d.yesno("Enable server authentication?") == d.OK:
+ if not config.has_section("Server"):
+ config.add_section("Server")
+ config.set("Server", "auth", True)
+ (answer, text) = d.inputbox("Login?")
+ if answer != d.OK:
+ return
+ config.set("Server", "user", text)
+ (answer, text) = d.passwordbox("Password?")
+ if answer != d.OK:
+ return
+ config.set("Server", "password", text)
+ else:
+ config.set("Server", "auth", False)
+
+ write_config(config)
+
+
+def log():
+ os.system("/usr/bin/sudo chmod 755 /var/log/upstart/gns3.log")
+ with open("/var/log/upstart/gns3.log") as f:
+ try:
+ while True:
+ line = f.readline()
+ sys.stdout.write(line)
+ except (KeyboardInterrupt, MemoryError):
+ return
+
+
+def edit_config():
+ """
+ Edit GNS3 configuration file
+ """
+
+ major_version = gns3_major_version()
+ if major_version == "2.2":
+ os.system("nano ~/.config/GNS3/{}/gns3_server.conf".format(major_version))
+ else:
+ os.system("nano ~/.config/GNS3/gns3_server.conf")
+
+
+def edit_network():
+ """
+ Edit network configuration file
+ """
+ if d.yesno("The server will reboot at the end of the process. Continue?") != d.OK:
+ return
+ os.system("sudo nano /etc/network/interfaces")
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+
+
+def edit_proxy():
+ """
+ Configure proxy settings
+ """
+ res, http_proxy = d.inputbox(text="HTTP proxy string, for example http://:@:. Leave empty for no proxy.")
+ if res != d.OK:
+ return
+ res, https_proxy = d.inputbox(text="HTTPS proxy string, for example http://:@:. Leave empty for no proxy.")
+ if res != d.OK:
+ return
+
+ with open('/tmp/00proxy', 'w+') as f:
+ f.write('Acquire::http::Proxy "' + http_proxy + '";')
+ os.system("sudo mv /tmp/00proxy /etc/apt/apt.conf.d/00proxy")
+ os.system("sudo chown root /etc/apt/apt.conf.d/00proxy")
+ os.system("sudo chmod 744 /etc/apt/apt.conf.d/00proxy")
+
+ with open('/tmp/proxy.sh', 'w+') as f:
+ f.write('export http_proxy="' + http_proxy + '"\n')
+ f.write('export https_proxy="' + https_proxy + '"\n')
+ f.write('export HTTP_PROXY="' + http_proxy + '"\n')
+ f.write('export HTTPS_PROXY="' + https_proxy + '"\n')
+ os.system("sudo mv /tmp/proxy.sh /etc/profile.d/proxy.sh")
+ os.system("sudo chown root /etc/profile.d/proxy.sh")
+ os.system("sudo chmod 744 /etc/profile.d/proxy.sh")
+ os.system("sudo cp /etc/profile.d/proxy.sh /etc/default/docker")
+
+ d.msgbox("The GNS3 VM will reboot")
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+
+
+def kvm_support():
+ """
+ Returns true if KVM is available
+ """
+ return subprocess.call("kvm-ok") == 0
+
+
+def kvm_control():
+ """
+ Check if KVM is correctly configured
+ """
+
+ kvm_ok = kvm_support()
+ config = get_config()
+ try:
+ if config.getboolean("Qemu", "enable_kvm") is True:
+ if kvm_ok is False:
+ if d.yesno("KVM is not available!\n\nQemu VM will crash!!\n\nThe reason could be unsupported hardware or another virtualization solution is already running.\n\nDisable KVM and get lower performances?") == d.OK:
+ config.set("Qemu", "enable_kvm", False)
+ write_config(config)
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+ else:
+ if kvm_ok is True:
+ if d.yesno("KVM is available on your computer.\n\nEnable KVM and get better performances?") == d.OK:
+ config.set("Qemu", "enable_kvm", True)
+ write_config(config)
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+ except configparser.NoSectionError:
+ return
+
+
+vm_information()
+kvm_control()
+
+
+try:
+ while True:
+ code, tag = d.menu("GNS3 {}".format(gns3_version()),
+ choices=[("Information", "Display VM information"),
+ ("Upgrade", "Upgrade GNS3"),
+ ("Migrate", "Migrate data to another GNS3 VM"),
+ ("Shell", "Open a console"),
+ ("Security", "Configure authentication"),
+ ("Keyboard", "Change keyboard layout"),
+ ("Configure", "Edit server configuration (advanced users ONLY)"),
+ ("Proxy", "Configure proxy settings"),
+ ("Networking", "Configure networking settings"),
+ ("Log", "Show server log"),
+ ("Test", "Check internet connection"),
+ ("Shrink", "Shrink the VM disk"),
+ ("Version", "Select the GNS3 version"),
+ ("Restore", "Restore the VM (if you have trouble for upgrade)"),
+ ("Reboot", "Reboot the VM"),
+ ("Shutdown", "Shutdown the VM")])
+ d.clear()
+ if code == Dialog.OK:
+ if tag == "Shell":
+ os.execvp("bash", ['/bin/bash'])
+ elif tag == "Version":
+ mode()
+ elif tag == "Restore":
+ os.execvp("sudo", ['/usr/bin/sudo', "/usr/local/bin/gns3restore"])
+ elif tag == "Reboot":
+ os.execvp("sudo", ['/usr/bin/sudo', "reboot"])
+ elif tag == "Shutdown":
+ os.execvp("sudo", ['/usr/bin/sudo', "poweroff"])
+ elif tag == "Upgrade":
+ update()
+ elif tag == "Information":
+ vm_information()
+ elif tag == "Log":
+ log()
+ elif tag == "Migrate":
+ migrate()
+ elif tag == "Configure":
+ edit_config()
+ elif tag == "Networking":
+ edit_network()
+ elif tag == "Security":
+ set_security()
+ elif tag == "Keyboard":
+ keyboard_configuration()
+ elif tag == "Test":
+ check_internet_connectivity()
+ elif tag == "Proxy":
+ edit_proxy()
+ elif tag == "Shrink":
+ shrink_disk()
+except KeyboardInterrupt:
+ sys.exit(0)
\ No newline at end of file