Exemplo n.º 1
0
Arquivo: run.py Projeto: jexhson/rbx
class RbxProjectRunAction(object):

    vagrantfile = 'Vagrantfile'
    configfile = 'rbx.sh'

    @property
    def package_path(self):
        if not hasattr(self, '_package_path'):
            self._package_path = os.path.abspath(
                os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
        return self._package_path

    @property
    def user_path(self):
        if not hasattr(self, '_user_path'):
            if self.params.location:
                self._user_path = os.path.abspath(self.params.location)
            else:
                self._user_path = os.path.abspath(os.getcwd())
        return self._user_path

    def write_config(self, commands, config):
        with open(os.path.join(self.user_path, self.configfile), 'w') as fd:
            fd.writelines('\n'.join(commands))
            for forwarded in config['ports']:
                fd.write('\n#RBX_PORT:{0}'.format(forwarded))
            for src, dest in config['volumes']:
                fd.write('\n#RBX_VOLUME:{0}:{1}'.format(src, dest))

    def _is_vagrant(self):
        return not self.params.host

    def do_action_run(self):
        if self._is_vagrant:
            self.copy_vagrantfile()
            self.vagrant = Vagrant(self.user_path)

        if self.params.stop:
            self._project_stop()
        elif self.params.restart:
            self._project_restart()
        elif self.params.suspend:
            self._project_suspend()
        elif self.params.reset:
            self._project_reset()
        else:
            self._project_start()

    def _project_start(self):
        if self._is_vagrant():
            status = self.vagrant.status()
            if status.get('default') != Vagrant.RUNNING:
                commands, config = self.build()
                self.write_config(commands, config)
                self.vagrant.up(False, capture_output=False)
                self.vagrant.provision(capture_output=False)
        else:
            self.out('Sorry, not implemented yet!')

    def _project_stop(self):
        if self._is_vagrant():
            status = self.vagrant.status()
            if status.get('default') == Vagrant.RUNNING:
                self.vagrant.halt(capture_output=False)
        else:
            self.out('Option no available for physical machine')

    def _project_restart(self):
        if self._is_vagrant():
            self._project_stop()
            self._project_start()
        else:
            self.out('Option no available for physical machine')

    def _project_suspend(self):
        if self._is_vagrant():
            status = self.vagrant.status()
            if status.get('default') == Vagrant.RUNNING:
                self.vagrant.suspend(capture_output=False)
        else:
            self.out('Sorry, not implemented yet!')

    def _project_reset(self):
        if self._is_vagrant():
            status = self.vagrant.status()
            if status.get('default') == Vagrant.RUNNING:
                commands, config = self.build()
                self.write_config(commands, config)
                self.vagrant.provision(capture_output=False)
            else:
                self._project_start()
        else:
            self.out('Sorry, not implemented yet!')

    def copy_vagrantfile(self):
        copy(os.path.join(self.package_path, self.vagrantfile),
             os.path.join(self.user_path, self.vagrantfile))

    def retrieve_components(self):
        self.components = {}
        for component in self.project['components']:
            self.components[component['name']] = self.query('get',
                '/component/{0}'.format(component['name']))

    def build(self):
        self.project = self.query_resource('get')
        self.retrieve_components()
        self.docker_command = []
        names = []
        commands = []
        ports = []
        volumes = []
        for component in self.project['components']:
            conf = self.components[component['name']]
            commands.append(('echo "[rbx] Deploying component \'{0}\'"; '.format(component['name']) +
                             '[ "x$(docker ps | grep {0})" != "x" ] && docker stop -t=3 {0} &> /dev/null; ' +
                             '[ "x$(docker ps -a | grep {0})" != "x" ] && docker rm {0} &> /dev/null; ' +
                             'docker run -d -name {0} {1} {2} {3} {4} {5} &> /dev/null').format(
                            self._docker_name(component['name']),
                            self._docker_links(names),
                            self._docker_ports(component['port']),
                            self._docker_volumes(component['volume']),
                            conf['image'],
                            subprocess.list2cmdline(conf['command'])))
            if component['port']:
                for port in component['port']:
                    ports.append(port['forwarded'])
            if component['volume']:
                for volume in component['volume']:
                    _vol = (volume['mounted'], volume['path'])
                    if _vol in volumes:
                        continue
                    volumes.append(_vol)
            names.append(component['name'])
        return commands, {'ports': ports, 'volumes': volumes}

    def _volume_path(self, conf):
        if self.params.host:
            return conf['mounted']
        return conf['path']

    def _docker_name(self, name):
        return '{0}_{1}'.format(self.project['name'], name)

    def _docker_links(self, names):
        return ' '.join(['-link {0}:{1}'.format(self._docker_name(n), n)
                         for n in names])

    def _docker_ports(self, ports):
        return ' '.join(['-p {0}:{1}'.format(p['forwarded'], p['number'])
                         for p in ports])

    def _docker_volumes(self, volumes):
        return ' '.join(['-v {0}:{1}:ro'.format(self._volume_path(v),
                                                v['path'])
                         for v in volumes])