def __init__(rf): rf._is_open = False # Log entry self._log_entry = logger.log_file(self, mode=mode, remote_path=remote_path, use_sudo=use_sudo, sandboxing=sandbox) self._log_entry.__enter__() if sandbox: # Use dummy file in sandbox mode. rf._file = open('/dev/null', mode) else: if use_sudo: rf._temppath = self._tempfile(context) if self.exists(remote_path, context=context): # Copy existing file to available location self._run_silent_sudo("cp '%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) self._run_silent_sudo("chown '%s' '%s' " % (esc1(self.username), esc1(rf._temppath))) self._run_silent_sudo("chmod u+r,u+w '%s' " % esc1(rf._temppath)) elif mode.startswith('w'): # Create empty tempfile for writing (without sudo, # using current username) self._run_silent("touch '%s' " % esc1(rf._temppath)) else: raise IOError('Remote file: "%s" does not exist' % remote_path) # Open stream to this temp file rf._file = self.sftp.open(rf._temppath, mode) else: rf._file = self.sftp.open(remote_path, mode) rf._is_open = True
def create(self): """ Create this user and home directory. (Does not fail when the user or directory already exists.) """ if self.exists(): return useradd_args = [] useradd_args.append("'%s'" % esc1(self.username)) useradd_args.append("-s '%s'" % self.shell) if self.has_home_directory: useradd_args.append('-m') if self.home_directory_base: useradd_args.append("-b '%s'" % self.home_directory_base) else: useradd_args.append('-M') # Group if self.username == self.groupname: useradd_args.append('-U') else: if self.groupname: self.host.sudo("grep '%s' /etc/group || groupadd '%s'" % esc1(self.groupname), esc1(self.groupname)) useradd_args.append("-g '%s'" % esc1(self.groupname)) self.host.sudo("useradd " + " ".join(useradd_args))
def put(self, local_path, remote_path, use_sudo=False, logger=None): """ Upload this local_file to the remote location. """ logger = logger or self.dummy_logger # Expand paths local_path = self._expand_local_path(local_path) remote_path = self.expand_path(remote_path) # Log entry with logger.log_file(self, Actions.Put, mode='wb', remote_path=remote_path, local_path=local_path, use_sudo=use_sudo, sandboxing=self._sandboxing) as log_entry: try: if not self._sandboxing: if use_sudo: # Upload in tempfile temppath = self._tempfile() self.put(local_path, temppath) # Move tempfile to real destination self._run_silent_sudo("mv '%s' '%s'" % (esc1(temppath), esc1(remote_path))) # chmod? # TODO else: self.sftp.open(remote_path, 'wb').write(open(local_path, 'rb').read()) except Exception as e: log_entry.complete(False) raise e else: log_entry.complete(True)
def get(self, remote_path, local_path, use_sudo=False, logger=None): """ Download this remote_file. """ logger = logger or self.dummy_logger # Expand paths local_path = self._expand_local_path(local_path) remote_path = self.expand_path(remote_path) # Log entries with logger.log_file(self, Actions.Get, mode='rb', remote_path=remote_path, local_path=local_path, use_sudo=use_sudo, sandboxing=self._sandboxing) as log_entry: try: if use_sudo: if not self._sandboxing: # Copy file to available location temppath = self._tempfile() self._run_silent_sudo("mv '%s' '%s'" % (esc1(remote_path), esc1(temppath))) self._run_silent_sudo("chown '%s' '%s'" % (esc1(self.username), esc1(temppath))) self._run_silent_sudo("chmod u+r '%s'" % esc1(temppath)) # Download file self.get(temppath, local_path) # Remove temp file self._run_silent_sudo('rm "%s"' % temppath) else: open(local_path, 'wb').write(self.sftp.open(remote_path, 'rb').read()) except Exception as e: log_entry.complete(False) raise e else: log_entry.complete(True)
def execute_sql(self, database, sql, role='master'): """ Run this SQL code. (Normally, you only run sql on the master database.) """ self.hosts.filter(role).sudo("echo ';%s;' | /usr/local/pgsql/bin/psql -p '%s' -d '%s' " % (esc1(sql), esc1(str(self.port)), esc1(database)), user='******')
def content(self): self = self.parent extra_scripts = '' for s in ('start', 'stop'): for p in ('pre', 'post'): script = getattr(self, '%s_%s_script' % (p, s), '') if script: extra_scripts += """ %s-%s script %s end script """ % (p, s, indent(script)) return upstart_template % { 'description': esc1(self.description), 'author': esc1(self.author), 'chdir': esc1(self.chdir), 'start_on': self.start_on, 'stop_on': self.stop_on, 'command': self.full_command, 'user': esc1(self.user), 'extra': self.extra, 'extra_scripts': extra_scripts, }
def add_user(self, user, password, admin=True): try: self.hosts.sudo("rabbitmqctl list_users | grep '%s'" % user) except ExecCommandFailed: self.hosts.sudo("rabbitmqctl add_user '%s' '%s'" % (esc1(user), esc1(password))) if admin: self.hosts.sudo("rabbitmqctl set_user_tags '%s' administrator" % esc1(user))
def create(self): """ Create this user and home directory. (Does not fail when the user or directory already exists.) """ if self.exists(): return useradd_args = [] useradd_args.append("'%s'" % esc1(self.username)) useradd_args.append("-s '%s'" % self.shell) if self.has_home_directory: useradd_args.append('-m') if self.home_directory_base: useradd_args.append("-b '%s'" % self.home_directory_base) else: useradd_args.append('-M') # Group if self.username == self.groupname: useradd_args.append('-U') else: if self.groupname: self.host.sudo( "grep '%s' /etc/group || groupadd '%s'" % esc1(self.groupname), esc1(self.groupname)) useradd_args.append("-g '%s'" % esc1(self.groupname)) self.host.sudo("useradd " + " ".join(useradd_args))
def backup(self): """ Create a backup of this configuration file on the same host, in the same directory. """ import datetime suffix = datetime.datetime.now().strftime('%Y-%m-%d--%H-%M-%S') self.host.sudo("test -f '%s' && cp --archive '%s' '%s.%s'" % ( esc1(self.remote_path), esc1(self.remote_path), esc1(self.remote_path), esc1(suffix)))
def rmpidfile(self): """ Remove pidfile, sometimes it can happen that the pidfile was created, and the server crached due to a bad configuration, without removing the pidfile. """ if input('Remove pidfile', answers=['y', 'n']) == 'y': self.hosts.sudo("kill -SIGQUIT ` cat '%s' ` || rm '%s' " % (esc1(self.pidfile), esc1(self.pidfile)))
def wget(url, target=None): """ Download file using wget """ if target: return "wget '%s' --output-document '%s'" % (esc1(url), esc1(target)) else: return "wget '%s'" % esc1(url)
def mkvirtualenv(self): with self.host.env('WORKON_HOME', os.path.dirname(self.virtual_env_location)): python_req = '-p %s' % esc1( self.python_version) if self.python_version else '' self.host.run( ". /usr/local/bin/virtualenvwrapper.sh && mkvirtualenv '%s' %s || true" % (esc1(self.virtual_env_location), python_req))
def _checkout(self, changeset): # Clone the fist time existed = self.host.exists(self.repository_location) if not existed: self.host.run("hg clone '%s' '%s'" % (esc1(self.repository), esc1(self.repository_location))) # Checkout with self.host.cd(self.repository_location): self.host.run("hg checkout '%s'" % esc1(changeset))
def backup(self): """ Create a backup of this configuration file on the same host, in the same directory. """ import datetime suffix = datetime.datetime.now().strftime('%Y-%m-%d--%H-%M-%S') self.host.sudo("test -f '%s' && cp --archive '%s' '%s.%s'" % (esc1(self.remote_path), esc1(self.remote_path), esc1(self.remote_path), esc1(suffix)))
def exists(self, filename): """ Returns True when this file exists. """ try: self._run_silent_sudo("test -f '%s' || test -d '%s'" % (esc1(filename), esc1(filename))) return True except ExecCommandFailed: return False
def install_requirements(self): """ Install packages through PIP. """ with self.host.prefix(self.activate_cmd): for f in self.requirements_files: self.host.run(_pip_install("-r '%s'" % esc1(f))) for r in self.requirements: self.host.run(_pip_install("'%s'" % esc1(r)))
def upgrade_requirements(self): """ Upgrade packages through PIP. """ with self.hosts.prefix(self.activate_cmd): for f in self.requirements_files: self.hosts.run(_pip_install("-U -r '%s'" % esc1(f))) for r in self.requirements: self.hosts.run(_pip_install("-U '%s'" % esc1(r)))
def upgrade_requirements_since(self, commit='-1', end_commit=None): """ Upgrade requirements changed since a commit. If you pass a negative number as the commit SHA, it means "the Nth change of the file". So -1 means the last change, -2 the change before that, ... """ requested_end_commit = end_commit for host in self.hosts: with host.prefix(self.activate_cmd): for requirements_file in self.requirements_files: # Change to directory, otherwise we need --git-dir, # which doesn't work with specifing files (git log -- <file>) with host.cd(posixpath.dirname(requirements_file)): # Define start and end commits start_commit = commit if commit[0] == '-': log_count = int(commit) - 1 # We want the changes before this one start_commit = host.run("git log --pretty=%%h %s -- '%s' | tail -1" % (log_count, esc1(requirements_file)), interactive=False).strip() # Or should end_commit always be HEAD? # Now we might miss changes in the file that are not committed # (Of course, they should be missed - don't forget to commit your stuff, dammit!) end_commit = requested_end_commit if not end_commit: end_commit = host.run("git log --pretty=%h -1 | tail -1", interactive=False).strip() # Take diff of the requirements file requirements_diff = host.run("git diff %s..%s -- '%s'" % (start_commit, end_commit, esc1(requirements_file)), interactive=False) DIFF_HEADER_LINE_COUNT = 5 requirements_to_update = [] if 0 < len(requirements_diff): for line in requirements_diff.splitlines()[DIFF_HEADER_LINE_COUNT:]: if '+' == line[0]: requirements_to_update.append(line[1:]) # Also update lines with 'auto-update' try: requirements_autoupdate = host.run("grep auto-update '%s'" % esc1(requirements_file), interactive=False) for r in requirements_autoupdate.splitlines(): if r not in requirements_to_update: requirements_to_update.append(r) except ExecCommandFailed: # Nothing found in grep, no problem pass if 0 == len(requirements_to_update): print 'No requirements to update' continue # Write lines to a file, pass it to pip requirements_diff_file = '/tmp/requirements-%s-%s.txt' % (start_commit, end_commit) host.open(requirements_diff_file, 'w').write('\n'.join(requirements_to_update)) host.run(_pip_install("--no-dependencies -U -r '%s'" % esc1(requirements_diff_file))) host.run("rm '%s'" % esc1(requirements_diff_file))
def exists(self, filename, use_sudo=True, **kw): """ Returns ``True`` when a file named ``filename`` exists on this hosts. """ # Note: the **kw is required for passing in a HostContext. try: self._run_silent("test -f '%s' || test -d '%s'" % (esc1(filename), esc1(filename)), use_sudo=use_sudo, **kw) return True except ExecCommandFailed: return False
def log_run(self, run_entry): if not run_entry.sandboxing: run_entry.host._run_silent(""" mkdir -p ~/.deployer/; echo -n `date '+%%Y-%%m-%%d %%H:%%M:%%S | ' ` >> ~/.deployer/history; echo -n '%s | %s | %s | ' >> ~/.deployer/history; echo '%s' >> ~/.deployer/history; """ % ('sudo' if run_entry.use_sudo else ' ', esc1(self.from_host), esc1( self.username), esc1(run_entry.command))) return RunCallback()
def setup(self): parent = self.parent parent.create_socket_directory() # Install config Config.setup(self) self.hosts.sudo("chown '%s' '%s' " % (esc1(parent.username), esc1(self.remote_path))) # Give write permissions to logging file self.hosts.sudo("touch '%s' " % esc1(parent.logfile)) self.hosts.sudo("chown '%s' '%s' " % (esc1(parent.username), esc1(parent.logfile)))
def log_run(self, run_entry): if not run_entry.sandboxing: run_entry.host._run_silent(""" mkdir -p ~/.deployer/; echo -n `date '+%%Y-%%m-%%d %%H:%%M:%%S | ' ` >> ~/.deployer/history; echo -n '%s | %s | %s | ' >> ~/.deployer/history; echo '%s' >> ~/.deployer/history; """ % ('sudo' if run_entry.use_sudo else ' ', esc1(self.from_host), esc1(self.username), esc1(run_entry.command) )) return RunCallback()
def create(self): """ Create this user and home directory. (Does not fail when the user or directory already exists.) """ username = esc1(self.username) home_directory = esc1(self.home_directory) shell = esc1(self.shell) # Create user if he doesn't exists yet self.hosts.sudo("grep '%s' /etc/passwd || useradd '%s' -d '%s' -s '%s' " % (username, username, home_directory, shell)) # Create home directory, and make this user the owner self.hosts.sudo("mkdir -p '%s' " % home_directory) self.hosts.sudo("chown %s:%s '%s' " % (username, username, self.home_directory))
def on_host(container): try: container.run("which '%s'" % esc1(command), use_sudo=use_sudo, interactive=False, sandbox=False) return True except ExecCommandFailed: return False
def close(rf): if rf._is_open: try: rf._file.close() if not rf._sandboxing: if use_sudo: # Restore permissions (when this file already existed.) if self.exists(remote_path): self._run_silent_sudo("chown --reference='%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) self._run_silent_sudo("chmod --reference='%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) # Move tempfile back in place self._run_silent_sudo("mv '%s' '%s' " % (esc1(rf._temppath), esc1(remote_path))) # chmod? # TODO except Exception as e: self._log_entry.complete(False) raise e else: self._log_entry.complete(True) self._log_entry.__exit__() rf._is_open=False
def add_vhost(self, vhost, user=None): try: self.hosts.sudo("rabbitmqctl list_vhosts | grep '%s'" % vhost) except ExecCommandFailed: self.hosts.sudo("rabbitmqctl add_vhost '%s'" % esc1(vhost)) if user: self.add_user_to_vhost(vhost, user)
def install_requirements(self): """ Script to install the requirements of our Django application. (We have a requirements.txt file in our repository.) """ with self.host.prefix(self.activate_cmd): for f in self.requirements_files: self.host.run("pip install -r '%s' " % esc1(f))
def get(self, remote_path, local_path, use_sudo=False, logger=None): """ Download this remote_file. """ logger = logger or self.dummy_logger # Expand paths local_path = self._expand_local_path(local_path) remote_path = self.expand_path(remote_path) # Log entries with logger.log_file(self, Actions.Get, mode='rb', remote_path=remote_path, local_path=local_path, use_sudo=use_sudo, sandboxing=self._sandboxing) as log_entry: try: if use_sudo: if not self._sandboxing: # Copy file to available location temppath = self._tempfile() self._run_silent_sudo( "mv '%s' '%s'" % (esc1(remote_path), esc1(temppath))) self._run_silent_sudo( "chown '%s' '%s'" % (esc1(self.username), esc1(temppath))) self._run_silent_sudo("chmod u+r '%s'" % esc1(temppath)) # Download file self.get(temppath, local_path) # Remove temp file self._run_silent_sudo('rm "%s"' % temppath) else: open(local_path, 'wb').write(self.sftp.open(remote_path, 'rb').read()) except Exception as e: log_entry.complete(False) raise e else: log_entry.complete(True)
def has_command(self, command): """ Test whether this command can be found in the bash shell, by executing a 'which' """ try: self._run_silent("which '%s'" % esc1(command)) return True except ExecCommandFailed: return False
def force_stop(self): """ When the upstart service was stopped, but there are still open connections to the database, it's possible it won't stop immediately. You will get following error. This command will tell the database not to wait. # psql: FATAL: the database system is shutting down """ self.hosts.filter('master', 'slaves').sudo("/usr/local/pgsql/bin/pg_ctl --pgdata '%s' -m immediate stop" % esc1(self.postgres_data_directory), user='******')
def content(self): self = self.parent if self.post_stop_script: post_stop_script = post_stop_script_template % { 'content': indent(self.post_stop_script), } else: post_stop_script = '' return upstart_template % { 'description': esc1(self.description), 'author': esc1(self.author), 'chdir': esc1(self.chdir), 'command': self.full_command, 'user': esc1(self.user), 'post_stop_script': post_stop_script, }
def find_version_of_package(self, package): """ Return the installed version of a certain package """ with self.host.prefix(self.activate_cmd): try: return self.host.run("pip freeze | grep '^%s' " % esc1(package)).strip() except ExecCommandFailed: # Nothing found in grep, return None return None
def _checkout(self, commit): """ This will either clone or checkout the given commit. Changes in the repository are always stashed before checking out, and stash-popped afterwards. """ # Checkout on every host. for host in self.hosts: existed = host.exists(self.repository_location) if not existed: # Do a new checkout host.run("git clone --recursive %s %s" % (self.repository, self.repository_location)) with host.cd(self.repository_location): host.run("git fetch --all --prune") # Check whether commit exists check_commit = "git show '%s' --oneline --summary > /dev/null" host.run(check_commit % esc1(commit)) # Stash if existed: host.run("git stash") # Checkout host.run("git checkout '%s'" % esc1(commit)) host.run("git submodule update --init") # Also load submodules. # Pop stash if existed: try: host.run( "git stash pop 2>&1", interactive=False ) # will fail when checkout had no local changes except ExecCommandFailed, e: result = e.result if result.strip() not in ("Nothing to apply", "No stash found."): print result if not confirm("Should we continue?"): raise Exception("Problem with popping your stash, please check logs and try again.")
def shell(self, database='postgres'): """ Open a shell. Prefer the master host if a master is available, otherwise, open a shell on a slave. """ if self.hosts.filter('master'): host = self.hosts.filter('master') else: host = self.hosts.filter('slaves') host[0].sudo("/usr/local/pgsql/bin/psql -p %s -U postgres -d '%s' " % (self.port, esc1(database)), user='******')
def setup(self): """ Install config on remote machines. """ # Backup existing configuration if self.always_backup_existing_config: self.backup() self.host.open(self.remote_path, 'wb', use_sudo=self.use_sudo).write(self.content) if self.make_executable: self.host.sudo("chmod a+x '%s'" % esc1(self.host.expand_path(self.remote_path)))
def close(rf): if rf._is_open: try: rf._file.close() if not rf._sandboxing: if use_sudo: # Restore permissions (when this file already existed.) if self.exists(remote_path): self._run_silent_sudo( "chown --reference='%s' '%s' " % (esc1(remote_path), esc1( rf._temppath))) self._run_silent_sudo( "chmod --reference='%s' '%s' " % (esc1(remote_path), esc1( rf._temppath))) # Move tempfile back in place self._run_silent_sudo( "mv '%s' '%s' " % (esc1(rf._temppath), esc1(remote_path))) # chmod? # TODO except Exception as e: self._log_entry.complete(False) raise e else: self._log_entry.complete(True) self._log_entry.__exit__() rf._is_open = False
def put(self, local_path, remote_path, use_sudo=False, logger=None): """ Upload this local_file to the remote location. """ logger = logger or self.dummy_logger # Expand paths local_path = self._expand_local_path(local_path) remote_path = self.expand_path(remote_path) # Log entry with logger.log_file(self, Actions.Put, mode='wb', remote_path=remote_path, local_path=local_path, use_sudo=use_sudo, sandboxing=self._sandboxing) as log_entry: try: if not self._sandboxing: if use_sudo: # Upload in tempfile temppath = self._tempfile() self.put(local_path, temppath) # Move tempfile to real destination self._run_silent_sudo( "mv '%s' '%s'" % (esc1(temppath), esc1(remote_path))) # chmod? # TODO else: self.sftp.open(remote_path, 'wb').write( open(local_path, 'rb').read()) except Exception as e: log_entry.complete(False) raise e else: log_entry.complete(True)
def __init__(rf): rf._is_open = False # Remember sandboxing state in here. (To make sure it's still # the same on __exit__) rf._sandboxing = self._sandboxing # Log entry self._log_entry = logger.log_file(self, Actions.Open, mode=mode, remote_path=remote_path, use_sudo=use_sudo, sandboxing=rf._sandboxing) self._log_entry.__enter__() if rf._sandboxing: # Use dummy file in sandbox mode. rf._file = open('/dev/null', mode) else: if use_sudo: rf._temppath = self._tempfile() if self.exists(remote_path): # Copy existing file to available location self._run_silent_sudo("cp '%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) self._run_silent_sudo("chown '%s' '%s' " % (esc1(self.username), esc1(rf._temppath))) self._run_silent_sudo("chmod u+r,u+w '%s' " % esc1(rf._temppath)) elif mode.startswith('w'): # Create empty tempfile for writing (without sudo, # using current username) self._run_silent("touch '%s' " % esc1(rf._temppath)) else: raise Exception('Remote file: "%s" does not exist' % remote_path) # Open stream to this temp file rf._file = self.sftp.open(rf._temppath, mode) else: rf._file = self.sftp.open(remote_path, mode) rf._is_open = True
def install(self): AptGet.install(self) for h in self.hosts: with h.cd('/tmp'): # Download tmux in /tmp self.hosts.run("wget '%s' -O /tmp/tmux.tgz" % esc1(Tmux.url)) self.hosts.run("tar xvzf tmux.tgz") with h.cd('tmux-1.*'): # ./configure; make; sudo make install self.hosts.run("./configure") self.hosts.run("make") self.hosts.sudo("make install")
def content(self): self = self.parent extra_scripts = '' for s in ('start', 'stop'): for p in ('pre', 'post'): script = getattr(self, '%s_%s_script' % (p, s), '') if script: extra_scripts += """ %s-%s script %s end script """ % (p, s, indent(script)) return upstart_template % { 'description': esc1(self.description), 'author': esc1(self.author), 'chdir': esc1(self.chdir), 'command': self.full_command, 'user': esc1(self.user), 'extra': self.extra, 'extra_scripts': extra_scripts, }
def env(self, variable, value, escape=True): """ Set this environment variable """ if escape: value = "'%s'" % esc1(value) class ENV(object): def __enter__(context): self._env.append((variable, value)) def __exit__(context, *args): self._env.pop() return ENV()
def __init__(rf): rf._is_open = False # Remember sandboxing state in here. (To make sure it's still # the same on __exit__) rf._sandboxing = self._sandboxing # Log entry self._log_entry = logger.log_file(self, Actions.Open, mode=mode, remote_path=remote_path, use_sudo=use_sudo, sandboxing=rf._sandboxing) self._log_entry.__enter__() if rf._sandboxing: # Use dummy file in sandbox mode. rf._file = open('/dev/null', mode) else: if use_sudo: rf._temppath = self._tempfile() if self.exists(remote_path): # Copy existing file to available location self._run_silent_sudo( "cp '%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) self._run_silent_sudo( "chown '%s' '%s' " % (esc1(self.username), esc1(rf._temppath))) self._run_silent_sudo("chmod u+r,u+w '%s' " % esc1(rf._temppath)) elif mode.startswith('w'): # Create empty tempfile for writing (without sudo, # using current username) self._run_silent("touch '%s' " % esc1(rf._temppath)) else: raise Exception( 'Remote file: "%s" does not exist' % remote_path) # Open stream to this temp file rf._file = self.sftp.open(rf._temppath, mode) else: rf._file = self.sftp.open(remote_path, mode) rf._is_open = True
def _checkout(self, commit): """ This will either clone or checkout the given commit. Changes in the repository are always stashed before checking out, and stash-popped afterwards. """ # Checkout on every host. host = self.host existed = host.exists(self.repository_location) if not existed: # Do a new checkout host.run('git clone --recursive %s %s' % (self.repository, self.repository_location)) with host.cd(self.repository_location): host.run('git fetch --all --prune') self._before_checkout_hook(commit) # Stash if existed: host.run('git stash') # Checkout try: host.run("git checkout '%s'" % esc1(commit)) host.run("git submodule update --init") # Also load submodules. finally: # Pop stash try: if existed: host.run('git stash pop 2>&1', interactive=False) # will fail when checkout had no local changes except ExecCommandFailed, e: result = e.result if result.strip() not in ('Nothing to apply', 'No stash found.'): print result if not self.console.confirm('Should we continue?', default=True): raise Exception('Problem with popping your stash, please check logs and try again.')
def env(self, variable, value, escape=True): """ Set this environment variable :: with host.cd('VAR', 'my-value'): host.run('echo $VAR') """ if value is None: value = '' if escape: value = "'%s'" % esc1(value) class ENV(object): def __enter__(context): self._env.append((variable, value)) def __exit__(context, *args): self._env.pop() return ENV()
def __init__(rf): rf._is_open = False # Log entry self._log_entry = self.logger.log_file(self, mode=mode, remote_path=remote_path, use_sudo=use_sudo, sandboxing=sandbox) self._log_entry.__enter__() if sandbox: # Use dummy file in sandbox mode. rf._file = open('/dev/null', mode) else: if use_sudo: rf._temppath = self._tempfile() if self.exists(remote_path): # Copy existing file to available location self._run_silent_sudo( "cp '%s' '%s' " % (esc1(remote_path), esc1(rf._temppath))) self._run_silent_sudo( "chown '%s' '%s' " % (esc1(self.username), esc1(rf._temppath))) self._run_silent_sudo("chmod u+r,u+w '%s' " % esc1(rf._temppath)) elif mode.startswith('w'): # Create empty tempfile for writing (without sudo, # using current username) self._run_silent("touch '%s' " % esc1(rf._temppath)) else: raise IOError('Remote file: "%s" does not exist' % remote_path) # Open stream to this temp file rf._file = self._open(rf._temppath, mode) else: rf._file = self._open(remote_path, mode) rf._is_open = True
def new_window_command(self): """ When a new window is opened, run this command. """ return "python -c 'from deployer.run.socket_client import start; import sys; start(sys.argv[1])' '%s' " % esc1( self.socket_path)
def tail_logfile(self): self.host.sudo("tail -n 20 -f '%s'" % esc1(self.logfile))
def touch_logfile(self): # Touch and chown logfile. self.host.sudo("touch '%s'" % esc1(self.logfile)) self.host.sudo("chown '%s' '%s'" % (esc1(self.username), esc1(self.logfile)))
def git_checkout(self, commit): """ Checkout specific commit (after cloning).""" with self.host.cd('~/git/django-project', expand=True): self.host.run("git checkout '{}'".format(esc1(commit)))
def git_clone(self): """ Clone repository.""" with self.host.cd(self.project_directory, expand=True): self.host.run("git clone '{}'".format(esc1(self.repository)))