def start_APP_and_check_status(): """ Starts the APP daemon process and checks that the server is up and running then it shuts down the server """ virtualenv('dlg --help') success('dlg help is working...')
def create_final_image(state): """Create docker image from container""" puts(blue("Building image")) # First need to cleanup container before we stop and commit it. # We execute most of the commands via ssh, until we actually remove ssh # itself and forcefully remove unnecessary system-level folders execute(cleanup_container) cont = state.container execOutput( cont, 'yum --assumeyes --quiet remove fipscheck fipscheck-lib openssh-server openssh-clients' ) execOutput(cont, 'rm -rf /var/log') execOutput(cont, 'rm -rf /var/lib/yum') conf = {'Cmd': ["/usr/bin/su", "-", APP_user(), "-c", "/home/{0}/{0}_rt/bin/ngamsServer -cfg /home/{0}/{1}/cfg/ngamsServer.conf -autoOnline -force -v 4".\ format(APP_user(), APP_name())]} image_repo = docker_image_repository() try: cont.stop() cont.commit(repository=image_repo, tag='latest', conf=conf) success("Created Docker image %s:latest" % (image_repo, )) except Exception as e: failure("Failed to build final image: %s" % (str(e))) raise finally: # Cleanup the docker environment from all our temporary stuff cont.remove()
def start_APP_and_check_status(): """ Starts the APP daemon process and checks that the server is up and running then it shuts down the server """ with cd('{0}/pyvospace/server/deploy'.format(APP_source_dir())): # >>>> Darwin docker shows a permission issue with keychain access <<<< if get_linux_flavor() != 'Darwin': virtualenv('docker-compose build') else: info('>>>> Darwin reuqires to build docker container manually') info('>>>> docker-compose build') virtualenv( 'docker run -d -p 5435:5432 pyvospace/pyvospace-db -h 0.0.0.0') time.sleep(10) with cd('{0}'.format(APP_source_dir())): virtualenv('python -m unittest discover test') # run('mkdir -p /tmp/fuse') # virtualenv('posix_space --cfg test_vo.ini > /tmp/space.log 2>&1') # time.sleep(2) # virtualenv('posix_storage --cfg test_vo.ini > /tmp/storage.log 2>&1') # time.sleep(2) # virtualenv('python -m pyvospace.client.fuse --host localhost --port 8080 --username test --password test --mountpoint /tmp/fuse/`` > /tmp/fusemnt.log 2>&1') # time.sleep(2) # run("cd /tmp/fuse && mkdir -p newdir && cd newdir && echo 'Hello World!' >> data && cat data") success('{0} is working...'.format(env.APP_NAME))
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the init script for an operational deployment of RASVAMT. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ with settings(user=env.AWS_SUDO_USER): print(red("Initialising deployment")) sudo('usermod -a -G {} ec2-user'.format(env.APP_USER)) sudo('mkdir -p /etc/supervisor/') sudo('mkdir -p /etc/supervisor/conf.d/') sudo('cp {0}/fabfile/init/sysv/nginx.conf /etc/nginx/.'. format(APP_source_dir())) # copy nginx and supervisor conf files sudo('cp {0}/fabfile/init/sysv/rasvama.conf /etc/supervisor/conf.d/.'. format(APP_source_dir())) # create the DB with settings(user=env.APP_USER): virtualenv('cd {0}/db; python create_db.py'.format(env.APP_SRC_DIR)) #check if nginx is running else print(red("Server setup and ready to deploy")) #Think we have success("Init scripts installed")
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the APP init script for an operational deployment. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ # Different distros place it in different directories # The init script is prepared for both opt_file = '/etc/sysconfig/dlg' if get_linux_flavor() in ('Ubuntu', 'Debian'): opt_file = '/etc/default/dlg' # Script file installation sudo('cp {0}/fabfile/init/sysv/dlg-* /etc/init.d/'.format(nsd)) sudo('chmod 755 /etc/init.d/dlg-*') # Options file installation and edition sudo('cp {0}/fabfile/init/sysv/dlg.options {1}'.format(nsd, opt_file)) sudo('chmod 644 %s' % (opt_file, )) # Enabling init file on boot if check_command('update-rc.d'): sudo('update-rc.d dlg-nm defaults') sudo('update-rc.d dlg-dim defaults') else: sudo('chkconfig --add dlg-nm') sudo('chkconfig --add dlg-dim') success("{0} init script installed".format(env.APP_NAME))
def build(): """ Builds and installs APP into the target virtualenv. """ info('Building {0}...'.format(env.APP_NAME)) with cd(APP_source_dir()): extra_pkgs = extra_python_packages() if extra_pkgs: virtualenv('pip install %s' % ' '.join(extra_pkgs)) else: info('No extra Python packages') with cd(APP_source_dir()): build_cmd = env.build_cmd() info('Build command: {0}'.format(build_cmd)) if build_cmd and build_cmd != '': virtualenv(build_cmd) if 'build_function' in env and env.build_function: res = env.build_function() # Install the /etc/init.d script for automatic start nsd = APP_source_dir() nuser = APP_user() cfgfile = None # success("{0} built and installed".format(env.APP_NAME))
def install_user_profile(): """ Put the activation of the virtualenv into the login profile of the user unless the APP_DONT_MODIFY_BASHPROFILE environment variable is defined NOTE: This will be executed for the user running APP. """ if run('echo $APP_DONT_MODIFY_BASHPROFILE') or \ 'APP_NO_BASH_PROFILE' in env: return nid = APP_install_dir() nrd = APP_root_dir() with cd("~"): if not exists(".bash_profile_orig"): run('cp .bash_profile .bash_profile_orig', warn_only=True) else: run('cp .bash_profile_orig .bash_profile') script = ('if [ -f "{0}/bin/activate" ]'.format(nid), 'then', ' source "{0}/bin/activate"'.format(nid), 'fi', 'export APP_PREFIX="{0}"'.format(nrd)) run("echo '{0}' >> .bash_profile".format('\n'.join(script))) success("~/.bash_profile edited for automatic virtualenv sourcing")
def prepare_ngas_data_dir(): """Creates a new NGAS root directory""" info('Preparing NGAS root directory') nrd = APP_root_dir() tgt_cfg = os.path.join(nrd, 'cfg', 'ngamsServer.conf') with cd(APP_source_dir()): cmd = ['./prepare_ngas_root.sh'] if 'NGAS_OVERWRITE_ROOT' in env and env.NGAS_OVERWRITE_ROOT: cmd.append('-f') cmd.append(nrd) res = run(' '.join(cmd), quiet=True) if res.succeeded: success("NGAS data directory ready") env.tgt_cfg = tgt_cfg return tgt_cfg # Deal with the errors here error = 'NGAS root directory preparation under {0} failed.\n'.format(nrd) if res.return_code == 2: error = (nrd + " already exists. Specify NGAS_OVERWRITE_ROOT to overwrite, " "or a different NGAS_ROOT_DIR location") else: error = res abort(error)
def start_APP_and_check_status(): """ Starts the APP daemon process and checks that the server is up and running then it shuts down the server """ ###>>> # Provide the actual implementation here if required. ###<<< success('{0} help is working...'.format(env.APP_NAME))
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the uwsgi init script for an operational deployment of EAGLE. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ with settings(user=env.AWS_SUDO_USER): pass success("Init scripts installed")
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the uwsgi init script for an operational deployment of EAGLE. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ if env.FAB_TASK == 'docker_image': env.sudo_user = '******' elif env.FAB_TASK == 'aws_deploy': env.sudo_user = env.AWS_SUDO_USER with settings(user=env.sudo_user): # Different distros place it in different directories # The init script is prepared for both opt_file = '/etc/uwsgi/uwsgi.ini' # The uwsgi binary got installed into the virtualenv. Lets pull that over # to the system wide folder. sudo('cp {0}/bin/uwsgi /usr/local/bin/uwsgi'.format(APP_install_dir())) sudo('chmod 755 /usr/local/bin/uwsgi') # init file installation sudo('cp {0}/fabfile/init/sysv/uwsgi /etc/init.d/'.format(APP_source_dir())) sudo('chmod 755 /etc/init.d/uwsgi') # Options file installation and edition sudo('mkdir -p /etc/uwsgi') sudo('cp {0}/fabfile/init/sysv/uwsgi.ini {1}'.format(APP_source_dir(), opt_file)) sudo('chmod 644 {0}'.format(opt_file)) # Enabling init file on boot if check_command('update-rc.d'): sudo('update-rc.d uwsgi defaults') else: sudo('chkconfig --add uwsgi') # Nginx is not in standard repos # go get it [This is just for centos] sudo('cp {0}/fabfile/init/nginx.repo /etc/yum.repos.d/.'. format(APP_source_dir())) sudo('yum update ; yum install nginx') # Now let's connect that to nginx # Copy main nginx conf file sudo('cp {0}/fabfile/init/sysv/nginx.conf /etc/nginx/.'. format(APP_source_dir())) # copy uwsgi nginx conf file sudo('cp {0}/fabfile/init/sysv/eagle.conf /etc/nginx/conf.d/.'. format(APP_source_dir())) success("Init scripts installed")
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the APP init script for an operational deployment. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ ###>>> # Provide the actual implementation here if required. ###<<< success("{0} init script installed".format(env.APP_NAME))
def build_APP(): """ Builds and installs APP into the target virtualenv. """ with cd(APP_source_dir()): extra_pkgs = extra_python_packages() if extra_pkgs: virtualenv('pip install %s' % ' '.join(extra_pkgs)) develop = False no_doc_dependencies = APP_doc_dependencies() build_cmd = APP_build_cmd() print(build_cmd) if build_cmd != '': virtualenv(build_cmd) success("{0} built and installed".format(env.APP_NAME))
def virtualenv_setup(): """ Creates a new virtualenv that will hold the APP installation """ APPInstallDir = APP_install_dir() if check_dir(APPInstallDir): overwrite = APP_overwrite_installation() if not overwrite: msg = ("%s exists already. Specify APP_OVERWRITE_INSTALLATION " "to overwrite, or a different APP_INSTALL_DIR location") abort(msg % (APPInstallDir,)) run("rm -rf %s" % (APPInstallDir,)) # Check which python will be bound to the virtualenv ppath = check_python() if not ppath: ppath = python_setup(os.path.join(home(), 'python')) # Use our create_venv.sh script to create the virtualenv # It already handles the download automatically if no virtualenv command is # found in the system, and also allows to specify a python executable path script_path = os.path.dirname(os.path.realpath(__file__))+'/create_venv.sh' put(script_path, APP_source_dir()+'/create_venv.sh') with cd(APP_source_dir()): run("/bin/bash create_venv.sh -p {0} {1}".format(ppath, APPInstallDir)) # Download this particular certifcate; otherwise pip complains # in some platforms if APP_use_custom_pip_cert(): if not(check_dir('~/.pip')): run('mkdir ~/.pip') with cd('~/.pip'): download('http://curl.haxx.se/ca/cacert.pem') run('echo "[global]" > ~/.pip/pip.conf; echo ' '"cert = {0}/.pip/cacert.pem" >> ~/.pip/pip.conf;'.format(home())) # Update pip and install wheel; this way we can install binary wheels from # PyPI if available (like astropy) # TODO: setuptools and python-daemon are here only because # python-daemon 2.1.2 is having a problem to install via setuptools # but not via pip (see https://pagure.io/python-daemon/issue/2 and # https://pagure.io/python-daemon/issue/3). # When this problem is fixed we'll fix our dependency on python-daemo # to avoid this issue entirely virtualenv('pip install -U pip wheel setuptools python-daemon') success("Virtualenv setup completed")
def install_sysv_init_script(nsd, nuser, cfgfile): """ Install the NGAS init script for an operational deployment. The init script is an old System V init system. In the presence of a systemd-enabled system we use the update-rc.d tool to enable the script as part of systemd (instead of the System V chkconfig tool which we use instead). The script is prepared to deal with both tools. """ # Different distros place it in different directories # The init script is prepared for both opt_file = '/etc/sysconfig/ngas' if get_linux_flavor() in ('Ubuntu', 'Debian'): opt_file = '/etc/default/ngas' # Script file installation sudo('cp %s/fabfile/init/sysv/ngas-server /etc/init.d/' % (nsd, )) sudo('chmod 755 /etc/init.d/ngas-server') # Options file installation and edition ntype = settings['NGAS_SERVER_TYPE'] sudo('cp %s/fabfile/init/sysv/ngas-server.options %s' % (nsd, opt_file)) sudo('chmod 644 %s' % (opt_file, )) sed(opt_file, '^USER=.*', 'USER=%s' % (nuser, ), use_sudo=True, backup='') sed(opt_file, '^CFGFILE=.*', 'CFGFILE=%s' % (cfgfile, ), use_sudo=True, backup='') if ntype == 'cache': sed(opt_file, '^CACHE=.*', 'CACHE=YES', use_sudo=True, backup='') elif ntype == 'data-mover': sed(opt_file, '^DATA_MOVER=.*', 'DATA_MOVER=YES', use_sudo=True, backup='') # Enabling init file on boot if check_command('update-rc.d'): sudo('update-rc.d ngas-server defaults') else: sudo('chkconfig --add ngas-server') success("NGAS init script installed")
def upload_to(host, filename, port=7777): """ Simple method to upload a file into NGAS """ with contextlib.closing(httplib.HTTPConnection(host, port)) as conn: conn.putrequest('POST', '/QARCHIVE?filename=%s' % ( urlparse.quote(os.path.basename(filename)),)) conn.putheader('Content-Length', os.stat(filename).st_size) conn.endheaders() with open(filename) as f: for data in iter(functools.partial(f.read, 4096), ''): conn.send(data) r = conn.getresponse() if r.status != httplib.OK: raise Exception("Error while QARCHIVE-ing %s to %s:%d:\nStatus: " "%d\n%s\n\n%s" % (filename, conn.host, conn.port, r.status, r.msg, r.read())) else: success("{0} successfully archived to {1}!".format(filename, host))
def copy_sources(): """ Creates a copy of the APP sources in the target host. """ # We don't open all the git repositories to the world, so for the time # being we always make a tarball from our repository and copy it over # ssh to the remote host, where we expand it back nsd = APP_source_dir() # Because this could be happening in parallel in various machines # we generate a tmpfile locally, but the target file is the same repo_git = APP_repo_git() if not repo_git: local_file = tempfile.mktemp(".tar.gz") else: #In this case the compression is done after git archive local_file = tempfile.mktemp(".tar") create_sources_tarball(local_file) if repo_git: local_file += ".gz" # transfer the tar file if not local if not is_localhost(): target_tarfile = '/tmp/{0}_tmp.tar'.format(APP_name()) put(local_file, target_tarfile) else: target_tarfile = local_file # unpack the tar file into the APP_src_dir # (mind the "p", to preserve permissions) run('mkdir -p {0}'.format(nsd)) with cd(nsd): run('tar xpf {0}'.format(target_tarfile)) if not is_localhost(): run('rm {0}'.format(target_tarfile)) # Cleaning up now local('rm {0}'.format(local_file)) success("{0} sources copied".format(APP_name()))
def sysinitstart_APP_and_check_status(): """ Starts the APP daemon process and checks that the server is up and running then it shuts down the server """ ###>>> # The following just runs the DB in a docker container and runs the tests ###<<< nuser = APP_user() with settings(user=nuser): with cd('{0}'.format(APP_source_dir())): # virtualenv('python -m unittest discover test') # run('mkdir -p /tmp/fuse') # virtualenv('posix_space --cfg test_vo.ini > /tmp/space.log 2>&1') # time.sleep(2) # virtualenv('posix_storage --cfg test_vo.ini > /tmp/storage.log 2>&1') # time.sleep(2) # virtualenv('python -m pyvospace.client.fuse --host localhost --port 8080 --username test --password test --mountpoint /tmp/fuse/`` > /tmp/fusemnt.log 2>&1') # time.sleep(2) # run("cd /tmp/fuse && mkdir -p newdir && cd newdir && echo 'Hello World!' >> data && cat data") pass success("{0} successfully tested!".format(env.APP_NAME))
def sysinitstart_NGAS_and_check_status(): """ Starts the ngamsDaemon process and checks that the server is up and running. Then it shuts down the server """ # We sleep 2 here as it was found on Mac deployment to docker container that the # shell would exit before the ngasDaemon could detach, thus resulting in no startup. sudo('service ngas-server start && sleep 2') try: res = sudo('service ngas-server status', warn_only=True) print(res) if res.failed: failure( "Couldn't contact NGAS server after starting it. " "Check log files under %s/log/ to find out what went wrong" % APP_source_dir(), with_stars=False) else: success('NGAS server started correctly :)') finally: info("Shutting NGAS server down now") sudo("service ngas-server stop ")
def start_APP_and_check_status(): """ Starts the ngamsDaemon process and checks that the server is up and running. Then it shuts down the server """ # We sleep 2 here as it was found on Mac deployment to docker container that the # shell would exit before the ngasDaemon could detach, thus resulting in no startup. virtualenv('ngamsDaemon start -cfg {0} && sleep 2'.format(env.tgt_cfg)) try: res = virtualenv('ngamsDaemon status -cfg {0}'.format(env.tgt_cfg), warn_only=True) if res.failed: failure( "Couldn't contact NGAS server after starting it. " "Check log files under %s/log/ to find out what went wrong" % APP_source_dir(), with_stars=False) else: success('NGAS server started correctly :)') finally: info("Shutting NGAS server down now") virtualenv("ngamsDaemon stop -cfg {0}".format(env.tgt_cfg))
def prepare_APP_data_dir(): """Creates a new APP root directory""" info('Preparing {0} root directory'.format(env.APP_NAME)) nrd = APP_root_dir() # tgt_cfg = os.path.join(nrd, 'cfg', 'ngamsServer.conf') tgt_cfg = None res = run('mkdir -p {0}'.format(nrd)) with cd(APP_source_dir()): for d in env.APP_DATAFILES: res = run('scp -r {0} {1}/.'.format(d, nrd), quiet=True) if res.succeeded: success("{0} data directory ready".format(env.APP_NAME)) return tgt_cfg # Deal with the errors here error = '{0} root directory preparation under {1} failed.\n'.format( env.APP_NAME, nrd) if res.return_code == 2: error = (nrd + " already exists. Specify APP_OVERWRITE_ROOT to " "overwrite, or a different APP_ROOT_DIR location") else: error = res abort(error)
def setup_container(): """Create and prepare a docker container and let Fabric point at it""" from docker.client import DockerClient image = 'library/centos:7' container_name = 'APP_installation_target' info("Creating docker container based on {0}".format(image)) info("Please stand-by....") cli = DockerClient.from_env(version='auto', timeout=60) # Create and start a container using the newly created stage1 image cont = cli.containers.run(image=image, name=container_name, remove=False, detach=True, tty=True, ports={22: 2222}) success("Created container %s from %s" % (container_name, image)) # Find out container IP, prepare container for APP installation try: host_ip = cli.api.inspect_container( cont.id)['NetworkSettings']['IPAddress'] # info("Updating and installing OpenSSH server in container") # execOutput(cont, 'yum -y update') info("Installing OpenSSH server...") execOutput(cont, 'yum -y install openssh-server sudo') info("Installing OpenSSH client...") execOutput(cont, 'yum -y install openssh-clients sudo') info("Installing initscripts...") execOutput(cont, 'yum -y install initscripts sudo') info("Cleaning up...") execOutput(cont, 'yum clean all') info('Configuring OpenSSH to allow connections to container') add_public_ssh_key(cont) execOutput( cont, 'sed -i "s/#PermitRootLogin yes/PermitRootLogin yes/" /etc/ssh/sshd_config' ) execOutput(cont, 'sed -i "s/#UseDNS yes/UseDNS no/" /etc/ssh/sshd_config') execOutput(cont, 'ssh-keygen -A') execOutput(cont, 'mkdir -p /root/.ssh') execOutput(cont, 'touch /root/.ssh/authorized_keys') execOutput(cont, 'chown root.root /root/.ssh/authorized_keys') execOutput(cont, 'chmod 600 /root/.ssh/authorized_keys') execOutput(cont, 'chmod 700 /root/.ssh') execOutput(cont, 'rm /run/nologin') info('Starting OpenSSH deamon in container') execOutput(cont, '/usr/sbin/sshd -D', detach=True) except: failure( "Error while preparing container for APP installation, cleaning up..." ) cont.stop() cont.remove() raise # From now on we connect to root@host_ip using our SSH key env.hosts = ['localhost'] env.docker = True env.port = 2222 env.user = '******' if 'key_filename' not in env and 'key' not in env: env.key_filename = os.path.expanduser("~/.ssh/id_rsa") # Make sure we can connect via SSH to the newly started container # We disable the known hosts check since docker containers created at # different times might end up having the same IP assigned to them, and the # ssh known hosts check will fail # # NOTE: This does NOT work on a Mac, because the docker0 network is not # available! with settings(disable_known_hosts=True): execute(check_ssh) success('Container successfully setup! {0} installation will start now'.\ format(APP_name())) return DockerContainerState(cli, cont)