aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'elivepatch_server')
-rw-r--r--elivepatch_server/__init__.py0
-rw-r--r--elivepatch_server/elivepatch41
-rw-r--r--elivepatch_server/requirements.txt2
-rw-r--r--elivepatch_server/resources/AgentInfo.py54
-rw-r--r--elivepatch_server/resources/__init__.py9
-rw-r--r--elivepatch_server/resources/dispatcher.py171
-rw-r--r--elivepatch_server/resources/livepatch.py134
-rw-r--r--elivepatch_server/setup.py12
8 files changed, 0 insertions, 423 deletions
diff --git a/elivepatch_server/__init__.py b/elivepatch_server/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/elivepatch_server/__init__.py
+++ /dev/null
diff --git a/elivepatch_server/elivepatch b/elivepatch_server/elivepatch
deleted file mode 100644
index cd14f75..0000000
--- a/elivepatch_server/elivepatch
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
-# Distributed under the terms of the GNU General Public License v2 or later
-
-
-from flask import Flask
-from flask_restful import Api
-from elivepatch_server.resources import AgentInfo, dispatcher
-
-
-def create_app():
- """
- Create server application
- RESTful api version 1.0
- """
-
- app = Flask(__name__, static_url_path="")
- api = Api(app)
-
- api.add_resource(AgentInfo.AgentAPI, '/elivepatch/api/',
- endpoint='root')
-
- # get agento information
- api.add_resource(AgentInfo.AgentAPI, '/elivepatch/api/v1.0/agent',
- endpoint='agent')
-
- # where to retrieve the live patch when ready
- api.add_resource(dispatcher.SendLivePatch,
- '/elivepatch/api/v1.0/send_livepatch',
- endpoint='send_livepatch')
-
- # where to receive the config file
- api.add_resource(dispatcher.GetFiles, '/elivepatch/api/v1.0/get_files',
- endpoint='config')
- return app
-
-if __name__ == '__main__':
- app = create_app()
- app.run(debug=True, host='0.0.0.0', threaded=True)
diff --git a/elivepatch_server/requirements.txt b/elivepatch_server/requirements.txt
deleted file mode 100644
index 1aff942..0000000
--- a/elivepatch_server/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-flask
-flask_restful \ No newline at end of file
diff --git a/elivepatch_server/resources/AgentInfo.py b/elivepatch_server/resources/AgentInfo.py
deleted file mode 100644
index 495512a..0000000
--- a/elivepatch_server/resources/AgentInfo.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
-# Distributed under the terms of the GNU General Public License v2 or later
-
-from flask_restful import Resource, reqparse, fields, marshal
-
-agent_fields = {
- 'module': fields.String,
- 'version': fields.String,
-}
-
-
-def agentinfo(module=None):
- """
- :rtype: object
- """
- agents = []
- agent = {
- 'id': 1,
- 'module': 'elivepatch',
- 'version' : '0.01',
- }
- agents.append(agent)
- return agents
-
-agents = agentinfo()
-
-
-class AgentAPI(Resource):
-
- def __init__(self):
- self.reqparse = reqparse.RequestParser()
- self.reqparse.add_argument('module', type=str, required=True,
- help='No task title provided',
- location='json')
- self.reqparse.add_argument('version', type=str, required=True,
- help='No task title provided',
- location='json')
- super(AgentAPI, self).__init__()
-
- def get(self):
- return {'agent': [marshal(host, agent_fields) for host in agents]}
-
- def post(self):
- args = self.reqparse.parse_args()
- host = {
- 'id': agents[-1]['id'] + 1,
- 'module': args['module'],
- 'version': args['version'],
- }
- agents.append(host)
- return {'agent': marshal(host, agent_fields)}, 201
diff --git a/elivepatch_server/resources/__init__.py b/elivepatch_server/resources/__init__.py
deleted file mode 100644
index 7797189..0000000
--- a/elivepatch_server/resources/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
-# Distributed under the terms of the GNU General Public License v2 or later
-
-__version__ = '0.0.1'
-__author__ = 'Alice Ferrazzi'
-__license__ = 'GNU GPLv2+' \ No newline at end of file
diff --git a/elivepatch_server/resources/dispatcher.py b/elivepatch_server/resources/dispatcher.py
deleted file mode 100644
index 92fbe4e..0000000
--- a/elivepatch_server/resources/dispatcher.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
-# Distributed under the terms of the GNU General Public License v2 or later
-
-
-import re
-
-import os
-import werkzeug
-from flask import jsonify, make_response
-from flask_restful import Resource, reqparse, fields, marshal
-
-from elivepatch_server.resources.livepatch import PaTch
-
-pack_fields = {
- 'KernelVersion': fields.String,
- 'UUID': fields.String
-
-}
-
-packs = {
- 'id': 1,
- 'KernelVersion': None,
- 'UUID': None
-}
-
-
-def check_uuid(uuid):
- """
- Check uuid is in the correct format
- :param uuid:
- :return:
- """
- if not uuid:
- print('uuid is missing')
- else:
- # check uuid format
- prog = re.compile('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')
- result = prog.match(uuid)
- if result:
- print('UUID: ' + str(uuid))
- return uuid
- print('uuid format is not correct')
-
-
-def get_uuid_dir(uuid):
- return os.path.join('/tmp/', 'elivepatch-' + uuid)
-
-
-class SendLivePatch(Resource):
-
- def __init__(self):
- self.reqparse = reqparse.RequestParser()
- self.reqparse.add_argument('KernelVersion', type=str, required=False,
- help='No task title provided',
- location='json')
- self.reqparse.add_argument('UUID', type=str, required=False,
- help='No task title provided',
- location='json')
- super(SendLivePatch, self).__init__()
- pass
-
- def get(self):
- args = self.reqparse.parse_args()
- print("get livepatch: " + str(args))
- # check if is a valid UUID request
- args['UUID'] = check_uuid(args['UUID'])
- uuid_dir = get_uuid_dir(args['UUID'])
-
- livepatch_full_path = os.path.join(uuid_dir, 'kpatch-main.ko')
- try:
- with open(livepatch_full_path, 'rb') as fp:
- response = make_response(fp.read())
- response.headers['content-type'] = 'application/octet-stream'
- return response
- except:
- return make_response(jsonify({'message': 'These are not the \
- patches you are looking for'}), 403)
-
- def post(self):
- return make_response(jsonify({'message': 'These are not the \
- patches you are looking for'}), 403)
-
-
-class GetFiles(Resource):
-
- def __init__(self):
- self.reqparse = reqparse.RequestParser()
- self.reqparse.add_argument('KernelVersion', type=str, required=False,
- help='No task title provided',
- location='headers')
- self.reqparse.add_argument('UUID', type=str, required=False,
- help='No task title provided',
- location='headers')
- super(GetFiles, self).__init__()
- pass
-
- def get(self):
- return make_response(jsonify({'message': 'These are not the \
- patches you are looking for'}), 403)
-
- def post(self):
- args = self.reqparse.parse_args()
- args['UUID'] = check_uuid(args['UUID'])
- parse = reqparse.RequestParser()
- parse.add_argument('patch', action='append', type=werkzeug.datastructures.FileStorage,
- location='files')
- parse.add_argument('main_patch', action='append', type=werkzeug.datastructures.FileStorage,
- location='files')
- parse.add_argument('config', type=werkzeug.datastructures.FileStorage,
- location='files')
- file_args = parse.parse_args()
-
- lpatch = PaTch()
-
- print("file get config: " + str(file_args))
- configFile = file_args['config']
- configFile_name = file_args['config'].filename
-
- # saving config file
- configFile_name = os.path.join('/tmp','elivepatch-' + args['UUID'], configFile_name)
- if os.path.exists('/tmp/elivepatch-' + args['UUID']):
- print('the folder: "/tmp/elivepatch-' + args['UUID'] + '" is already present')
- return {'the request with ' + args['UUID'] + ' is already present'}, 201
- else:
- print('creating: "/tmp/elivepatch-' + args['UUID'])
- os.makedirs('/tmp/elivepatch-' + args['UUID'])
-
- configFile.save(configFile_name)
-
-
- # saving incremental patches
- incremental_patches_directory = os.path.join('/tmp', 'elivepatch-' + args['UUID'], 'etc', 'portage', 'patches',
- 'sys-kernel', 'gentoo-sources')
- if os.path.exists(incremental_patches_directory):
- print('the folder: "/tmp/elivepatch-' + args['UUID'] + '" is already present')
- return {'the request with ' + args['UUID'] + ' is already present'}, 201
- else:
- print('creating: '+incremental_patches_directory)
- os.makedirs(incremental_patches_directory)
- try:
- for patch in file_args['patch']:
- print(str(patch))
- patchfile = patch
- patchfile_name = patch.filename
- patch_fulldir_name = os.path.join(incremental_patches_directory, patchfile_name)
- patchfile.save(patch_fulldir_name)
- except:
- print('no incremental patches')
-
- # saving main patch
- print(str(file_args['main_patch']))
- main_patchfile = file_args['main_patch'][0]
- main_patchfile_name = main_patchfile.filename
- main_patch_fulldir_name = os.path.join('/tmp','elivepatch-' + args['UUID'], main_patchfile_name)
- main_patchfile.save(main_patch_fulldir_name)
-
- # check vmlinux presence if not rebuild the kernel
- kernel_sources_status = lpatch.get_kernel_sources(args['UUID'], args['KernelVersion'])
- if not kernel_sources_status:
- return make_response(jsonify({'message': 'gentoo-sources not available'}), 403)
- lpatch.build_livepatch(args['UUID'], 'vmlinux')
-
- pack = {
- 'id': packs['id'] + 1,
- 'KernelVersion': None,
- 'UUID' : args['UUID']
- }
- return {'get_config': marshal(pack, pack_fields)}, 201 \ No newline at end of file
diff --git a/elivepatch_server/resources/livepatch.py b/elivepatch_server/resources/livepatch.py
deleted file mode 100644
index d499d9b..0000000
--- a/elivepatch_server/resources/livepatch.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# (c) 2017, Alice Ferrazzi <alice.ferrazzi@gmail.com>
-# Distributed under the terms of the GNU General Public License v2 or later
-
-import subprocess
-import os
-import fileinput
-import tempfile
-
-
-class PaTch(object):
-
- def __init__(self):
- pass
-
- def build_livepatch(self, uuid, vmlinux, debug=True):
- """
- Function for building the livepatch
-
- :param uuid: UUID session identification
- :param vmlinux: path to the vmlinux file
- :param debug: copy build.log in the uuid directory
- :return: void
- """
- kernel_source = os.path.join('/tmp/', 'elivepatch-' + uuid, 'usr/src/linux/')
- uuid_dir = os.path.join('/tmp/', 'elivepatch-' + uuid)
- vmlinux_source = os.path.join(kernel_source, vmlinux)
- kpatch_cachedir = os.path.join(uuid_dir, 'kpatch')
-
- os.makedirs(kpatch_cachedir)
- if not os.path.isfile(vmlinux_source):
- self.build_kernel(uuid)
-
- bashCommand = ['kpatch-build']
- bashCommand.extend(['-s', kernel_source])
- bashCommand.extend(['-v', vmlinux_source])
- bashCommand.extend(['-c', 'config'])
- bashCommand.extend(['main.patch'])
- bashCommand.extend(['--skip-gcc-check'])
- if debug:
- bashCommand.extend(['--skip-cleanup'])
- bashCommand.extend(['--debug'])
- _command(bashCommand, uuid_dir, {'CACHEDIR': kpatch_cachedir})
- if debug:
- _command(['cp', '-f', os.path.join(kpatch_cachedir, 'build.log'), uuid_dir])
-
- def get_kernel_sources(self, uuid, kernel_version, debug=True):
- """
- Function for download the kernel sources
-
- :return: void
- """
- try:
- _command(['git', 'clone', 'https://github.com/aliceinwire/gentoo-sources_overlay.git'])
- except:
- print('git clone failed.')
-
- uuid_dir = os.path.join('/tmp/', 'elivepatch-' + uuid)
- ebuild_path = os.path.join('gentoo-sources_overlay', 'sys-kernel', 'gentoo-sources', 'gentoo-sources-' +
- kernel_version + '.ebuild')
- print(ebuild_path)
- if os.path.isfile(ebuild_path):
- # Use a private tmpdir for portage
- with tempfile.TemporaryDirectory(dir=uuid_dir) as portage_tmpdir:
- print('uuid_dir: ' + str(uuid_dir) + ' PORTAGE_TMPDIR: ' + str(portage_tmpdir))
- # portage_tmpdir is not always working with root privileges
- if debug:
- if os.geteuid() != 0:
- env = {'ROOT': uuid_dir, 'PORTAGE_CONFIGROOT': uuid_dir, 'PORTAGE_TMPDIR': portage_tmpdir,
- 'PORTAGE_DEBUG': '1'}
- else:
- env = {'ROOT': uuid_dir, 'PORTAGE_CONFIGROOT': uuid_dir, 'PORTAGE_TMPDIR': uuid_dir,
- 'PORTAGE_DEBUG': '1'}
- else:
- if os.geteuid() != 0:
- env = {'ROOT': uuid_dir, 'PORTAGE_CONFIGROOT': uuid_dir, 'PORTAGE_TMPDIR': portage_tmpdir}
- else:
- env = {'ROOT': uuid_dir, 'PORTAGE_CONFIGROOT': uuid_dir, 'PORTAGE_TMPDIR': uuid_dir}
- _command(['ebuild', ebuild_path, 'digest', 'clean', 'merge'], env=env)
- kernel_sources_status = True
- else:
- print('ebuild not present')
- kernel_sources_status = None
- return kernel_sources_status
-
- def build_kernel(self, uuid):
- kernel_source_dir = '/tmp/elivepatch-' + uuid + '/usr/src/linux/'
- uuid_dir_config = '/tmp/elivepatch-' + uuid + '/config'
- if 'CONFIG_DEBUG_INFO=y' in open(uuid_dir_config).read():
- print("DEBUG_INFO correctly present")
- elif 'CONFIG_DEBUG_INFO=n' in open(uuid_dir_config).read():
- print("changing DEBUG_INFO to yes")
- for line in fileinput.input(uuid_dir_config, inplace=1):
- print(line.replace("CONFIG_DEBUG_INFO=n", "CONFIG_DEBUG_INFO=y"))
- else:
- print("Adding DEBUG_INFO for getting kernel debug symbols")
- for line in fileinput.input(uuid_dir_config, inplace=1):
- print(line.replace("# CONFIG_DEBUG_INFO is not set", "CONFIG_DEBUG_INFO=y"))
- _command(['cp', '/tmp/elivepatch-' + uuid + '/config', kernel_source_dir + '.config'])
- # olddefconfig default everything that is new from the configuration file
- _command(['make', 'olddefconfig'], kernel_source_dir)
- _command(['make'], kernel_source_dir)
- _command(['make', 'modules'], kernel_source_dir)
-
-
-def _command(bashCommand, kernel_source_dir=None, env=None):
- """
- Popen override function
-
- :param bashCommand: List of command arguments to execute
- :param kernel_source_dir: String with the directory where the command is executed
- :param env: Dictionary for setting system environment variable
- :return: void
- """
- # Inherit the parent environment and update the private copy
- if env:
- process_env = os.environ.copy()
- process_env.update(env)
- env = process_env
-
- if kernel_source_dir:
- print(bashCommand)
- process = subprocess.Popen(bashCommand, stdout=subprocess.PIPE, cwd=kernel_source_dir, env=env)
- output, error = process.communicate()
- for output_line in output.split(b'\n'):
- print(output_line.strip())
- else:
- print(bashCommand)
- process = subprocess.Popen(bashCommand, stdout=subprocess.PIPE, env=env)
- output, error = process.communicate()
- for output_line in output.split(b'\n'):
- print(output_line.strip())
diff --git a/elivepatch_server/setup.py b/elivepatch_server/setup.py
deleted file mode 100644
index 6de3be4..0000000
--- a/elivepatch_server/setup.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from setuptools import setup, find_packages
-
-setup(
- name='elivepatch_server',
- version='0.01',
- description='Patching differents gentoo distributions',
- url='https://gentoo.org',
- author='Alice Ferrazzi',
- author_email='alice.ferrazzi@gmail.com',
- license='GNU GPLv2+',
- packages=find_packages(),
-)