Backup
Use python to automatically backup Proxmox Virutal Machine to Remote Server!

Use python to automatically backup Proxmox Virutal Machine to Remote Server!

Recently proxmox has been used by a lot of companies for various reasons, I’ve already written quite a few articles on Proxmox. Virtual Machines backups are a really important issue for any organization because disasters can happen anywhere and anytime, so we must be careful and have backups in case anything goes wrong.

Proxmox by default offers a really nice way of backing up virtual machines through the graphical user interface as well from the command line but backups are only stored in the local storage, in this article, we will see that how we can use Python to automatically backup proxmox virtual machines to a remote server using SCP protocol. We are going to write a small script that will do the trick. If you are interested in doing this manually you can read our previous article:

How to backup and transfer a Proxmox VM to another Proxmox Node

So, let see how we can do this automatically using python.

Step 1: Identify Virtual Machine ID

The first thing you need to do is to identify the virtual machine ID that you are going to take backup of, there are two ways to identify virtual machine id in proxmox. One is through their browser based GUI control panel and other is through the command line.

Using GUI

Open your proxmox installation through the following URL on any browser of your choice:

https://<ip address>:8006

It will then ask for your login credentials, once logged in you can see the list of virtual machines, and your virtual machine ID will look something like this:

Arrow points towards the virtual machine ID, now you can identify the VPS for which you need to take backup and note down its ID.

Using Command Line

Command line can also be used to list virtual machines, you can log into the ssh of your server and execute the following command:

qm list

This will print out the name of virtual machines, as seen in the image below:

First arrow points towards the command, and seconds towards the virtual machine ID. Once you are sure about virtual machine ID, we are ready to write our python code.

Step 2: Write Python Function that initiates backup!

Once you know the virtual machine ID, you are ready to initiate its backup using python. Currently, this backup will reside on the same server where the virtual machine is hosted, later we will use SCP protocol to move this virtual machine to a remote server. I’ve written the function that will do the trick:

import subprocess
import sys

def initiateBackup(vmID):

    # Lets build command to execute

    command = []
    command.append("vzdump")
    command.append(vmID)

    # Executing the command

    result = subprocess.call(command)

    if(result==0):
        return "OK"
    else:
        print("Backup was not successfull.")
        sys.exit()

Well, let us discuss this function line by line.

First two lines

First two lines are a simple module’s import that we are going to need in executing our commands.

From line 8-10

We’ve first created an empty list, so that we can build our command that will be executed, in other words, it is simply writing your command on the shell i.e:

vzdump <vmid>

However this time it is done through python.

Line 14th

Is the actual execution of our command, it is similar to pressing enter on command line once you are done writing your command. This function call can return 2 possible values.

  • “0” – If command executed successfully.
  • “1” – If the command is not executed successfully.

We store the return value in variable “result”, so if the value is “0” we return “OK”, otherwise we exit the program execution. This piece of code will simply initiate the backup process and once this process is successfully executed backup file will be stored in the directory: /var/lib/vz/dump/

Step 3: Get the Backup File Name

Once the backup is created and stored in the backup directory we’ve to write code that will pick the file name of the backup file just created above, because without the file name we can not send it over via SCP. A piece of code below will do the trick:

def getPath(vmID):

    import os

    for file in os.listdir("/var/lib/vz/dump"):

        if file.endswith(".vma") and (file.find("vzdump-qemu-"+vmID)>-1):

            return "/var/lib/vz/dump/"+file

Let us discuss this code line by line.

Line 3

On line 3 we did a simple import of “os” module that will help us identify the files in the directory.

Line 5 to 9

From line 5-9 we’ve written a code that will first save all files names ( files that are present inside “/var/lib/vz/dump” directory) in a variable called “file”, we will then iterate through this variable and find the file name that we need.

Now when proxmox generate a backup file it always contains virtual machine ID inside it and the backup file ends with “vma”, so we’ve used some basic logic of string manipulation to find the file name, you can use any logic that suits you. An example of the backup file name is:

vzdump-qemu-101-2017_05_31-14_26_49.vma (Bold part is virtual machine ID)

Now if the string contains virtual machine ID inside it and it ends with “vma” then that means it is the file that we are looking for, once you find this line you can use return to return its name to the calling function. This is important because we will need a complete file path later to send this file over SCP because if we don’t know that path we can not send the file.

Step 4: Send file via SCP!

Finally, the step we’ve all been waiting for, once all the steps mentioned above are completed we are ready to send our proxmox virtual machine to the remote server. I’ve written a code that will do this job:

def sendFileViaSCP(ipAddress,srcFile,destination):

    print("#####################################################")
    print("                  Sending via scp                    ")
    print("#####################################################")

    # Lets build command to execute

    command = []
    command.append("scp")
    command.append(srcFile)
    command.append("root"+"@"+ipAddress+":"+destination)


    # Executing the command

    result = subprocess.call(command)

    if (result == 0):
        print("#####################################################")
        print("               File Sent via scp                     ")
        print("#####################################################")
        return "OK"
    else:
        print("Backup File Not Sent")
        sys.exit()

Line 9-12

As we’ve done in the second step, we’ve to repeat the same again, we need to define a command and that command will then be executed via python. So command will be defined in the form of a list because python command execution function takes a list and execute it as a command. This is simply writing following on the command line:

SCP filename root@ipaddress:/

Line 17

On line 17 we have just executed the command.

Line 19 and onwards

As I’ve also written in step 2 when Python forks a process, process have two possible return values.

  • 0 – Process executed successfully.
  • 1 – Process has some issues.

So we track the return value and see if our SCP transfer process went successfully or end up with errors. Please note that on the command line after the execution of SCP command it will ask you for the password of your remote server, you will have to provide so that transfer process can continue.

Step 5: Write the main function!

The main function is nothing much important, just some housekeeping stuff. We need to pass virtual machine id to all those functions that we’ve written above, so the main function will do all that stuff.

def Main():
    
    initiateBackup("101")
    src = getPath("101")

    ipAddress = "94.176.233.214"
    username = "root"
    destination = "/root"

    sendFileViaSCP(ipAddress,src,destination)

Firstly the main function will call the “initiateBackup” function with virtual machine ID, and backup of virtual machine id “101” will be generated. We will then call the “getPath” function with same virtual machine id to get the exact location of the backup file. Then we finally call “sendFileViaSCP” function with IP address, source file location, and destination path to send this file via SCP to a remote server.

Conclusion

I’ve explained the general overview that how this can be achieved through python. However, error checking was not completely taken care in case there are some failures. So if you are looking to do this in production environment make sure proper error checking is in place.

If you have any questions feel free to put them in the comment box below.

Leave a Reply

Your email address will not be published. Required fields are marked *