Server IP : 85.214.239.14 / Your IP : 3.137.221.114 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/ansible_collections/theforeman/foreman/plugins/modules/ |
Upload File : |
#!/usr/bin/python # -*- coding: utf-8 -*- # (c) 2016, Eric D Helms <ericdhelms@gmail.com> # (c) 2018, Sean O'Keeffe <seanokeeffe797@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = ''' --- module: content_upload version_added: 1.0.0 short_description: Upload content to a repository description: - Allows the upload of content to a repository author: "Eric D Helms (@ehelms)" requirements: - python-debian (For deb Package upload) - rpm (For rpm upload) options: src: description: - File (on the remote/target machine) to upload required: true type: path aliases: - file repository: description: - Repository to upload file in to required: true type: str product: description: - Product to which the repository lives in required: true type: str ostree_repository_name: description: - Name of repository within the OSTree archive. - Required for OSTree uploads. required: false type: str notes: - Currently only uploading to deb, RPM, OSTree & file repositories is supported - For anything but file repositories, a supporting library must be installed. See Requirements. - OSTree content upload is not idempotent - running mutliple times will attempt to upload the content unit. extends_documentation_fragment: - theforeman.foreman.foreman - theforeman.foreman.foreman.organization ''' EXAMPLES = ''' - name: "Upload my.rpm" theforeman.foreman.content_upload: username: "admin" password: "changeme" server_url: "https://foreman.example.com" src: "my.rpm" repository: "Build RPMs" product: "My Product" organization: "Default Organization" - name: "Upload ostree-archive.tar" theforeman.foreman.content_upload: username: "admin" password: "changeme" server_url: "https://foreman.example.com" src: "ostree_archive.tar" repository: "My OStree Repository" product: "My Product" organization: "Default Organization" ostree_repository_name: "small" ''' RETURN = ''' # ''' import os import traceback from ansible.module_utils._text import to_bytes, to_native from ansible_collections.theforeman.foreman.plugins.module_utils.foreman_helper import KatelloAnsibleModule, missing_required_lib try: from debian import debfile HAS_DEBFILE = True DEBFILE_IMP_ERR = None except ImportError: HAS_DEBFILE = False DEBFILE_IMP_ERR = traceback.format_exc() try: import rpm HAS_RPM = True RPM_IMP_ERR = None except ImportError: HAS_RPM = False RPM_IMP_ERR = traceback.format_exc() CONTENT_CHUNK_SIZE = 2 * 1024 * 1024 def get_deb_info(path): control = debfile.DebFile(path).debcontrol() return control['package'], control['version'], control['architecture'] def get_rpm_info(path): ts = rpm.TransactionSet() # disable signature checks, we might not have the key or the file might be unsigned # pre 4.15 RPM needs to use the old name of the bitmask try: vsflags = rpm.RPMVSF_MASK_NOSIGNATURES except AttributeError: vsflags = rpm._RPMVSF_NOSIGNATURES ts.setVSFlags(vsflags) with open(path) as rpmfile: rpmhdr = ts.hdrFromFdno(rpmfile) epoch = rpmhdr[rpm.RPMTAG_EPOCHNUM] name = to_native(rpmhdr[rpm.RPMTAG_NAME]) version = to_native(rpmhdr[rpm.RPMTAG_VERSION]) release = to_native(rpmhdr[rpm.RPMTAG_RELEASE]) arch = to_native(rpmhdr[rpm.RPMTAG_ARCH]) if arch == 'noarch' and rpmhdr[rpm.RPMTAG_SOURCEPACKAGE] == 1: arch = 'src' return (name, epoch, version, release, arch) def main(): module = KatelloAnsibleModule( foreman_spec=dict( src=dict(required=True, type='path', aliases=['file']), repository=dict(required=True, type='entity', scope=['product'], thin=False), product=dict(required=True, type='entity', scope=['organization']), ostree_repository_name=dict(required=False, type='str'), ), ) with module.api_connection(): repository_scope = module.scope_for('repository') b_src = to_bytes(module.foreman_params['src']) filename = os.path.basename(module.foreman_params['src']) checksum = module.sha256(module.foreman_params['src']) content_unit = None if module.foreman_params['repository']['content_type'] == 'deb': if not HAS_DEBFILE: module.fail_json(msg=missing_required_lib("python-debian"), exception=DEBFILE_IMP_ERR) name, version, architecture = get_deb_info(b_src) query = 'name = "{0}" and version = "{1}" and architecture = "{2}"'.format(name, version, architecture) content_unit = module.find_resource('debs', query, params=repository_scope, failsafe=True) elif module.foreman_params['repository']['content_type'] == 'yum': if not HAS_RPM: module.fail_json(msg=missing_required_lib("rpm"), exception=RPM_IMP_ERR) name, epoch, version, release, arch = get_rpm_info(b_src) query = 'name = "{0}" and epoch = "{1}" and version = "{2}" and release = "{3}" and arch = "{4}"'.format(name, epoch, version, release, arch) content_unit = module.find_resource('packages', query, params=repository_scope, failsafe=True) elif module.foreman_params['repository']['content_type'] == 'file': query = 'name = "{0}" and checksum = "{1}"'.format(filename, checksum) content_unit = module.find_resource('file_units', query, params=repository_scope, failsafe=True) elif module.foreman_params['repository']['content_type'] == 'ostree': try: ostree_repository_name = module.foreman_params['ostree_repository_name'] except KeyError: module.fail_json(msg="The 'ostree_repository_name' parameter is required when uploading to OSTree repositories!") else: # possible types in 3.12: docker, ostree, yum, puppet, file, deb module.fail_json(msg="Uploading to a {0} repository is not supported yet.".format(module.foreman_params['repository']['content_type'])) if not content_unit: if not module.check_mode: size = os.stat(module.foreman_params['src']).st_size content_upload_payload = {'size': size} content_upload_payload.update(repository_scope) content_upload = module.resource_action('content_uploads', 'create', content_upload_payload) content_upload_scope = {'id': content_upload['upload_id']} content_upload_scope.update(repository_scope) offset = 0 with open(b_src, 'rb') as contentfile: for chunk in iter(lambda: contentfile.read(CONTENT_CHUNK_SIZE), b""): data = {'content': chunk, 'offset': offset, 'size': size} module.resource_action('content_uploads', 'update', params=content_upload_scope, data=data) offset += len(chunk) uploads = [{'id': content_upload['upload_id'], 'name': filename, 'size': offset, 'checksum': checksum}] import_params = {'id': module.foreman_params['repository']['id'], 'uploads': uploads} if module.foreman_params['repository']['content_type'] == 'ostree': ostree_parameters = {'ostree_repository_name': ostree_repository_name, 'content_type': 'ostree_ref'} import_params.update(ostree_parameters) module.resource_action('repositories', 'import_uploads', import_params) module.resource_action('content_uploads', 'destroy', content_upload_scope) else: module.set_changed() if __name__ == '__main__': main()