def restart_software_updater():
    """
  <Purpose>
    Attempts to start a new software updater, and will exit this one if the
    new one seems to start successfully.  If the new one does not start
    successfully, then we just return.

  <Arguments>
    None

  <Exceptions>
   Possible exception if there is problems writing the OK file.
 
  <Side Effects>
    If all goes well, a new softwareupdater will be started, and this one will
    exit.

  <Returns>
    In the successful case, it will not return.  If the new softwareupdater does
    not start correctly, we will return None.
  """

    safe_log(
        "[restart_software_updater] Attempting to restart software updater.")

    # find an unused mutex
    thismutex = get_mutex()

    # starts new with arg that is the mutex
    junkupdaterobject = portable_popen.Popen(
        ["python", "softwareupdater.py", thismutex])

    # wait for some time (1 minute) for them to init and stop them if they don't
    for junkcount in range(30):
        misc.do_sleep(2.0)

        # if "OK" file exists, release softwareupdater.old, remove OK file and exit
        if os.path.exists("softwareupdater.OK." + thismutex):
            runonce.releaseprocesslock('softwareupdater.old')
            os.remove("softwareupdater.OK." + thismutex)
            # I'm happy, it is taking over
            safe_log(
                "[restart_software_updater] The new instance of the software updater is running. This one is exiting."
            )
            sys.exit(10)

    # else write "stop" file because it failed...
    file("softwareupdater.stop." + thismutex, "w").close()

    safe_log(
        "[restart_software_updater] Failed to restart software updater. This instance will continue."
    )

    # I continue normal operation
    return
def restart_software_updater():
    """
  <Purpose>
    Attempts to start a new software updater, and will exit this one if the
    new one seems to start successfully.  If the new one does not start
    successfully, then we just return.

  <Arguments>
    None

  <Exceptions>
   Possible exception if there is problems writing the OK file.
 
  <Side Effects>
    If all goes well, a new softwareupdater will be started, and this one will
    exit.

  <Returns>
    In the successful case, it will not return.  If the new softwareupdater does
    not start correctly, we will return None.
  """

    safe_log("[restart_software_updater] Attempting to restart software updater.")

    # find an unused mutex
    thismutex = get_mutex()

    # starts new with arg that is the mutex
    junkupdaterobject = portable_popen.Popen(["python", "softwareupdater.py", thismutex])

    # wait for some time (1 minute) for them to init and stop them if they don't
    for junkcount in range(30):
        misc.do_sleep(2.0)

        # if "OK" file exists, release softwareupdater.old, remove OK file and exit
        if os.path.exists("softwareupdater.OK." + thismutex):
            runonce.releaseprocesslock("softwareupdater.old")
            os.remove("softwareupdater.OK." + thismutex)
            # I'm happy, it is taking over
            safe_log(
                "[restart_software_updater] The new instance of the software updater is running. This one is exiting."
            )
            sys.exit(10)

    # else write "stop" file because it failed...
    file("softwareupdater.stop." + thismutex, "w").close()

    safe_log("[restart_software_updater] Failed to restart software updater. This instance will continue.")

    # I continue normal operation
    return
Exemple #3
0
def sleep(seconds):
    """
   <Purpose>
      Allow the current event to pause execution (similar to time.sleep()).
      This function will not return early for any reason

   <Arguments>
      seconds:
         The number of seconds to sleep.   This can be a floating point value

   <Exceptions>
      None.

   <Side Effects>
      None.

   <Returns>
      None.
  """

    restrictions.assertisallowed('sleep', seconds)

    # Use the do_sleep implementation in misc
    misc.do_sleep(seconds)
Exemple #4
0
def sleep(seconds):
  """
   <Purpose>
      Allow the current event to pause execution (similar to time.sleep()).
      This function will not return early for any reason

   <Arguments>
      seconds:
         The number of seconds to sleep.   This can be a floating point value

   <Exceptions>
      None.

   <Side Effects>
      None.

   <Returns>
      None.
  """

  restrictions.assertisallowed('sleep',seconds)
  
  # Use the do_sleep implementation in misc
  misc.do_sleep(seconds)
