Managing GNS3 appliances
![thumbnail for this post](https://dosztal.com/blog/gns3-appliances/cover.png)
Although the GNS3 team makes a lot of effort to keep the appliances up to date,we certainly can’t guarantee that every supported network device’s every release will be included. In such case, you can do two things: submit a request to have the desired version included, or do it yourself. This post is a howto for the latter case.
Please note that I’m focusing on QEMU/KVM appliances because the majority (107 out of 140 at the time of the writing) is using this virtualization technology.
1) Creating a local copy of the GNS3 repository
After registering an account on GitHub, you can start contributing to the GNS3 project.
1a) Forking the repo
Go to the gns3-registry repository and press the “Fork” button. This creates a copy of the repo under your user: <your-username>/gns3-registry (in my case, it’s adosztal/gns3-registry).
1b) Cloning to a local directory
Go to your gns3-registry repository, click on “Clone or download”, then on the button right to the URL, as shown below:
This copied the URL of your repo to the clipboard. Execute the following command on your computer (copy the URL after “git clone”):
adosztal@lab:~/Documents/$ git clone https://github.com/<your-username>/gns3-registry.git
Cloning into 'gns3-registry'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 4532 (delta 6), reused 11 (delta 4), pack-reused 4516
Receiving objects: 100% (4532/4532), 1.74 MiB | 1.16 MiB/s, done.
Resolving deltas: 100% (3045/3045), done.
This created a local copy of your repository on your computer. Note: These examples are executed in Linux but similar functionality is built into GitHub Desktop that you can use on Windows and macOS.
1c) Adding a Remote
Remote repositories are versions of a project that are hosted on the Internet or network somewhere. In our case, we need to add the GNS3/gns3-registry repo; this will come handy later:
adosztal@lab:~/Documents/$ cd gns3-registry
adosztal@lab:~/Documents/gns3-registry$ git remote add upstream https://github.com/GNS3/gns3-registry
Note: All git commands related to your repository can be executed in that repo’s directory only. E.g. in the example above, I switched to gns3-registry before adding the Remote.
You can check the remotes by running “git remote -v”:
adosztal@lab:~/Documents/gns3-registry$ git remote -v
origin https://github.com/adosztal/gns3-registry.git (fetch)
origin https://github.com/adosztal/gns3-registry.git (push)
upstream https://github.com/gns3/gns3-registry.git (fetch)
upstream https://github.com/gns3/gns3-registry.git (push)
2) Editing the appliance
Finally the appliance files are on your computer; you can start editing them. How? I’ll tell you in this section.
2a) The schema
An appliance file is JSON formatted and usually divided into four sections, described below. Note: I only listed to most common properties; for a full list, please check the schema file.
Each section is marked with different colors on this image:
The details of each section are described in this document:
2b) Adding a new version
Updating the appliance file with a new version is not that hard. First, download the image and extract it if necessary. Then you need to get the file’s size using the following commands:
# Windows
dir {filename}
# Linux & macOS
ls -l {filename}
The next step is generating the MD5 hash:
# Windows (PowerShell)
Get-FileHash {filename} -Algorithm MD5 | Format-List
# Linux
md5sum {filename}
# macOS
md5 -r {filename}
Now all you need to do is to copy-paste an old image’s and version’s section, and overwrite the values for all keys. I created a sample; download the following files and compare them:
Important: Make sure you’re using unique filenames, otherwise appliances might overwrite each others images!
3) Committing the changes and create a PR
Now it’s time to apply your changes in your online repository, then get them merged into the official GNS3 repo.
3a) Syntax check
There’s a python script in the repo’s root directory, called check.py, that you can use to check if there are errors in the appliance files. It either returns an OK or gives a hint about the issue:
adosztal@lab:~/Documents/gns3-registry$ python check.py
=> Check appliances
Check forticache.gns3a
Check asterisk.gns3a
Check vrin.gns3a
[...]
=> Check symbols
Check loadbalancer.svg
Check microsoft.svg
Check csr1000v_bybaro.svg
[...]
=> Check packer files
Check openbsd/openbsd.json
Check alpine-linux/alpine-linux.json
Check tinycore-linux/core64-linux.json
[...]
Everything is ok!
3b) Making the commit
If there were no errors in the previous step, you can make the commit. Optionally you can check which files were changed using the “git status” command:
adosztal@lab:~/Documents/gns3-registry$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: appliances/fortiproxy.gns3a
no changes added to commit (use "git add" and/or "git commit -a")
The following command tell git to commit all modified files (-a) with a comment (-m). You should always make a comment when making a commit.
adosztal@lab:~/Documents/gns3-registry$ git commit -a -m "New release"
[master 508e9ef] New release
1 file changed, 14 insertions(+)
Now the changes are staged on you local computer but you still need to upload them:
adosztal@lab:~/Documents/gns3-registry$ git push origin master
Username for 'https://github.com': adosztal
Password for 'https://adosztal@github.com':
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 448 bytes | 448.00 KiB/s, done.
Total 4 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
To https://github.com/adosztal/gns3-registry.git
bb612c7..508e9ef master -> master
This tells git to upload the changes into your repo’s (origin) master branch. You can learn about branches here.
3c) Creating the Pull Request
Now that you’ve uploaded the changes, you can create a Pull Request (PR) to get them merged back into the official repo. Go to your repository, you’ll see that it’s one commit ahead of the official. Click on “Pull request”.
A preliminary comparison of the changes is made. If there’s no conflict, click on the “Create pull request” button.
Fill in the appropriate section (i.e. updated vs. new appliance), then click on “Create pull request”.
The PR is created. Some automated checks are ran to make sure the updated appliance files work.
When the check finishes, your PR is ready to be merged. Please wait for the GNS3 team to review and approve your changes.
3d) Merge
Once the change is approved by the devs, it gets merged to the official repo:
4) Updating your repository
Here’s why we added the remote repos in section 1c). You made your changes and uploaded them but others make commits too; you need a way to synchronize those changes to your local directory. The following three commands get the status of the official GNS3 repo, pull its contents, then push the changes back to your repo on GitHub.
adosztal@lab:~/Documents/gns3-registry$ git fetch upstream
adosztal@lab:~/Documents/gns3-registry$ git pull upstream master
adosztal@lab:~/Documents/gns3-registry$ git push origin master
Conclusion
Managing GNS3 appliances is not that hard. As everything else, it might be a bit confusing in the beginning but the learning curve is not steep. Start with only updating an appliance with a new version, then move on to adding new ones.
Final advices:
- Check your VM’s install/admin guide for the QEMU settings (CPUs, RAM, drivers, etc.).
- Use unique filenames (I know I said this already but it’s very important).
- Always test a new appliance on your box before submitting a PR; you’ll save yourself and others from troubles.
- Don’t be afraid to ask here, on GitHub, or on the GNS3 forum.