#!/usr/bin/python2.7
#
# Univention Appliance Docker Container
#  save data before the image gets removed
#
# Copyright 2015-2020 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

from optparse import OptionParser
import glob
import os
import shutil
import traceback


# Helper function to copy all meta data of a file or directory
def copy_permissions(src, dest):
	s_stat = os.stat(src)
	os.chown(dest, s_stat.st_uid, s_stat.st_gid)
	shutil.copymode(src, dest)
	shutil.copystat(src, dest)
	d_stat = os.stat(dest)


# Helper function to copy the files and directory
def copy_to_persistent_storage(src, dest):
	l_src = src.split('/')
	# Ignore first empty entry
	if l_src[0] == '':
		l_src = l_src[1:]
	for j in range(0, len(l_src)):
		s = os.path.join('/', '/'.join(l_src[0:j + 1]))
		d = os.path.join(dest, '/'.join(l_src[0:j + 1]))
		if os.path.isdir(s):
			if not os.path.exists(d):
				os.makedirs(d)
				copy_permissions(s, d)
		elif os.path.islink(s):
			linkto = os.readlink(s)
			if os.path.exists(d) or os.path.islink(d):
				print 'rm %s' % d
				os.remove(d)
			print 'ln -sf %s %s' % (linkto, d)
			os.symlink(linkto, d)
		else:
			print 'cp %s %s' % (s, d)
			shutil.copy(s, d)
			copy_permissions(s, d)


def copy_files(src, dest):
	for f in glob.glob(src):
		copy_to_persistent_storage(f, dest)


def copy_recursive(src, dest):
	if not os.path.exists(src):
		return
	copy_to_persistent_storage(src, dest)
	for root, dirs, files in os.walk(src):
		for f in files:
			fullpath = os.path.join(root, f)
			copy_to_persistent_storage(fullpath, dest)


if __name__ == '__main__':
	parser = OptionParser('%prog [options]')
	parser.add_option('--app', dest='app', help='App ID')
	parser.add_option('--app-version', dest='app_version', help='Version of App')
	parser.add_option('--error-file', dest='error_file', help='Name of Error File')
	opts, args = parser.parse_args()

	dest = '/var/lib/univention-appcenter/apps/%s/conf/' % opts.app

	# The files and directories below the files directory are restored
	# automatically after the new container has been started
	store = '/var/lib/univention-appcenter/apps/%s/conf/files' % opts.app

	try:
		for f in glob.glob('/etc/univention/base*conf'):
			print 'cp %s %s' % (f, dest)
			shutil.copy(f, dest)
		copy_files('/etc/*.secret', store)
		copy_recursive('/etc/univention/ssl', store)
		copy_recursive('/var/univention-join', store)
		copy_recursive('/var/lib/univention-ldap/', store)
		copy_recursive('/var/lib/univention-directory-listener/', store)
		copy_recursive('/etc/univention/connector', store)
	except:
		traceback.print_exc()
		if opts.error_file:
			error_file = open(opts.error_file, 'a+')
			traceback.print_exc(file=error_file)
			error_file.close()
		raise
