Source code for freezer.engine.tar.tar_builders

"""
(c) Copyright 2014,2015 Hewlett-Packard Development Company, L.P.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Freezer Tar related functions
"""
from freezer.utils import utils


[docs]class TarCommandBuilder(object): """ Building a tar cmd command. To build command invoke method build. """ UNIX_TEMPLATE = ( "{gnutar_path} --create {algo} --warning=none --no-check-device " "--one-file-system --preserve-permissions --same-owner " "--seek --ignore-failed-read") # local windows template WINDOWS_TEMPLATE = ( "{gnutar_path} -c {algo} --incremental --unlink-first " "--ignore-zeros") LISTED_TEMPLATE = "{tar_command} --listed-incremental={listed_incremental}" DEREFERENCE_MODE = {'soft': '--dereference', 'hard': '--hard-dereference', 'all': '--hard-dereference --dereference'} def __init__(self, filepath, compression_algo, is_windows, tar_path=None): self.tar_path = tar_path or utils.tar_path() self.dereference = '' self.listed_incremental = None self.exclude = '' self.openssl_path = None self.encrypt_pass_file = None self.output_file = None self.filepath = filepath self.compression_algo = get_tar_flag_from_algo(compression_algo) self.is_windows = is_windows
[docs] def set_listed_incremental(self, absolute_path): self.listed_incremental = absolute_path
[docs] def set_exclude(self, exclude): self.exclude = exclude
[docs] def set_dereference(self, mode): """ Dereference hard and soft links according option choices. 'soft' dereference soft links, 'hard' dereference hardlinks, 'all' dereference both. Default 'none'. """ self.dereference = self.DEREFERENCE_MODE[mode]
[docs] def set_encryption(self, encrypt_pass_file, openssl_path=None): self.openssl_path = openssl_path or utils.openssl_path() self.encrypt_pass_file = encrypt_pass_file
[docs] def build(self): if self.is_windows: tar_command = self.WINDOWS_TEMPLATE.format( gnutar_path=self.tar_path, algo=self.compression_algo) else: tar_command = self.UNIX_TEMPLATE.format( gnutar_path=self.tar_path, algo=self.compression_algo) if self.dereference: tar_command = "{0} {1}".format(tar_command, self.dereference) if self.listed_incremental: tar_command = self.LISTED_TEMPLATE.format( tar_command=tar_command, listed_incremental=self.listed_incremental) if self.exclude: tar_command = '{tar_command} --exclude="{exclude}"'.format( tar_command=tar_command, exclude=self.exclude) tar_command = '{0} {1}'.format(tar_command, self.filepath) if self.encrypt_pass_file: openssl_cmd = "{openssl_path} enc -aes-256-cfb -pass file:{file}"\ .format(openssl_path=self.openssl_path, file=self.encrypt_pass_file) tar_command = '{0} | {1} && exit ${{PIPESTATUS[0]}}'\ .format(tar_command, openssl_cmd) return tar_command
[docs]class TarCommandRestoreBuilder(object): WINDOWS_TEMPLATE = '{0} -x {1} --incremental --unlink-first ' \ '--ignore-zeros' DRY_RUN_TEMPLATE = '{0} {1} --incremental --list ' \ '--ignore-zeros --warning=none' UNIX_TEMPLATE = '{0} {1} --incremental --extract ' \ '--ignore-zeros --warning=none --overwrite --directory {2}' OPENSSL_DEC = "{openssl_path} enc -d -aes-256-cfb -pass file:{file}" def __init__(self, restore_path, compression_algo, is_windows, tar_path=None): self.dry_run = False self.is_windows = False self.openssl_path = None self.encrypt_pass_file = None self.tar_path = tar_path or utils.tar_path() self.restore_path = restore_path self.compression_algo = get_tar_flag_from_algo(compression_algo) self.is_windows = is_windows
[docs] def set_dry_run(self): self.dry_run = True
[docs] def set_encryption(self, encrypt_pass_file, openssl_path=None): self.openssl_path = openssl_path or utils.openssl_path() self.encrypt_pass_file = encrypt_pass_file
[docs] def build(self): if self.dry_run: tar_command = self.DRY_RUN_TEMPLATE.format(self.tar_path, self.compression_algo) elif self.is_windows: tar_command = self.WINDOWS_TEMPLATE.format(self.tar_path, self.compression_algo) else: tar_command = self.UNIX_TEMPLATE.format(self.tar_path, self.compression_algo, self.restore_path) # Check if encryption file is provided and set the openssl decrypt # command accordingly if self.encrypt_pass_file: openssl_cmd = self.OPENSSL_DEC.format( openssl_path=self.openssl_path, file=self.encrypt_pass_file) tar_command = '{0} | {1} && exit ${{PIPESTATUS[0]}}'\ .format(openssl_cmd, tar_command) return tar_command
[docs]def get_tar_flag_from_algo(compression): algo = { 'gzip': '-z', 'bzip2': '-j', 'xz': '-J', } compression_exec = utils.get_executable_path(compression) if not compression_exec: raise Exception("Critical Error: {0} executable not found ". format(compression)) return algo.get(compression)