Esempio n. 1
0
def main():
    try:
        current_release = int(open(release_file).read().strip())
    except:
        current_release = 0

    data = {'old_release': current_release,
            'hostname': socket.gethostname()}

    log.debug('Sending: {}', data)

    response = server_request('/penguindome/v1/update', data=data,
                              exit_on_connection_error=True)

    data = response.json()

    changed = False

    if data['status'] == 'current':
        log.debug('Current')
    elif data['status'] == 'out-of-date':
        do_release(data)
        changed = True
    else:
        log.exception('Unrecognized status: {}'.format(data['status']))
        sys.exit(1)

    if 'patches' in data:
        do_patches(data['patches'])
        changed = True

    if changed:
        subprocess.check_output(os.path.join('bin', 'verify'))
        log.info('Successful update')
        sys.exit(42)
Esempio n. 2
0
def do_patches(patches):
    for patch in patches:
        patch_id = patch['id']
        for patch_file in patch['files']:
            patch_path = patch_file['path']
            patch_mode = patch_file['mode']
            patch_content = b64decode(patch_file.get('content', ''))

            if patch_path.startswith('/'):
                log.error('Ignoring absolute patch {}', patch_path)
                continue
            if '..' in os.sep.split(patch_path):
                log.error('Ignoring patch {} with ".." in it', patch_path)
                continue
            if patch_mode == 0:
                if patch_content:
                    log.error(
                        "Patch for {}, mode 0, has content but shouldn't",
                        patch_path)
                    continue
                if os.path.exists(patch_path):
                    log.info('Removing {} due to patch', patch_path)
                    try:
                        os.remove(patch_path)
                    except FileNotFoundError:
                        log.warn('Failed to delete {} (already gone)',
                                 patch_path)
                        pass
                else:
                    log.warn("Patch says to remove {} but it's already gone",
                             patch_path)
                continue
            log.info('Patching {} (id {}, mode {:o})', patch_path, patch_id,
                     patch_mode)
            patch_dir = os.path.dirname(os.path.join(top_dir, patch_path))
            os.makedirs(patch_dir, exist_ok=True)
            open(patch_path, 'wb').write(patch_content)
            os.chmod(patch_path, patch_mode)

        server_request('/penguindome/v1/acknowledge_patch',
                       data={
                           'id': patch_id,
                           'hostname': socket.gethostname()
                       },
                       exit_on_connection_error=True)
Esempio n. 3
0
 def _request(self, request, data=None):
     if data is None:
         data = {}
     else:
         data = data.copy()
     if self.pipe_id:
         data['pipe_id'] = self.pipe_id
     response = server_request('/penguindome/v1/server_pipe/{}/{}'.format(
         self.type, request),
                               data=data,
                               local_port=self.local_port,
                               logger=self.logger,
                               signed=request not in ('send', 'receive'))
     if response.status_code == 404:
         raise FileNotFoundError('Pipe ID {} not found'.format(
             self.pipe_id))
     response.raise_for_status()
     return response.json()
Esempio n. 4
0
from requests.exceptions import HTTPError, ReadTimeout
import sys

from penguindome import top_dir, collected_dir, set_gpg
from penguindome.client import get_logger, server_request

log = get_logger('submit')
os.chdir(top_dir)
set_gpg('client')

for collected in sorted(glob.glob(os.path.join(collected_dir, '*[0-9]'))):
    # This nested try/except is that we don't have to duplicate the code twice,
    # one for unrecognized HTTPError exceptiosns and again for ReadTimeout.
    try:
        try:
            server_request('/penguindome/v1/submit', data_path=collected,
                           exit_on_connection_error=True, logger=log)
        except HTTPError as e:
            if e.response.status_code == 400:
                log.error('Server returned status code 400. '
                          'Renaming {} to {}.bad.', collected, collected)
                os.rename(collected, collected + '.bad')
                sys.exit(1)
            raise
    except (HTTPError, ReadTimeout) as e:
        log.error('Submit failed: {}', str(e))
        log.debug('Traceback of failed submission', exc_info=sys.exc_info())
        sys.exit(1)

    os.unlink(collected)
    log.debug('Successful submission of {}', collected)