def get_tree(self, **options):
     base_dir = tempfile.mkdtemp()
     try:
         self.make_project(**options)
         yield
         assemble_project(self.project, base_dir)
         self.tree = read_tree(base_dir)
     finally:
         shutil.rmtree(base_dir)
Example #2
0
 def get_tree(self, **options):
     base_dir = tempfile.mkdtemp()
     try:
         self.make_project(**options)
         yield
         assemble_project(self.project, base_dir)
         self.tree = read_tree(base_dir)
     finally:
         shutil.rmtree(base_dir)
Example #3
0
def run_compile(build_result):
    build_result = BuildResult.objects.get(pk=build_result)
    project = build_result.project

    # Assemble the project somewhere
    base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp')
                                if settings.CHROOT_ROOT else None)

    try:
        assemble_project(project, base_dir, build_result)
        # Build the thing
        cwd = os.getcwd()
        success = False
        output = ''
        build_start_time = now()

        try:
            os.chdir(base_dir)

            environ = os.environ.copy()
            environ.update({
                'LD_PRELOAD': settings.C_PRELOAD_ROOT + 'libpreload.so',
                'ALLOWED_FOR_CREATE': '/tmp',
                'ALLOWED_FOR_READ': '/usr/local/include:/usr/include:/usr/lib:/lib:/lib64:/tmp' \
                                    ':/dev/urandom:/proc/self:/proc/self/maps:/proc/mounts' \
                                    ':/app/.heroku:/app/sdk2:/app/sdk3:/app/arm-cs-tools',
                'PATH': '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH']),
                'HOME': '/app'
            })

            # Install dependencies if there are any
            dependencies = project.get_dependencies()
            if dependencies:
                # Checking for path-based dependencies is performed by the database so in theory we shouldn't need to do
                # it here but we will do it anyway just to be extra safe.
                for version in dependencies.values():
                    validate_dependency_version(version)
                npm_command = [
                    settings.NPM_BINARY, "install", "--ignore-scripts",
                    "--no-bin-links"
                ]
                output = subprocess.check_output(
                    npm_command,
                    stderr=subprocess.STDOUT,
                    preexec_fn=_set_resource_limits,
                    env=environ)
                subprocess.check_output([settings.NPM_BINARY, "dedupe"],
                                        stderr=subprocess.STDOUT,
                                        preexec_fn=_set_resource_limits,
                                        env=environ)

            if project.sdk_version == '2':
                command = [settings.SDK2_PEBBLE_WAF, "configure", "build"]
            elif project.sdk_version == '3':
                if settings.WAF_NODE_PATH:
                    environ['NODE_PATH'] = settings.WAF_NODE_PATH
                command = [settings.SDK3_PEBBLE_WAF, "configure", "build"]
            else:
                raise Exception("invalid sdk version.")

            output += subprocess.check_output(command,
                                              stderr=subprocess.STDOUT,
                                              preexec_fn=_set_resource_limits,
                                              env=environ)
        except subprocess.CalledProcessError as e:
            output = e.output
            logger.warning("Build command failed with error:\n%s\n", output)
            success = False
        except Exception as e:
            logger.exception("Unexpected exception during build")
            success = False
            output = str(e)
        else:
            success = True
            if project.project_type == 'package':
                temp_file = os.path.join(base_dir, 'dist.zip')
            else:
                temp_file = os.path.join(base_dir, 'build',
                                         '%s.pbw' % os.path.basename(base_dir))
            if not os.path.exists(temp_file):
                success = False
                logger.warning("Success was a lie.")
        finally:
            build_end_time = now()
            os.chdir(cwd)

            if success:
                # Try reading file sizes out of it first.
                if project.project_type != 'package':
                    try:
                        s = os.stat(temp_file)
                        build_result.total_size = s.st_size
                        # Now peek into the zip to see the component parts
                        with zipfile.ZipFile(temp_file, 'r') as z:
                            for platform in [
                                    'aplite', 'basalt', 'chalk', 'diorite',
                                    'emery'
                            ]:
                                store_size_info(project, build_result,
                                                platform, z)

                    except Exception as e:
                        logger.warning("Couldn't extract filesizes: %s", e)

                    # Try pulling out debug information.
                    if project.sdk_version == '2':
                        save_debug_info(
                            base_dir, build_result, BuildResult.DEBUG_APP,
                            'aplite',
                            os.path.join(base_dir, 'build', 'pebble-app.elf'))
                        save_debug_info(
                            base_dir, build_result, BuildResult.DEBUG_WORKER,
                            'aplite',
                            os.path.join(base_dir, 'build',
                                         'pebble-worker.elf'))
                    else:
                        for platform in [
                                'aplite', 'basalt', 'chalk', 'diorite', 'emery'
                        ]:
                            save_debug_info(
                                base_dir, build_result, BuildResult.DEBUG_APP,
                                platform,
                                os.path.join(base_dir, 'build',
                                             '%s/pebble-app.elf' % platform))
                            save_debug_info(
                                base_dir, build_result,
                                BuildResult.DEBUG_WORKER, platform,
                                os.path.join(base_dir, 'build',
                                             '%s/pebble-worker.elf' %
                                             platform))

                    build_result.save_pbw(temp_file)
                else:
                    # tar.gz up the entire built project directory as the build result.
                    archive = shutil.make_archive(
                        os.path.join(base_dir, "package"), 'gztar', base_dir)
                    build_result.save_package(archive)

            build_result.save_build_log(output or 'Failed to get output')
            build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED
            build_result.finished = now()
            build_result.save()

            data = {
                'data': {
                    'cloudpebble': {
                        'build_id':
                        build_result.id,
                        'job_run_time': (build_result.finished -
                                         build_result.started).total_seconds(),
                    },
                    'build_time':
                    (build_end_time - build_start_time).total_seconds(),
                }
            }

            event_name = 'app_build_succeeded' if success else 'app_build_failed'

            send_td_event(event_name, data, project=project)

    except Exception as e:
        logger.exception("Build failed due to internal error: %s", e)
        build_result.state = BuildResult.STATE_FAILED
        build_result.finished = now()
        try:
            build_result.save_build_log("Something broke:\n%s" % e)
        except:
            pass
        build_result.save()
    finally:
        shutil.rmtree(base_dir)
