diff --git a/.gitignore b/.gitignore index e69de29..0926f33 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1 @@ +/gns3-server-1.5.1.tar.gz diff --git a/0001-Move-utils.vmnet-to-gns3-namespace.patch b/0001-Move-utils.vmnet-to-gns3-namespace.patch new file mode 100644 index 0000000..96ab6cb --- /dev/null +++ b/0001-Move-utils.vmnet-to-gns3-namespace.patch @@ -0,0 +1,546 @@ +From fc4a7b440201ccfaae3a45d1d98573cef9f33f09 Mon Sep 17 00:00:00 2001 +From: Athmane Madjoudj +Date: Fri, 29 Jul 2016 17:33:41 +0000 +Subject: [PATCH] Move utils.vmnet to gns3 namespace + +--- + gns3server/utils/vmnet.py | 250 ++++++++++++++++++++++++++++++++++++++++++++++ + setup.py | 2 +- + utils/__init__.py | 0 + utils/vmnet.py | 250 ---------------------------------------------- + 4 files changed, 251 insertions(+), 251 deletions(-) + create mode 100644 gns3server/utils/vmnet.py + delete mode 100644 utils/__init__.py + delete mode 100644 utils/vmnet.py + +diff --git a/gns3server/utils/vmnet.py b/gns3server/utils/vmnet.py +new file mode 100644 +index 0000000..a9be3f1 +--- /dev/null ++++ b/gns3server/utils/vmnet.py +@@ -0,0 +1,250 @@ ++#!/usr/bin/env python ++# -*- 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 sys ++import os ++import ipaddress ++import argparse ++import shutil ++ ++from collections import OrderedDict ++ ++if sys.platform.startswith("darwin"): ++ VMWARE_NETWORKING_FILE = "/Library/Preferences/VMware Fusion/networking" ++else: ++ # location on Linux ++ VMWARE_NETWORKING_FILE = "/etc/vmware/networking" ++ ++if sys.platform.startswith("win"): ++ DEFAULT_RANGE = [1, 19] ++else: ++ DEFAULT_RANGE = [10, 99] ++ ++ ++def parse_networking_file(): ++ """ ++ Parse the VMware networking file. ++ """ ++ ++ pairs = dict() ++ allocated_subnets = [] ++ try: ++ with open(VMWARE_NETWORKING_FILE, "r", encoding="utf-8") as f: ++ version = f.readline() ++ for line in f.read().splitlines(): ++ try: ++ _, key, value = line.split(' ', 3) ++ key = key.strip() ++ value = value.strip() ++ pairs[key] = value ++ if key.endswith("HOSTONLY_SUBNET"): ++ allocated_subnets.append(value) ++ except ValueError: ++ raise SystemExit("Error while parsing {}".format(VMWARE_NETWORKING_FILE)) ++ except OSError as e: ++ raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e)) ++ return version, pairs, allocated_subnets ++ ++ ++def write_networking_file(version, pairs): ++ """ ++ Write the VMware networking file. ++ """ ++ ++ vmnets = OrderedDict(sorted(pairs.items(), key=lambda t: t[0])) ++ try: ++ with open(VMWARE_NETWORKING_FILE, "w", encoding="utf-8") as f: ++ f.write(version) ++ for key, value in vmnets.items(): ++ f.write("answer {} {}\n".format(key, value)) ++ except OSError as e: ++ raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e)) ++ ++ # restart VMware networking service ++ if sys.platform.startswith("darwin"): ++ if not os.path.exists("/Applications/VMware Fusion.app/Contents/Library/vmnet-cli"): ++ raise SystemExit("VMware Fusion is not installed in Applications") ++ os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure") ++ os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop") ++ os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start") ++ else: ++ os.system("vmware-networks --stop") ++ os.system("vmware-networks --start") ++ ++ ++def parse_vmnet_range(start, end): ++ """ ++ Parse the vmnet range on the command line. ++ """ ++ ++ class Range(argparse.Action): ++ ++ def __call__(self, parser, args, values, option_string=None): ++ if len(values) != 2: ++ raise argparse.ArgumentTypeError("vmnet range must consist of 2 numbers") ++ if not start <= values[0] or not values[1] <= end: ++ raise argparse.ArgumentTypeError("vmnet range must be between {} and {}".format(start, end)) ++ setattr(args, self.dest, values) ++ return Range ++ ++ ++def find_vnetlib_registry(regkey): ++ ++ import winreg ++ try: ++ # default path not used, let's look in the registry ++ hkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, regkey) ++ install_path, _ = winreg.QueryValueEx(hkey, "InstallPath") ++ vnetlib_path = os.path.join(install_path, "vnetlib.exe") ++ winreg.CloseKey(hkey) ++ if os.path.exists(vnetlib_path): ++ return vnetlib_path ++ except OSError: ++ pass ++ return None ++ ++ ++def find_vnetlib_on_windows(): ++ ++ vnetlib_path = shutil.which("vnetlib") ++ if vnetlib_path is None: ++ # look for vnetlib.exe in default VMware Workstation directory ++ vnetlib_ws = os.path.expandvars(r"%PROGRAMFILES(X86)%\VMware\VMware Workstation\vnetlib.exe") ++ if os.path.exists(vnetlib_ws): ++ vnetlib_path = vnetlib_ws ++ else: ++ # look for vnetlib.exe using the directory listed in the registry ++ vnetlib_path = find_vnetlib_registry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation") ++ if vnetlib_path is None: ++ # look for vnetlib.exe in default VMware VIX directory ++ vnetlib_vix = os.path.expandvars(r"%PROGRAMFILES(X86)%\VMware\VMware VIX\vnetlib.exe") ++ if os.path.exists(vnetlib_vix): ++ vnetlib_path = vnetlib_vix ++ else: ++ # look for vnetlib.exe using the directory listed in the registry ++ vnetlib_path = find_vnetlib_registry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Player") ++ return vnetlib_path ++ ++ ++def vmnet_windows(args, vmnet_range_start, vmnet_range_end): ++ ++ vnetlib_path = find_vnetlib_on_windows() ++ if not vnetlib_path: ++ raise SystemExit("VMware is not installed, could not find vnetlib.exe") ++ from win32com.shell import shell ++ if not shell.IsUserAnAdmin(): ++ raise SystemExit("You must run this script as an administrator") ++ ++ if args.list: ++ raise SystemExit("Not implemented") ++ ++ if args.clean: ++ # clean all vmnets but vmnet1 and vmnet8 ++ for vmnet_number in range(1, 20): ++ if vmnet_number in (1, 8): ++ continue ++ print("Removing vmnet{}...".format(vmnet_number)) ++ os.system('"{}" -- remove adapter vmnet{}'.format(vnetlib_path, vmnet_number)) ++ else: ++ for vmnet_number in range(vmnet_range_start, vmnet_range_end + 1): ++ if vmnet_number in (1, 8): ++ continue ++ print("Adding vmnet{}...".format(vmnet_number)) ++ os.system('"{}" -- add adapter vmnet{}'.format(vnetlib_path, vmnet_number)) ++ os.system("net stop npf") ++ os.system("net start npf") ++ os.system("net stop npcap") ++ os.system("net start npcap") ++ ++def vmnet_unix(args, vmnet_range_start, vmnet_range_end): ++ """ ++ Implementation on Linux and Mac OS X. ++ """ ++ ++ if not os.path.exists(VMWARE_NETWORKING_FILE): ++ raise SystemExit("VMware Player, Workstation or Fusion is not installed") ++ if not os.access(VMWARE_NETWORKING_FILE, os.W_OK): ++ raise SystemExit("You must run this script as root") ++ ++ version, pairs, allocated_subnets = parse_networking_file() ++ if args.list and not sys.platform.startswith("win"): ++ for vmnet_number in range(1, 256): ++ vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number) ++ if vmnet_name in pairs: ++ print("vmnet{}".format(vmnet_number)) ++ return ++ ++ if args.clean: ++ # clean all vmnets but vmnet1 and vmnet8 ++ for key in pairs.copy().keys(): ++ if key.startswith("VNET_1_") or key.startswith("VNET_8_"): ++ continue ++ del pairs[key] ++ else: ++ for vmnet_number in range(vmnet_range_start, vmnet_range_end + 1): ++ vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number) ++ if vmnet_name in pairs: ++ continue ++ allocated_subnet = None ++ for subnet in ipaddress.ip_network("172.16.0.0/16").subnets(prefixlen_diff=8): ++ subnet = str(subnet.network_address) ++ if subnet not in allocated_subnets: ++ allocated_subnet = subnet ++ allocated_subnets.append(allocated_subnet) ++ break ++ ++ if allocated_subnet is None: ++ print("Couldn't allocate a subnet for vmnet{}".format(vmnet_number)) ++ continue ++ ++ print("Adding vmnet{}...".format(vmnet_number)) ++ pairs["VNET_{}_HOSTONLY_NETMASK".format(vmnet_number)] = "255.255.255.0" ++ pairs["VNET_{}_HOSTONLY_SUBNET".format(vmnet_number)] = allocated_subnet ++ pairs["VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number)] = "yes" ++ ++ write_networking_file(version, pairs) ++ ++ ++def main(): ++ """ ++ Entry point for the VMNET tool. ++ """ ++ ++ parser = argparse.ArgumentParser(description='%(prog)s add/remove vmnet interfaces') ++ parser.add_argument('-r', "--range", nargs='+', action=parse_vmnet_range(1, 255), ++ type=int, help="vmnet range to add (default is {} {})".format(DEFAULT_RANGE[0], DEFAULT_RANGE[1])) ++ parser.add_argument("-C", "--clean", action="store_true", help="remove all vmnets excepting vmnet1 and vmnet8") ++ parser.add_argument("-l", "--list", action="store_true", help="list all existing vmnets (UNIX only)") ++ ++ try: ++ args = parser.parse_args() ++ except argparse.ArgumentTypeError as e: ++ raise SystemExit(e) ++ ++ vmnet_range = args.range if args.range is not None else DEFAULT_RANGE ++ if sys.platform.startswith("win"): ++ try: ++ vmnet_windows(args, vmnet_range[0], vmnet_range[1]) ++ except SystemExit: ++ os.system("pause") ++ raise ++ else: ++ vmnet_unix(args, vmnet_range[0], vmnet_range[1]) ++ ++if __name__ == '__main__': ++ main() +diff --git a/setup.py b/setup.py +index d0c8d0d..8d41046 100644 +--- a/setup.py ++++ b/setup.py +@@ -53,7 +53,7 @@ setup( + entry_points={ + "console_scripts": [ + "gns3server = gns3server.main:main", +- "gns3vmnet = utils.vmnet:main", ++ "gns3vmnet = gns3server.utils.vmnet:main", + ] + }, + packages=find_packages(".", exclude=["docs", "tests"]), +diff --git a/utils/__init__.py b/utils/__init__.py +deleted file mode 100644 +index e69de29..0000000 +diff --git a/utils/vmnet.py b/utils/vmnet.py +deleted file mode 100644 +index a9be3f1..0000000 +--- a/utils/vmnet.py ++++ /dev/null +@@ -1,250 +0,0 @@ +-#!/usr/bin/env python +-# -*- 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 sys +-import os +-import ipaddress +-import argparse +-import shutil +- +-from collections import OrderedDict +- +-if sys.platform.startswith("darwin"): +- VMWARE_NETWORKING_FILE = "/Library/Preferences/VMware Fusion/networking" +-else: +- # location on Linux +- VMWARE_NETWORKING_FILE = "/etc/vmware/networking" +- +-if sys.platform.startswith("win"): +- DEFAULT_RANGE = [1, 19] +-else: +- DEFAULT_RANGE = [10, 99] +- +- +-def parse_networking_file(): +- """ +- Parse the VMware networking file. +- """ +- +- pairs = dict() +- allocated_subnets = [] +- try: +- with open(VMWARE_NETWORKING_FILE, "r", encoding="utf-8") as f: +- version = f.readline() +- for line in f.read().splitlines(): +- try: +- _, key, value = line.split(' ', 3) +- key = key.strip() +- value = value.strip() +- pairs[key] = value +- if key.endswith("HOSTONLY_SUBNET"): +- allocated_subnets.append(value) +- except ValueError: +- raise SystemExit("Error while parsing {}".format(VMWARE_NETWORKING_FILE)) +- except OSError as e: +- raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e)) +- return version, pairs, allocated_subnets +- +- +-def write_networking_file(version, pairs): +- """ +- Write the VMware networking file. +- """ +- +- vmnets = OrderedDict(sorted(pairs.items(), key=lambda t: t[0])) +- try: +- with open(VMWARE_NETWORKING_FILE, "w", encoding="utf-8") as f: +- f.write(version) +- for key, value in vmnets.items(): +- f.write("answer {} {}\n".format(key, value)) +- except OSError as e: +- raise SystemExit("Cannot open {}: {}".format(VMWARE_NETWORKING_FILE, e)) +- +- # restart VMware networking service +- if sys.platform.startswith("darwin"): +- if not os.path.exists("/Applications/VMware Fusion.app/Contents/Library/vmnet-cli"): +- raise SystemExit("VMware Fusion is not installed in Applications") +- os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --configure") +- os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop") +- os.system(r"/Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start") +- else: +- os.system("vmware-networks --stop") +- os.system("vmware-networks --start") +- +- +-def parse_vmnet_range(start, end): +- """ +- Parse the vmnet range on the command line. +- """ +- +- class Range(argparse.Action): +- +- def __call__(self, parser, args, values, option_string=None): +- if len(values) != 2: +- raise argparse.ArgumentTypeError("vmnet range must consist of 2 numbers") +- if not start <= values[0] or not values[1] <= end: +- raise argparse.ArgumentTypeError("vmnet range must be between {} and {}".format(start, end)) +- setattr(args, self.dest, values) +- return Range +- +- +-def find_vnetlib_registry(regkey): +- +- import winreg +- try: +- # default path not used, let's look in the registry +- hkey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, regkey) +- install_path, _ = winreg.QueryValueEx(hkey, "InstallPath") +- vnetlib_path = os.path.join(install_path, "vnetlib.exe") +- winreg.CloseKey(hkey) +- if os.path.exists(vnetlib_path): +- return vnetlib_path +- except OSError: +- pass +- return None +- +- +-def find_vnetlib_on_windows(): +- +- vnetlib_path = shutil.which("vnetlib") +- if vnetlib_path is None: +- # look for vnetlib.exe in default VMware Workstation directory +- vnetlib_ws = os.path.expandvars(r"%PROGRAMFILES(X86)%\VMware\VMware Workstation\vnetlib.exe") +- if os.path.exists(vnetlib_ws): +- vnetlib_path = vnetlib_ws +- else: +- # look for vnetlib.exe using the directory listed in the registry +- vnetlib_path = find_vnetlib_registry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Workstation") +- if vnetlib_path is None: +- # look for vnetlib.exe in default VMware VIX directory +- vnetlib_vix = os.path.expandvars(r"%PROGRAMFILES(X86)%\VMware\VMware VIX\vnetlib.exe") +- if os.path.exists(vnetlib_vix): +- vnetlib_path = vnetlib_vix +- else: +- # look for vnetlib.exe using the directory listed in the registry +- vnetlib_path = find_vnetlib_registry(r"SOFTWARE\Wow6432Node\VMware, Inc.\VMware Player") +- return vnetlib_path +- +- +-def vmnet_windows(args, vmnet_range_start, vmnet_range_end): +- +- vnetlib_path = find_vnetlib_on_windows() +- if not vnetlib_path: +- raise SystemExit("VMware is not installed, could not find vnetlib.exe") +- from win32com.shell import shell +- if not shell.IsUserAnAdmin(): +- raise SystemExit("You must run this script as an administrator") +- +- if args.list: +- raise SystemExit("Not implemented") +- +- if args.clean: +- # clean all vmnets but vmnet1 and vmnet8 +- for vmnet_number in range(1, 20): +- if vmnet_number in (1, 8): +- continue +- print("Removing vmnet{}...".format(vmnet_number)) +- os.system('"{}" -- remove adapter vmnet{}'.format(vnetlib_path, vmnet_number)) +- else: +- for vmnet_number in range(vmnet_range_start, vmnet_range_end + 1): +- if vmnet_number in (1, 8): +- continue +- print("Adding vmnet{}...".format(vmnet_number)) +- os.system('"{}" -- add adapter vmnet{}'.format(vnetlib_path, vmnet_number)) +- os.system("net stop npf") +- os.system("net start npf") +- os.system("net stop npcap") +- os.system("net start npcap") +- +-def vmnet_unix(args, vmnet_range_start, vmnet_range_end): +- """ +- Implementation on Linux and Mac OS X. +- """ +- +- if not os.path.exists(VMWARE_NETWORKING_FILE): +- raise SystemExit("VMware Player, Workstation or Fusion is not installed") +- if not os.access(VMWARE_NETWORKING_FILE, os.W_OK): +- raise SystemExit("You must run this script as root") +- +- version, pairs, allocated_subnets = parse_networking_file() +- if args.list and not sys.platform.startswith("win"): +- for vmnet_number in range(1, 256): +- vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number) +- if vmnet_name in pairs: +- print("vmnet{}".format(vmnet_number)) +- return +- +- if args.clean: +- # clean all vmnets but vmnet1 and vmnet8 +- for key in pairs.copy().keys(): +- if key.startswith("VNET_1_") or key.startswith("VNET_8_"): +- continue +- del pairs[key] +- else: +- for vmnet_number in range(vmnet_range_start, vmnet_range_end + 1): +- vmnet_name = "VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number) +- if vmnet_name in pairs: +- continue +- allocated_subnet = None +- for subnet in ipaddress.ip_network("172.16.0.0/16").subnets(prefixlen_diff=8): +- subnet = str(subnet.network_address) +- if subnet not in allocated_subnets: +- allocated_subnet = subnet +- allocated_subnets.append(allocated_subnet) +- break +- +- if allocated_subnet is None: +- print("Couldn't allocate a subnet for vmnet{}".format(vmnet_number)) +- continue +- +- print("Adding vmnet{}...".format(vmnet_number)) +- pairs["VNET_{}_HOSTONLY_NETMASK".format(vmnet_number)] = "255.255.255.0" +- pairs["VNET_{}_HOSTONLY_SUBNET".format(vmnet_number)] = allocated_subnet +- pairs["VNET_{}_VIRTUAL_ADAPTER".format(vmnet_number)] = "yes" +- +- write_networking_file(version, pairs) +- +- +-def main(): +- """ +- Entry point for the VMNET tool. +- """ +- +- parser = argparse.ArgumentParser(description='%(prog)s add/remove vmnet interfaces') +- parser.add_argument('-r', "--range", nargs='+', action=parse_vmnet_range(1, 255), +- type=int, help="vmnet range to add (default is {} {})".format(DEFAULT_RANGE[0], DEFAULT_RANGE[1])) +- parser.add_argument("-C", "--clean", action="store_true", help="remove all vmnets excepting vmnet1 and vmnet8") +- parser.add_argument("-l", "--list", action="store_true", help="list all existing vmnets (UNIX only)") +- +- try: +- args = parser.parse_args() +- except argparse.ArgumentTypeError as e: +- raise SystemExit(e) +- +- vmnet_range = args.range if args.range is not None else DEFAULT_RANGE +- if sys.platform.startswith("win"): +- try: +- vmnet_windows(args, vmnet_range[0], vmnet_range[1]) +- except SystemExit: +- os.system("pause") +- raise +- else: +- vmnet_unix(args, vmnet_range[0], vmnet_range[1]) +- +-if __name__ == '__main__': +- main() +-- +2.7.4 + diff --git a/gns3-server.spec b/gns3-server.spec new file mode 100644 index 0000000..886af6b --- /dev/null +++ b/gns3-server.spec @@ -0,0 +1,127 @@ +Name: gns3-server +Version: 1.5.1 +Release: 1%{?dist} +Summary: Graphical Network Simulator 3 + +License: GPLv3 +URL: http://gns3.com +Source0: https://github.com/GNS3/gns3-server/archive/v%{version}/%{name}-%{version}.tar.gz +Source1: gns3.service +# Upstream PR #630 +Patch0: 0001-Move-utils.vmnet-to-gns3-namespace.patch + +BuildArch: noarch +BuildRequires: python3-devel +%{?systemd_requires} +BuildRequires: systemd +BuildRequires: git-core +BuildRequires: python-sphinx + +#Requires: busybox +Requires: qemu-kvm +Requires: docker +Requires: python3-jsonschema +Requires: python3-aiohttp +Requires: python3-jinja2 +Requires: python3-raven +Requires: python3-psutil +Requires: python3-zipstream + + +%description +GNS3 is a graphical network simulator that allows you to design complex network +topologies. You may run simulations or configure devices ranging from simple +workstations to powerful routers. + +This is the server package which provides an HTTP REST API for the client (GUI). + +%package doc +Summary: Documentation for %{name} +Requires: %{name} = %{version}-%{release} +%description doc +%{name}-doc package contains documentation. + + +%prep +%autosetup -S git +sed -i 's/aiohttp==0.21.5/aiohttp>=0.21.5/' requirements.txt + +%build +%py3_build + +%install +%py3_install + +# Remove shebang +find %{buildroot}/%{python3_sitelib}/ -name '*.py' -print \ + -exec sed -i '1{\@^#!/usr/bin/env python@d}' {} \; + +# Remove bundled busybox/docker resources +# TODO: fix the code to use system's busybox +rm %{buildroot}/%{python3_sitelib}/gns3server/modules/docker/resources/bin/* +rm %{buildroot}/%{python3_sitelib}/gns3server/modules/docker/resources/init.sh +rm %{buildroot}/%{python3_sitelib}/gns3server/modules/docker/resources/etc/udhcpc/default.script + +# Build the docs +%{make_build} -C docs html +/bin/rm -f docs/_build/html/.buildinfo + +## Systemd service part +mkdir -p %{buildroot}%{_unitdir} +install -m 644 %{SOURCE1} %{buildroot}%{_unitdir} +mkdir -p %{buildroot}%{_sharedstatedir}/gns3 + +%check + + +%files +%license LICENSE +%doc README.rst AUTHORS CHANGELOG +%{python3_sitelib}/gns3_server-%{version}-py*.egg-info/ +%{python3_sitelib}/gns3server/ +%{_bindir}/gns3server +%{_bindir}/gns3vmnet +%{_unitdir}/gns3.service +%dir %attr(2755,gns3,gns3) %{_sharedstatedir}/gns3 + +%files doc +%license LICENSE +%doc docs/_build/html + +%pre +getent group gns3 >/dev/null || groupadd -r gns3 +getent passwd gns3 >/dev/null || \ + useradd -r -g gns3 -d /var/lib/gns3 -s /sbin/nologin \ + -c "gns3 server" gns3 +exit 0 + +%post +[ -d "/var/lib/gns3" ] && chown -R gns3:gns3 %{_sharedstatedir}/gns3 +%systemd_post gns3.service + +%preun +%systemd_preun gns3.service + +%postun +%systemd_postun_with_restart gns3.service + +%changelog +* Tue Aug 02 2016 Athmane Madjoudj - 1.5.1-1 +- Update to 1.5.1 + +* Fri Jul 29 2016 Athmane Madjoudj - 1.5.0-4 +- Fix typo in egg dir +- Build/ship the doc +- update BR + +* Fri Jul 29 2016 Athmane Madjoudj - 1.5.0-3 +- Spec cleanup +- Add patch to move vmnet to gns3 namespace. +- Merge service sub pkg (too small) + +* Thu Jul 07 2016 Athmane Madjoudj - 1.5.0-2 +- Minor spec fixes +- Provide a systemd service + +* Tue Jul 05 2016 Athmane Madjoudj - 1.5.0-1 +- Initial spec diff --git a/gns3.service b/gns3.service new file mode 100644 index 0000000..fce9c5e --- /dev/null +++ b/gns3.service @@ -0,0 +1,16 @@ +[Unit] +Description=GNS3 server + +[Service] +Type=simple +Environment=statedir=/var/lib/gns3 +ExecStart=/usr/bin/gns3server +Restart=on-abort +User=gns3 +Group=gns3 +TimeoutSec=300 + +[Install] +WantedBy=multi-user.target + + diff --git a/sources b/sources index e69de29..959547d 100644 --- a/sources +++ b/sources @@ -0,0 +1 @@ +371d50e3f4e52159620249326a19d0fe gns3-server-1.5.1.tar.gz