def main():
  """
  <Purpose>
    Has an infinite loop where we sleep for 5-55 minutes, then check for 
    updates.  If an update happens, we will restart ourselves and/or the
    node manager as necesary.
    
  <Arguments>
    None

  <Exceptions>
    Any non-RsyncError exceptions from do_rsync.

  <Side Effects>
    If there is an update on the update site we are checking, it will be 
    grabbed eventually.

  <Return>
    Will not return.  Either an exception will be thrown, we exit because we
    are restarting, or we loop infinitely.
  """

  global restartme

  # This is similar to init only:
  #   1) we loop / sleep
  #   2) we restart ourselves if we are updated
  #   3) we restart our client if they are updated

  while True:
    # sleep for 5-55 minutes 
    for junk in range(random.randint(10, 110)):
      # We need to wake up every 30 seconds otherwise we will take
      # the full 5-55 minutes before we die when someone tries to
      # kill us nicely.
      misc.do_sleep(30)
      # Make sure we still have the process lock.
      # If not, we should exit
      if not runonce.stillhaveprocesslock('softwareupdater.old'):
        safe_log('[main] We no longer have the processlock\n')
        sys.exit(55)


    # Make sure that if we failed somehow to restart, we keep trying before
    # every time we try to update. - Brent
    if restartme:
      restart_software_updater()
      
    # where I'll put files...
    tempdir = tempfile.mkdtemp()+"/"


    # I'll clean this up in a minute
    try:
      updatedlist = do_rsync(softwareurl, "./",tempdir)
    except RsyncError:
      # oops, hopefully this will be fixed next time...
      continue

    finally:
      shutil.rmtree(tempdir)

    # no updates   :)   Let's wait again...
    if updatedlist == []:
      continue

    # if there were updates, the metainfo file should be one of them...
    assert('metainfo' in updatedlist)

    clientlist = updatedlist[:]

    if 'softwareupdater.py' in clientlist:
      restartme = True
      clientlist.remove('softwareupdater.py')

    # if the client software changed, let's update it!
    # AR: On Android, the native app takes care of starting/restarting 
    # the client and/or updater, depending on the exit code we return here.
    if clientlist != []:
      if not is_android:
        restart_client(clientlist)
      else:
        sys.exit(200) # Native app should restart both client and updater

    # oh! I've changed too.   I should restart...   search for MUTEX for info
    if restartme:
      if not is_android:
        restart_software_updater()
      else:
        sys.exit(201) # Native app should restart the updater
def software_updater_start(mutexname):
  """
  <Purpose>
    When restarting the software updater, this method is called in the new 
    one.  It will write an OK file to let the original know it has started,
    then will wait for the original to acknowledge by either removing the OK
    file, meaning we should carry on, or by writing a stop file, meaning we
    should exit.  Carrying on means getting the softwareupdater.old lock, and
    releasing the softwareupdater.new lock, then returning.
  
  <Arguments>
    mutexname - The new software updater was started with a given mutex name,
                which is used to uniquely identify the stop and OK files as
                coming from this softwareupdater.  This way the old one can
                know that the softwareupdater it started is the one that is
                continueing on.

  <Exceptions>
    Possible Exception creating the OK file.

  <Side Effects>
    Acquires the softwareupdater.old lock and releases the softwareupdater.new
    lock.

  <Return>
    None
  """

  safe_log("[software_updater_start] This is a new software updater process started by an existing one.")

  # if "stop" file exists, then exit
  if os.path.exists("softwareupdater.stop."+mutexname):
    safe_log("[software_updater_start] There's a stop file. Exiting.")
    sys.exit(2)

  # write "OK" file
  file("softwareupdater.OK."+mutexname,"w").close()
  
  # while "OK" file exists
  while os.path.exists("softwareupdater.OK."+mutexname):
    safe_log("[software_updater_start] Waiting for the file softwareupdater.OK."+mutexname+" to be removed.")
    misc.do_sleep(1.0)
    # if "stop" file exists, then exit
    if os.path.exists("softwareupdater.stop."+mutexname):
      sys.exit(3)

  # Get the process lock for the main part of the program.
  gotlock = runonce.getprocesslock("softwareupdater.old")
  # Release the lock on the initialization part of the program
  runonce.releaseprocesslock('softwareupdater.new')
  if gotlock == True:
    # I got the lock.   All is well...
    pass
  else:
    if gotlock:
      safe_log("[software_updater_start] Another software updater old process (pid: "+str(gotlock)+") is running")
      sys.exit(55)
    else:
      safe_log("[software_updater_start] Another software updater old process is running")
      sys.exit(55)
 
  safe_log("[software_updater_start] This software updater process is now taking over.")
 
  # start normal operation
  return
if __name__ == '__main__':
  read_environmental_options()
  if not run_softwareupdater_in_foreground:
    daemon.daemonize()

  # Initialize the service logger.
  safe_servicelogger_init()
  
  # problems here are fatal.   If they occur, the old updater won't stop...
  try:
    init()
  except Exception, e:
    safe_log_last_exception()
    raise e

  # in case there is an unexpected exception, continue (we'll sleep first thing
  # in main)
  while True:
    try:
      main()
    except SystemExit:
      # If there is a SystemExit exception, we should probably actually exit...
      raise
    except Exception, e:
      # Log the exception and let main() run again.
      safe_log_last_exception()
      # Sleep a little to prevent a fast loop if the exception is happening
      # before any other calls to do_sleep().
      misc.do_sleep(1.0)
