def manage(self, command): """ Django manage.py command execution. Local safe - could be used in cuisine_local() block. """ with cd(self.src_root): with self.virtualenv_safe(): print ("admin command dir %s" % cuisine.run("pwd")) cuisine.run("django-admin.py %s --pythonpath=%s" % (command, self.src_root))
def upload_code(self, update_submodules=True): self.before_upload_code() # we need to ensure the directory is open for writing with cuisine_sudo(): dir_attribs(self.remote_project_path, mode="777") temp_dir_prefix = "django_temp_" # zip and upload file temp_dir = temp_dir_prefix + self.project_name + "_" + timestamp_str() temp_remote_path = path(remote_home()).joinpath("tmp").joinpath(temp_dir) temp_local_path = path(self.project_local_path).joinpath(temp_dir) local_dir_ensure(temp_local_path) with cuisine_sudo(): dir_ensure(temp_remote_path, recursive=True, mode="666") files = self.scm.local_archive(temp_local_path, include_submodules=update_submodules) # upload files for dir, file in files.iteritems(): local_archive_path = temp_local_path.joinpath(file) remote_archive_path = temp_remote_path.joinpath(file) operations.put(str(local_archive_path), str(temp_remote_path), use_sudo=True) local_file_delete(local_archive_path) # reset project dir self.reset_project_dir() # unpack files for dir, file in files.iteritems(): remote_archive_path = temp_remote_path.joinpath(file) # unzip file with cuisine_sudo(): if self.webserver: self.webserver.stop() extdir = path(self.remote_project_path).joinpath(dir).abspath() dir_ensure(extdir, recursive=True, mode="777") file_unzip(remote_archive_path, extdir) file_delete(remote_archive_path) cuisine.run("cd %s" % self.src_root) cuisine.run("pwd") with cuisine_sudo(): cuisine.dir_attribs(self.remote_project_path, mode="777", recursive=True) for precomp in self.precompilers: precomp.compile() # clear old archives local_dirs_delete(self.project_local_path, "%s%s.*" % (temp_dir_prefix, self.project_name)) ## upload ends here self.after_upload_code()
def media_restore_local_latest(self): dump_basename = self.latest_media_dump_basename() dump_local_path = self.local_media_dump_dir.joinpath(dump_basename) dir_delete(self.local_media_root) dir_ensure(self.local_media_root) with cd(self.local_media_root): run("tar -xvzf %s" % dump_local_path)
def backup_database(self, file_name=''): filepath = path(self.backup_path).joinpath(self._create_db_backup_name() if file_name == '' else file_name) dump_command = "%s/pg_dump -O -x %s -U %s -w -h %s" % (self.bin_path, self.database_name, self.user, self.host) if self.use_zip: command = "%s | gzip > %s" % (dump_command, filepath) else: command = "%s > %s" % (dump_command, filepath) run(command)
def configure_webserver(self, name, config, delete_other_sites=False): if delete_other_sites: with cuisine_sudo(): clear_dir('/etc/apache2/sites-enabled') with cuisine_sudo(): cuisine.file_write('/etc/apache2/sites-enabled/%s' % name, config) run("ln -fs /etc/apache2/mods-available/rewrite.load /etc/apache2/mods-enabled/rewrite.load") run("ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load") print("Apache configured\n%s" % config)
def upload_code(self, update_submodules=True): if self.webserver: self.webserver.stop() self.before_upload_code() # we need to ensure the directory is open for writing with cuisine_sudo(): dir_attribs(self.remote_project_path, mode='777') self.clear_remote_project_path_save_site() temp_dir_prefix = 'django_temp_' # zip and upload file temp_dir = temp_dir_prefix + self.project_name + '_' + timestamp_str() temp_remote_path = path(self.remote_project_path).joinpath(temp_dir) temp_local_path = path(self.project_local_path).joinpath(temp_dir) local_dir_ensure(temp_local_path) dir_ensure(temp_remote_path) files = self.scm.local_archive(temp_local_path, include_submodules=update_submodules) for dir, file in files.iteritems(): local_archive_path = temp_local_path.joinpath(file) remote_archive_path = temp_remote_path.joinpath(file) put(str(local_archive_path), str(temp_remote_path), use_sudo=True) local_file_delete(local_archive_path) #unzip file with cuisine_sudo(): extdir = path(self.remote_project_path).joinpath(dir).abspath() dir_ensure(extdir, recursive=True, mode='777') file_unzip(remote_archive_path, extdir) file_delete(remote_archive_path) cuisine.run("cd %s" % self.src_root) cuisine.run("pwd") with cuisine_sudo(): cuisine.dir_attribs(self.remote_project_path, mode="777", recursive=True) for precomp in self.precompilers: precomp.compile() # clear old archives local_dirs_delete(self.project_local_path, '%s%s.*' % (temp_dir_prefix, self.project_name)) ## upload ends here self.after_upload_code() if self.webserver: self.webserver.start()
def init_database(self, init_sql_file, delete_if_exists=False, unzip=False): self.create_database(delete_if_exists) if unzip: command = "cat %s | gunzip | psql %s -w -U %s" else: command = "cat %s | psql %s -w -U %s" with self.pg_pass(): run(command % (init_sql_file, self.database_name, self.user)) sudo_pipeline("echo GRANT ALL ON SCHEMA public TO %s | psql" % self.user, user=self.superuser_login) sudo_pipeline("echo ALTER DATABASE %s OWNER TO %s | psql" % (self.database_name, self.user), user=self.superuser_login)
def download_media(self): media_dump_basename = "%s_media_%s.tar.gz" % (self.django.project_name, timestamp_str()) media_dump_remote_path = "%s/%s" % (remote_home(), media_dump_basename) media_dump_local_path = self.local_media_dump_dir.joinpath(media_dump_basename) with cd(self.django.media_root): cuisine.run("tar -cvzf %s ." % media_dump_remote_path) cuisine.file_attribs(media_dump_remote_path, '777') get(media_dump_remote_path, media_dump_local_path) with cuisine_sudo(): file_delete(media_dump_remote_path)
def setup(self): if not file_exists(self.lessc_path()): print("Installing Node and Less") cuisine.sudo("sudo apt-get --yes install python-software-properties") cuisine.sudo("sudo add-apt-repository ppa:chris-lea/node.js --yes") cuisine.sudo("sudo apt-get --yes update") cuisine.sudo("sudo apt-get --yes install nodejs") cuisine.run("curl http://npmjs.org/install.sh | sudo sh") with cd('~'): cuisine.run("npm install less") else: print ("Less is already installed")
def init(self, delete_if_exists, python_path=""): if self.use_virtualenv: virtualenv_full_path = path(self.virtualenv_path).joinpath(self.virtualenv_name) if cuisine.dir_exists(virtualenv_full_path) and delete_if_exists: dir_delete(virtualenv_full_path) with cuisine_sudo(): pip_install(['virtualenv']) with cuisine_sudo(): dir_ensure(self.virtualenv_path, recursive=True, mode=777) dir_attribs(self.virtualenv_path, mode=777, recursive=True) # make lib synlinks to install PIL correctly with cuisine_sudo(): if not file_exists("/usr/lib/libfreetype.so"): run("ln -sf /usr/lib/x86_64-linux-gnu/libfreetype.so /usr/lib/") if not file_exists("/usr/lib/libz.so"): run("ln -sf /usr/lib/x86_64-linux-gnu/libz.so /usr/lib/") if not file_exists("/usr/lib/libjpeg.so"): run("ln -sf /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib/") with cd(self.virtualenv_path): run('VIRTUALENV_EXTRA_SEARCH_DIR="%s" && virtualenv %s' % (python_path, self.virtualenv_name))
def reset_project_dir(self): home_dir = remote_home() site_path_basename = path(self.remote_site_path).name with cuisine_sudo(): cuisine.dir_ensure(self.remote_site_path, recursive=True, mode="777") cuisine.dir_ensure("%s/tmp" % home_dir, mode="777") dir_delete("%(home_dir)s/tmp/%(site_path_basename)s" % locals()) cuisine.run("mv %(site_dir)s %(home_dir)s/tmp" % {"site_dir": self.remote_site_path, "home_dir": home_dir}) clear_dir(self.remote_project_path) # restore site dir cuisine.run( "mv %(home_dir)s/tmp/%(site_dir_basename)s %(proj_path)s" % {"site_dir_basename": site_path_basename, "proj_path": self.remote_project_path, "home_dir": home_dir} )
def ls_re(root_dir, regex): """ Lists files in the dirs that match a reg ex """ dir_list = [filename for filename in re.split('\\s+',cuisine.run('ls %s' % root_dir)) if filename] re_obj = re.compile(regex) new_dir_list = [dir for dir in dir_list if re_obj.match(dir)] return new_dir_list
def clear_remote_project_path_save_site(self): home_dir = remote_home() site_path_basename = path(self.remote_site_path).name with cuisine_sudo(): cuisine.dir_ensure(self.remote_site_path, recursive=True, mode='777') cuisine.dir_ensure("%s/tmp" % home_dir, mode='777') dir_delete("%(home_dir)s/tmp/%(site_path_basename)s" % locals()) cuisine.run('mv %(site_dir)s %(home_dir)s/tmp' % {'site_dir': self.remote_site_path, 'home_dir': home_dir}) clear_dir(self.remote_project_path) #restore site dir cuisine.run('mv %(home_dir)s/tmp/%(site_dir_basename)s %(proj_path)s' % { 'site_dir_basename': site_path_basename, 'proj_path': self.remote_project_path, 'home_dir': home_dir })
def database_exists(self): query = "SELECT 1 AS result FROM pg_database WHERE datname='%s'" % self.database_name result = run(self.psql_command('template1', query)) if "0" in result: return False elif "1" in result: return True else: print("Result: %s" % result) raise RuntimeError("Unknown PostgreSQL result: %s" % result)
def restore_database(self, delete_if_exists=False): self.create_database(delete_if_exists) if self.use_zip: command = "cat %s | gunzip | %s" else: command = "cat %s | %s" init_sql_file = path(self.backup_path).joinpath(self.latest_db_dump_basename()) return run(command % (init_sql_file, self.psql_command_db()))
def pg_pass(self): run("echo *:*:%s:%s:%s > ~/.pgpass" % (self.database_name, self.user, self.password)) run("chmod 0600 ~/.pgpass") yield run("rm ~/.pgpass")
def version(self): version_info = cuisine.run("psql --version") version_line = version_info.split("\n")[0].strip() # assert len(version_line) > 7, "There's something wrong with Postgres version info: " + version_info return re.search("\\d+\\.\\d+\\.\\d+", version_line).group(0)
def test_full_version(self): cuisine.run = lambda arg: 'Python 2.6.6' tt = cuisine.run("python --version") a = self.python_manager.get_full_version() self.assertNotEquals(a, None) self.assertRegexpMatches(a, "^[\\d\\.]+$")
def file_delete(file): cuisine.run("rm %s" % file)
def dir_delete(dir_name): cuisine.run('rm -rf %s' % dir_name)
def status(self): result = run("service apache2 status") if "running" in result: return "running" else: return "stopped"
def sym_link(file_from, file_to): cuisine.run("ln -s %s %s" % (file_from, file_to))
def file_unzip(filename, extdir="."): cuisine.run("unzip %s -d %s" % (filename, extdir))
def create_user(self): run("echo CREATE USER %s WITH PASSWORD \\'%s\\' | %s" % (self.user, self.password, self.psql_command(as_dba=True)))
def file_delete(file, only_if_exists=True): if only_if_exists and not cuisine.file_exists(file): return cuisine.run("rm %s" % file)
def python_egg_ensure(egg_name): cuisine.run("pip install %s" % egg_name)
def psql(self, command, database="", as_dba=False): return run("echo \"%s\" | %s" % (command, self.psql_command(database, as_dba=as_dba)))
def clear_dir(dir): cuisine.run("rm -rf %s/*" % dir) cuisine.run("rm -rf %s/.??*" % dir)
def get_version_pattern(self, pattern): ver_str = cuisine.run('python --version') regex = re.compile(pattern) match = regex.match(ver_str) version = match.group(1) return version
def drop_database_connections(self): # self.psql("SELECT pg_terminate_backend(pg_stat_activity.procpid) FROM pg_stat_activity " \ # "WHERE pg_stat_activity.datname = '%s';" % self.database_name) # run("%s restart -D %s -w -m f" % (self.pg_ctl_path(), self.pgdata))