Example #4
0
def run_compile(build_result):
    build_result = BuildResult.objects.get(pk=build_result)
    project = build_result.project

    # Assemble the project somewhere
    base_dir = tempfile.mkdtemp(dir=os.path.join(settings.CHROOT_ROOT, 'tmp') if settings.CHROOT_ROOT else None)

    try:
        assemble_project(project, base_dir, build_result)
        # Build the thing
        cwd = os.getcwd()
        success = False
        output = ''
        build_start_time = now()

        try:
            os.chdir(base_dir)

            # Install dependencies if there are any
            dependencies = project.get_dependencies()
            if dependencies:
                # Checking for path-based dependencies is performed by the database so in theory we shouldn't need to do
                # it here but we will do it anyway just to be extra safe.
                for version in dependencies.values():
                    validate_dependency_version(version)
                npm_command = [settings.NPM_BINARY, "install", "--ignore-scripts", "--no-bin-links"]
                output = subprocess.check_output(npm_command, stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits)
                subprocess.check_output([settings.NPM_BINARY, "dedupe"], stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits)

            if project.sdk_version == '2':
                environ = os.environ.copy()
                environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH'])
                command = [settings.SDK2_PEBBLE_WAF, "configure", "build"]
            elif project.sdk_version == '3':
                environ = os.environ.copy()
                environ['PATH'] = '{}:{}'.format(settings.ARM_CS_TOOLS, environ['PATH'])
                if settings.WAF_NODE_PATH:
                    environ['NODE_PATH'] = settings.WAF_NODE_PATH
                command = [settings.SDK3_PEBBLE_WAF, "configure", "build"]
            else:
                raise Exception("invalid sdk version.")
            output += subprocess.check_output(command, stderr=subprocess.STDOUT, preexec_fn=_set_resource_limits,
                                              env=environ)
        except subprocess.CalledProcessError as e:
            output = e.output
            logger.warning("Build command failed with error:\n%s\n", output)
            success = False
        except Exception as e:
            logger.exception("Unexpected exception during build")
            success = False
            output = str(e)
        else:
            success = True
            if project.project_type == 'package':
                temp_file = os.path.join(base_dir, 'dist.zip')
            else:
                temp_file = os.path.join(base_dir, 'build', '%s.pbw' % os.path.basename(base_dir))
            if not os.path.exists(temp_file):
                success = False
                logger.warning("Success was a lie.")
        finally:
            build_end_time = now()
            os.chdir(cwd)

            if success:
                # Try reading file sizes out of it first.
                if project.project_type != 'package':
                    try:
                        s = os.stat(temp_file)
                        build_result.total_size = s.st_size
                        # Now peek into the zip to see the component parts
                        with zipfile.ZipFile(temp_file, 'r') as z:
                            for platform in ['aplite', 'basalt', 'chalk', 'diorite', 'emery']:
                                store_size_info(project, build_result, platform, z)

                    except Exception as e:
                        logger.warning("Couldn't extract filesizes: %s", e)

                    # Try pulling out debug information.
                    if project.sdk_version == '2':
                        save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, 'aplite', os.path.join(base_dir, 'build', 'pebble-app.elf'))
                        save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, 'aplite', os.path.join(base_dir, 'build', 'pebble-worker.elf'))
                    else:
                        for platform in ['aplite', 'basalt', 'chalk', 'diorite', 'emery']:
                            save_debug_info(base_dir, build_result, BuildResult.DEBUG_APP, platform, os.path.join(base_dir, 'build', '%s/pebble-app.elf' % platform))
                            save_debug_info(base_dir, build_result, BuildResult.DEBUG_WORKER, platform, os.path.join(base_dir, 'build', '%s/pebble-worker.elf' % platform))

                    build_result.save_pbw(temp_file)
                else:
                    # tar.gz up the entire built project directory as the build result.
                    archive = shutil.make_archive(os.path.join(base_dir, "package"), 'gztar', base_dir)
                    build_result.save_package(archive)

            build_result.save_build_log(output or 'Failed to get output')
            build_result.state = BuildResult.STATE_SUCCEEDED if success else BuildResult.STATE_FAILED
            build_result.finished = now()
            build_result.save()

            data = {
                'data': {
                    'cloudpebble': {
                        'build_id': build_result.id,
                        'job_run_time': (build_result.finished - build_result.started).total_seconds(),
                    },
                    'build_time': (build_end_time - build_start_time).total_seconds(),
                }
            }

            event_name = 'app_build_succeeded' if success else 'app_build_failed'

            send_td_event(event_name, data, project=project)

    except Exception as e:
        logger.exception("Build failed due to internal error: %s", e)
        build_result.state = BuildResult.STATE_FAILED
        build_result.finished = now()
        try:
            build_result.save_build_log("Something broke:\n%s" % e)
        except:
            pass
        build_result.save()
    finally:
        shutil.rmtree(base_dir)