Commit 7d922faa authored by Leo Le Bouter's avatar Leo Le Bouter

Upload results to ERP5

TODO: Find a way to properly increment version without having to
      store any additional state client-side

TODO: Investigate using HATEOAS to talk to ERP5

TODO: Investigate using TLS client certificates to authenticate,
      they would be stored in /boot and would prevent the machine
      from booting if they were invalid or missing so that
      tampering with them is not interesting for an attacker.
      Also, the certificate's Common Name should be the computer
      reference and therefore should be used to construct the
      metadata snapshot document's reference instead of having
      to specify it on the command line.
parent d6bebb62
......@@ -8,8 +8,11 @@ import traceback
import hashlib
import io
import multiprocessing
import urllib
import time
from msgpack import dump
import urllib3
from msgpack import dumps
import psutil
import posix1e # pylibacl
......@@ -144,11 +147,71 @@ def construct_fs_tree(mp_pool=None, mp_tasks=[], cur_dict=None, path="/", dev_wh
return cur_dict
def upload_to_erp5(fileobj, size, base_url, username, password, reference):
pool = urllib3.PoolManager()
url = '{0}/portal_contributions/newContent'.format(base_url)
headers = urllib3.make_headers(
keep_alive=True, basic_auth='{0}:{1}'.format(username, password))
resp = pool.request('GET', url, fields={'portal_type': 'File',
'filename': '{0}.metadata'.format(reference),
'container_path': 'document_module',
'data': ''},
headers=headers,
redirect=False)
# workaround for ERP5 disappearing documents race condition bug
time.sleep(3)
upload_path = resp.headers['X-Location']
data = fileobj.read(io.DEFAULT_BUFFER_SIZE)
offset = 0
upload_headers = headers
while data:
upload_headers['Content-Range'] = 'bytes {0}-{1}/{2}'.format(
offset, offset+len(data), size)
pool.urlopen('PUT', upload_path, headers=upload_headers, body=data)
offset += len(data)
data = fileobj.read(io.DEFAULT_BUFFER_SIZE)
parsed = urllib.parse.urlparse(upload_path)
resp = pool.request('POST', upload_path, fields={
'form_id': 'File_view',
'object_path': parsed.path,
'field_my_reference': reference,
'Base_edit:method': '',
},
redirect=False,
headers=headers)
# workaround for ERP5 disappearing documents race condition bug
time.sleep(3)
resp = pool.request('POST', upload_path, fields={
'dialog_id': 'Base_viewWorkflowActionDialog',
'dialog_method': 'Workflow_statusModify',
'form_id': 'File_view',
'object_path': parsed.path,
'field_your_comment': '',
'field_your_workflow_action': 'share_action',
'Base_callDialogMethod:method': '',
},
redirect=False,
headers=headers)
# workaround for ERP5 disappearing documents race condition bug
time.sleep(3)
def main():
parser = argparse.ArgumentParser(
description="Collect and report metadata about a system")
parser.add_argument("start_directory", type=str, default="/")
parser.add_argument("--ignored-dirs", type=str, nargs="+", default=[])
parser.add_argument("--erp5-user", type=str)
parser.add_argument("--erp5-pass", type=str)
parser.add_argument("--erp5-file-reference", type=str)
parser.add_argument("--erp5-base-url", type=str)
args = parser.parse_args()
......@@ -162,7 +225,12 @@ def main():
tree = construct_fs_tree(path=args.start_directory,
dev_whitelist=dev_whitelist, ignored_dirs=args.ignored_dirs)
dump(tree, sys.stdout.buffer)
final = {'disk_partitions': parts, 'fs_tree': tree}
packed = dumps(final)
upload_to_erp5(io.BytesIO(packed), len(packed), args.erp5_base_url,
args.erp5_user, args.erp5_pass, args.erp5_file_reference)
if __name__ == "__main__":
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment