def default_paths(self): """Returns the default paths to use for various configuration options for this platform. @return: The default paths @rtype: DefaultPaths """ if self._install_type == PACKAGE_INSTALL: return DefaultPaths('/var/log/scalyr-agent-2', '/etc/scalyr-agent-2/agent.json', '/var/lib/scalyr-agent-2') elif self._install_type == TARBALL_INSTALL: install_location = get_install_root() return DefaultPaths( os.path.join(install_location, 'log'), os.path.join(install_location, 'config', 'agent.json'), os.path.join(install_location, 'data')) else: assert (self._install_type == DEV_INSTALL) # For developers only. We default to a directory ~/scalyr-agent-dev for storing # all log/data information, and then require a log, config, and data subdirectory in each of those. base_dir = os.path.join(os.path.expanduser('~'), 'scalyr-agent-dev') return DefaultPaths(os.path.join(base_dir, 'log'), os.path.join(base_dir, 'config', 'agent.json'), os.path.join(base_dir, 'data'))
def default_paths(self): """Returns the default paths to use for various configuration options for this platform. @return: The default paths @rtype: DefaultPaths """ # TODO: Change this to something that is not Linux-specific. Maybe we should always just default # to the home directory location. if self._install_type == PACKAGE_INSTALL: return DefaultPaths('/var/log/scalyr-agent-2', '/etc/scalyr-agent-2/agent.json', '/var/lib/scalyr-agent-2') elif self._install_type == TARBALL_INSTALL: install_location = get_install_root() return DefaultPaths(os.path.join(install_location, 'log'), os.path.join(install_location, 'config', 'agent.json'), os.path.join(install_location, 'data')) else: assert(self._install_type == DEV_INSTALL) # For developers only. We default to a directory ~/scalyr-agent-dev for storing # all log/data information, and then require a log, config, and data subdirectory in each of those. base_dir = os.path.join(os.path.expanduser('~'), 'scalyr-agent-dev') return DefaultPaths(os.path.join(base_dir, 'log'), os.path.join(base_dir, 'config', 'agent.json'), os.path.join(base_dir, 'data'))
def default_paths(self): """Returns the default paths to use for various configuration options for this platform. @return: The default paths @rtype: DefaultPaths """ if self._install_type == PACKAGE_INSTALL: return DefaultPaths( "/var/log/scalyr-agent-2", "/etc/scalyr-agent-2/agent.json", "/var/lib/scalyr-agent-2", ) elif self._install_type == TARBALL_INSTALL: install_location = get_install_root() return DefaultPaths( os.path.join(install_location, "log"), os.path.join(install_location, "config", "agent.json"), os.path.join(install_location, "data"), ) else: assert self._install_type == DEV_INSTALL # For developers only. We default to a directory ~/scalyr-agent-dev for storing # all log/data information, and then require a log, config, and data subdirectory in each of those. base_dir = os.path.join(os.path.expanduser("~"), "scalyr-agent-dev") return DefaultPaths( os.path.join(base_dir, "log"), os.path.join(base_dir, "config", "agent.json"), os.path.join(base_dir, "data"), )
def new_platform(): """Returns an instance of the first previously registered platform classes that can handle the server this process is running on. The platform class used is the first one that returns True when its 'can_handle_current_platform' method is invoked. They are checked in order of registration. @return: The PlatformController instance to use @rtype: PlatformController """ # Determine which type of install this is. We do this based on # whether or not certain files exist in the root of the source tree. install_root = get_install_root() if os.path.exists(os.path.join(install_root, 'packageless')): install_type = TARBALL_INSTALL elif os.path.exists(os.path.join(install_root, 'run_tests.py')): install_type = DEV_INSTALL else: install_type = PACKAGE_INSTALL for platform_class in PlatformController.__platform_classes__: result = platform_class(install_type) if result.can_handle_current_platform(): return result return None
def __resolve_to_install_location(*paths): """Returns the absolute path created by joining the specified intermediate paths to the install location for this package. @param paths: The file components of the desired path. There can be multiple, starting with the outer directory first and finishing with the last file. """ result = get_install_root() for path in paths: result = os.path.join(result, path) return result
def default_paths(self): """Returns the default paths to use for various configuration options for this platform. @return: The default paths @rtype: DefaultPaths """ # NOTE: For this module, it is assumed that the 'install_type' is always PACKAGE_INSTALL root = get_install_root() logdir = os.path.join(root, "log") libdir = os.path.join(root, "data") config = os.path.join(root, "config", "agent.json") return DefaultPaths(logdir, config, libdir)
def __determine_platform_type(): """Returns a string identifying the installation method that was used to install the agent, as well as the platform. TODO: This method doesn't return all platforms yet, just 'tarball' or 'linux'. """ # See if the source was installed using the tarball method, which # is identified by 'packageless' being a file in root of the install location for the source. # (Typically, the path looks like /usr/share/scalyr-agent-2/py/scalyr_agent/configuration.py, # where scalyr-agent-2 is the install location). tarball_install = os.path.exists(os.path.join(get_install_root(), 'packageless')) if tarball_install: return 'tarball' else: return 'linux'
def upgrade_tarball_install(config, new_tarball, preserve_old_install): """Performs an upgrade for an existing Scalyr Agent 2 that was previously installed using the tarball method. @param config: The configuration for this agent. @param new_tarball: The path to file containing the new tarball to install. @param preserve_old_install: If True, will move the old install directory to a new location rather than deleting it. @return: The exit status code. """ # Create a temporary directory hold the new install as we untar it and copy files into it. tmp_install_dir = tempfile.mkdtemp() # Some variables that capture some important state that we may need to unwind if we execute # out the installation along the way. # # If not None, then the directory we are currently holding the old installation directory in. preserve_dir = None # True if the agent was running when the install started. was_running = False # True if the agent was successfully restarted. was_restarted = False try: try: platform_controller = PlatformController.new_platform() my_default_paths = platform_controller.default_paths # Ensure that this is a tarball install if platform_controller.install_type != TARBALL_INSTALL: raise UpgradeFailure( 'The current agent was not installed using a tarball, so you may not use the ' 'upgrade tarball command.') # Ensure that the user has not changed the defaults for the config, data, and log directory. if my_default_paths.config_file_path != config.file_path: raise UpgradeFailure( 'The agent is not using the default configuration file so you may not use the ' 'upgrade tarball command.') if my_default_paths.agent_data_path != config.agent_data_path: raise UpgradeFailure( 'The agent is not using the default data directory so you may not use the upgrade ' 'tarball command.') if my_default_paths.agent_log_path != config.agent_log_path: raise UpgradeFailure( 'The agent is not using the default log directory so you may not use the upgrade ' 'tarball command.') # We rely on the current installation being included in the PATH variable. if spawn.find_executable('scalyr-agent-2-config') is None: raise UpgradeFailure( 'Could not locate the scalyr-agent-2-config command from the current ' 'installation. Please ensure that the agent\'s bin directory is in the system\'s ' 'PATH variable.') if not os.path.isfile(new_tarball): raise UpgradeFailure('The tarball file %s does not exist.' % new_tarball) file_name = os.path.basename(new_tarball) if re.match('^scalyr-agent-2\..*\.tar\.gz$', file_name) is None: raise UpgradeFailure( 'The supplied tarball file name does not match the expected format.' ) tarball_directory = file_name[0:-7] # We will be installing in the same directory where scalyr-agent-2 is currently installed. install_directory = os.path.dirname(get_install_root()) if not os.path.isdir( os.path.join(install_directory, 'scalyr-agent-2')): raise UpgradeFailure( 'Could not determine the install directory. Either the main directory is no ' 'longer called scalyr-agent-2, or the directory structure has changed.' ) # Compute the full paths to the scalyr-agent-2 directories for both the new install and old install. tmp_new_install_location = os.path.join(tmp_install_dir, tarball_directory) old_install_location = os.path.join(install_directory, 'scalyr-agent-2') # Untar the new package into the temp location. tar = tarfile.open(new_tarball, 'r:gz') for member in tar.getmembers(): tar.extract(member, path=tmp_install_dir) # Check to see if the agent is running. If so, stop it. was_running = run_command( 'scalyr-agent-2 stop', grep_for='Agent has stopped', command_name='scalyr-agent-2 stop')[0] == 0 # Copy the config, data, and log directories. for dir_name in ['config', 'log', 'data']: copy_dir_to_new_agent(old_install_location, tmp_new_install_location, dir_name) # Allow the new agent code to perform any actions it deems necessary. We do the special commandline # here where to pass in both directories to the --upgrade-tarball-command result = subprocess.call([ os.path.join(tmp_new_install_location, 'bin', 'scalyr-agent-2-config'), '--upgrade-tarball', '%s%s%s' % (old_install_location, os.pathsep, tmp_new_install_location) ]) if result != 0: raise UpgradeFailure( 'New package failed to finish the upgrade process.') # Move the old install directory to a temporary location, so we can undo the next move if we need to. preserve_dir = tempfile.mkdtemp() shutil.move(old_install_location, preserve_dir) # Move the new install into place. success = False try: shutil.move(tmp_new_install_location, old_install_location) success = True finally: if not success: # Move the old install back in place just to be safe. shutil.move(os.path.join(preserve_dir, 'scalyr-agent-2'), old_install_location) if success and not preserve_old_install: shutil.rmtree(preserve_dir) preserve_dir = None print 'New agent installed.' # Start the agent if it was previously running. if was_running: if run_command('scalyr-agent-2 start', exit_on_fail=False, command_name='scalyr-agent-2 start')[0] == 0: print 'Agent has successfully restarted.' print ' You may execute the following command for status details: scalyr-agent-2 status -v' was_restarted = True else: raise UpgradeFailure( 'Could not start the agent. Execute the following command for more details: ' 'scalyr-agent-2 start') else: print 'Execute the following command to start the agent: scalyr-agent-2 start' return 0 except UpgradeFailure, error: print >> sys.stderr print >> sys.stderr, 'The upgrade failed due to the following reason: %s' % error.message return 1 finally: # Delete the temporary directory. shutil.rmtree(tmp_install_dir) # Warn if we should have restarted the agent but did not. if was_running and not was_restarted: print '' print( 'WARNING, due to failure, the agent may no longer be running. Restart it with: scalyr-agent-2 ' 'start') # If there is still a preserve_directory, there must be a reason for it, so tell the user where it is. if preserve_dir is not None: print '' print 'The previous agent installation was left in \'%s\'' % preserve_dir print 'You should be sure to delete this directory once you no longer need it.'
def upgrade_tarball_install(config, new_tarball, preserve_old_install): """Performs an upgrade for an existing Scalyr Agent 2 that was previously installed using the tarball method. @param config: The configuration for this agent. @param new_tarball: The path to file containing the new tarball to install. @param preserve_old_install: If True, will move the old install directory to a new location rather than deleting it. @return: The exit status code. """ # Create a temporary directory hold the new install as we untar it and copy files into it. tmp_install_dir = tempfile.mkdtemp() # Some variables that capture some important state that we may need to unwind if we execute # out the installation along the way. # # If not None, then the directory we are currently holding the old installation directory in. preserve_dir = None # True if the agent was running when the install started. was_running = False # True if the agent was successfully restarted. was_restarted = False try: try: platform_controller = PlatformController.new_platform() my_default_paths = platform_controller.default_paths # Ensure that this is a tarball install if platform_controller.install_type != TARBALL_INSTALL: raise UpgradeFailure('The current agent was not installed using a tarball, so you may not use the ' 'upgrade tarball command.') # Ensure that the user has not changed the defaults for the config, data, and log directory. if my_default_paths.config_file_path != config.file_path: raise UpgradeFailure('The agent is not using the default configuration file so you may not use the ' 'upgrade tarball command.') if my_default_paths.agent_data_path != config.agent_data_path: raise UpgradeFailure('The agent is not using the default data directory so you may not use the upgrade ' 'tarball command.') if my_default_paths.agent_log_path != config.agent_log_path: raise UpgradeFailure('The agent is not using the default log directory so you may not use the upgrade ' 'tarball command.') # We rely on the current installation being included in the PATH variable. if spawn.find_executable('scalyr-agent-2-config') is None: raise UpgradeFailure('Could not locate the scalyr-agent-2-config command from the current ' 'installation. Please ensure that the agent\'s bin directory is in the system\'s ' 'PATH variable.') if not os.path.isfile(new_tarball): raise UpgradeFailure('The tarball file %s does not exist.' % new_tarball) file_name = os.path.basename(new_tarball) if re.match('^scalyr-agent-2\..*\.tar\.gz$', file_name) is None: raise UpgradeFailure('The supplied tarball file name does not match the expected format.') tarball_directory = file_name[0:-7] # We will be installing in the same directory where scalyr-agent-2 is currently installed. install_directory = os.path.dirname(get_install_root()) if not os.path.isdir(os.path.join(install_directory, 'scalyr-agent-2')): raise UpgradeFailure('Could not determine the install directory. Either the main directory is no ' 'longer called scalyr-agent-2, or the directory structure has changed.') # Compute the full paths to the scalyr-agent-2 directories for both the new install and old install. tmp_new_install_location = os.path.join(tmp_install_dir, tarball_directory) old_install_location = os.path.join(install_directory, 'scalyr-agent-2') # Untar the new package into the temp location. tar = tarfile.open(new_tarball, 'r:gz') for member in tar.getmembers(): tar.extract(member, path=tmp_install_dir) # Check to see if the agent is running. If so, stop it. was_running = run_command('scalyr-agent-2 stop', grep_for='Agent has stopped', command_name='scalyr-agent-2 stop')[0] == 0 # Copy the config, data, and log directories. for dir_name in ['config', 'log', 'data']: copy_dir_to_new_agent(old_install_location, tmp_new_install_location, dir_name) # Allow the new agent code to perform any actions it deems necessary. We do the special commandline # here where to pass in both directories to the --upgrade-tarball-command result = subprocess.call([os.path.join(tmp_new_install_location, 'bin', 'scalyr-agent-2-config'), '--upgrade-tarball', '%s%s%s' % (old_install_location, os.pathsep, tmp_new_install_location)]) if result != 0: raise UpgradeFailure('New package failed to finish the upgrade process.') # Move the old install directory to a temporary location, so we can undo the next move if we need to. preserve_dir = tempfile.mkdtemp() shutil.move(old_install_location, preserve_dir) # Move the new install into place. success = False try: shutil.move(tmp_new_install_location, old_install_location) success = True finally: if not success: # Move the old install back in place just to be safe. shutil.move(os.path.join(preserve_dir, 'scalyr-agent-2'), old_install_location) if success and not preserve_old_install: shutil.rmtree(preserve_dir) preserve_dir = None print 'New agent installed.' # Start the agent if it was previously running. if was_running: if run_command('scalyr-agent-2 start', exit_on_fail=False, command_name='scalyr-agent-2 start')[0] == 0: print 'Agent has successfully restarted.' print ' You may execute the following command for status details: scalyr-agent-2 status -v' was_restarted = True else: raise UpgradeFailure('Could not start the agent. Execute the following command for more details: ' 'scalyr-agent-2 start') else: print 'Execute the following command to start the agent: scalyr-agent-2 start' return 0 except UpgradeFailure, error: print >>sys.stderr print >>sys.stderr, 'The upgrade failed due to the following reason: %s' % error.message return 1 finally: # Delete the temporary directory. shutil.rmtree(tmp_install_dir) # Warn if we should have restarted the agent but did not. if was_running and not was_restarted: print '' print ('WARNING, due to failure, the agent may no longer be running. Restart it with: scalyr-agent-2 ' 'start') # If there is still a preserve_directory, there must be a reason for it, so tell the user where it is. if preserve_dir is not None: print '' print 'The previous agent installation was left in \'%s\'' % preserve_dir print 'You should be sure to delete this directory once you no longer need it.'