Taking backup for znc instance in Python
IRC plays an invaluable role in the life of so many people, separated by so many miles. It has been the primary source of communication for the Free and Open Source community for decades, now. In my last post, I shared how to install a znc bouncer to stay connected persistently to IRC. If you want to stay on top of the comings and goings on, in your favourite communities.
The next step, after installation, is to always create a backup. No sys-admin wants to lose their data. Mainly this was user data for me this time.
So, a backup was needed. But the job of :
- getting into the server
- taking a backup
- scp ing the file down to my computer and then,
- closing the box down,
seemed pretty dull to me.
So why not automate stuff? I choose Python over Bash for this.
(It was the PyLady inside me :))
Create a tarball backup
The 2 directories I need to backup are :
/etc/letsencrypt
: The TLS certificates.
/var/lib/znc/.znc
: The znc data directory.
I learned how to use the tarfile module to create the tar file.
This is the code in my backup.py
#!/usr/bin/env python3
import os
import tarfile
import os.path
from pathlib import Path
from datetime import date
today = str(date.today())
def make_tarfile(output_filename, source_dirs):
with tarfile.open(output_filename, "w:gz") as tar:
for source_dir in source_dirs:
tar.add(source_dir, arcname=os.path.basename(source_dir))
filename = f"znc-dgplug-{today}.tar.gz"
homedir = Path.home()
fullpath = os.path.join(str(homedir), "backups")
if not os.path.exists(fullpath):
os.mkdir(fullpath)
finalpath = os.path.join(fullpath, filename)
make_tarfile(finalpath, ["/etc/letsencrypt", "/var/lib/znc/.znc"])
print(f"Backup is saved at {finalpath}")
Running the code, we get the filepath of the tar file and the date of running the file.
To do the next set of jobs, i.e
- ssh into the server,
- execute backup.py from the command output,
- find the backup filename, and
- scp the filename back into my computer, I wrote a file called runonserver.py.
I am using the paramiko module to ssh into the box and to execute commands. And the scp module is helping me copy the data down into my local machine.
#!/usr/bin/env python3
import paramiko
from scp import SCPClient
import os.path
def create_backup(client):
chan = client.get_transport().open_session()
chan.settimeout(60)
chan.set_combine_stderr(True)
chan.get_pty()
chan.exec_command("/root/backup.py")
stdout = chan.makefile("r", -1)
stderr = chan.makefile_stderr("r", -1)
stdout_text = stdout.read().decode("utf-8").strip("\r\n")
stderr_text = stderr.read()
status = int(chan.recv_exit_status())
return stdout_text, status
def main():
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname="znc.dgplug.org", port=22, username="root")
stdout, status = create_backup(client)
if status != 0:
client.close()
print(f"The command failed with output: {stdout}")
return
filepath = get_filepath(stdout)
scp = SCPClient(client.get_transport())
scp.get(filepath)
scp.close()
client.close()
filename = os.path.basename(filepath)
print(filename)
def get_filepath(cmdoutput):
result = cmdoutput.split()[-1]
return result
if __name__ == "__main__":
main()
This little handy script has made my life really easy. Hopefully, this will help you readers, too.