| Server IP : 85.214.239.14 / Your IP : 216.73.216.37 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | 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()