def main(debug=False):
  """
  <Purpose>
    Has an infinite loop where we sleep for 5-55 minutes, then check for 
    updates.  If an update happens, we will restart ourselves and/or the
    node manager as necesary.
    
  <Arguments>
    None

  <Exceptions>
    Any non-RsyncError exceptions from do_rsync.

  <Side Effects>
    If there is an update on the update site we are checking, it will be 
    grabbed eventually.

  <Return>
    Will not return.  Either an exception will be thrown, we exit because we
    are restarting, or we loop infinitely.
  """

  global restartme

  # This is similar to init only:
  #   1) we loop / sleep
  #   2) we restart ourselves if we are updated
  #   3) we restart our client if they are updated

  while True:
    if debug:
      rint = 1
    else:
      rint = random.randint(10, 110)
    for junk in range(rint):
      # We need to wake up every 30 seconds otherwise we will take
      # the full 5-55 minutes before we die when someone tries to
      # kill us nicely.
      misc.do_sleep(1)
      # Make sure we still have the process lock.
      # If not, we should exit
      if not runonce.stillhaveprocesslock('softwareupdater.old'):
        safe_log('[main] We no longer have the processlock\n')
        sys.exit(55)

    # set the softwareurl based on whether debug is set
    if debug:
      softwareurl = 'http://localhost:12345'
    else:
      softwareurl = seattle_url

    # Make sure that if we failed somehow to restart, we keep trying before
    # every time we try to update. - Brent
    if restartme:
      restart_software_updater()
      
    # where I'll put files...
    tempdir = tempfile.mkdtemp()+"/"


    # I'll clean this up in a minute
    try:
      updatedlist = do_rsync(softwareurl, "./",tempdir)
    except Exception:
      safe_log_last_exception()
      # oops, hopefully this will be fixed next time...
      continue

    finally:
      shutil.rmtree(tempdir)

    safe_log('[main] rsync with server yielded the following changes: %s' % str(updatedlist))
    # no updates   :)   Let's wait again...
    if updatedlist == []:
      continue

    clientlist = updatedlist[:]
    if 'softwareupdater.py' in clientlist:
      restartme = True
      clientlist.remove('softwareupdater.py')

    # if the client software changed, let's update it!
    if clientlist != []:
      restart_client(clientlist)

    # oh! I've changed too.   I should restart...   search for MUTEX for info
    if restartme:
      restart_software_updater()

    if debug: break
Exemple #9
0
def main(debug=False):
  """
  <Purpose>
    Has an infinite loop where we sleep for 5-55 minutes, then check for 
    updates.  If an update happens, we will restart ourselves and/or the
    node manager as necesary.
    
  <Arguments>
    None

  <Exceptions>
    Any non-RsyncError exceptions from do_rsync.

  <Side Effects>
    If there is an update on the update site we are checking, it will be 
    grabbed eventually.

  <Return>
    Will not return.  Either an exception will be thrown, we exit because we
    are restarting, or we loop infinitely.
  """

  global restartme

  # This is similar to init only:
  #   1) we loop / sleep
  #   2) we restart ourselves if we are updated
  #   3) we restart our client if they are updated

  while True:
    if debug:
      rint = 1
    else:
      rint = random.randint(10, 110)
    for junk in range(rint):
      # We need to wake up every 30 seconds otherwise we will take
      # the full 5-55 minutes before we die when someone tries to
      # kill us nicely.
      misc.do_sleep(1)
      # Make sure we still have the process lock.
      # If not, we should exit
      if not runonce.stillhaveprocesslock('softwareupdater.old'):
        safe_log('[main] We no longer have the processlock\n')
        sys.exit(55)

    # set the softwareurl based on whether debug is set
    if debug:
      softwareurl = 'http://localhost:12345'
    else:
      softwareurl = seattle_url

    # Make sure that if we failed somehow to restart, we keep trying before
    # every time we try to update. - Brent
    if restartme:
      restart_software_updater()
      
    # where I'll put files...
    tempdir = tempfile.mkdtemp()+"/"


    # I'll clean this up in a minute
    try:
      updatedlist = do_rsync(softwareurl, "./",tempdir)
    except Exception:
      safe_log_last_exception()
      # oops, hopefully this will be fixed next time...
      continue

    finally:
      shutil.rmtree(tempdir)

    safe_log('[main] rsync with server yielded the following changes: %s' % str(updatedlist))
    # no updates   :)   Let's wait again...
    if updatedlist == []:
      continue

    clientlist = updatedlist[:]
    if 'softwareupdater.py' in clientlist:
      restartme = True
      clientlist.remove('softwareupdater.py')

    # if the client software changed, let's update it!
    if clientlist != []:
      restart_client(clientlist)

    # oh! I've changed too.   I should restart...   search for MUTEX for info
    if restartme:
      restart_software_updater()

    if debug: break