Hello community,

here is the log from the commit of package google-daemon for openSUSE:Factory 
checked in at 2015-08-03 17:22:39
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/google-daemon (Old)
 and      /work/SRC/openSUSE:Factory/.google-daemon.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "google-daemon"

Changes:
--------
--- /work/SRC/openSUSE:Factory/google-daemon/google-daemon.changes      
2015-03-19 21:16:32.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.google-daemon.new/google-daemon.changes 
2015-08-03 17:22:40.000000000 +0200
@@ -1,0 +2,15 @@
+Mon Aug  3 08:26:42 UTC 2015 - [email protected]
+
+- Update to version 1.2.7 (bnc#940190)
+  + Fix check for gcua
+  + Preventing the accounts manager from starting if GCUA is
+    installed.
+  + Remove temp files when move operation fails
+  + Fix string formatting.
+  + Documentation should point to gcloud compute instead of the
+    deprecated gcutil.
+  + Use /bin/ip instead of /sbin/ip
+  + Google clock sync manager to sync the system clock when a migration
+    occurs. Fix white space in existing daemons to be consistent.
+
+-------------------------------------------------------------------

Old:
----
  google-daemon-1.2.4.tar.bz2

New:
----
  google-daemon-1.2.7.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ google-daemon.spec ++++++
--- /var/tmp/diff_new_pack.UMoZtQ/_old  2015-08-03 17:22:41.000000000 +0200
+++ /var/tmp/diff_new_pack.UMoZtQ/_new  2015-08-03 17:22:41.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           google-daemon
-Version:        1.2.4
+Version:        1.2.7
 Release:        0
 Summary:        VM management inside GCE
 License:        Apache-2.0
@@ -100,7 +100,7 @@
 
 %files
 %defattr(-,root,root,-)
-%doc LICENSE
+%doc LICENSE README.md
 %{_datadir}/google/google_daemon/*
 %{_sbindir}/rcgoogle-address-manager
 %{_sbindir}/rcgoogle-accounts-manager

++++++ google-daemon-1.2.4.tar.bz2 -> google-daemon-1.2.7.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/google-daemon-1.2.4/README.md 
new/google-daemon-1.2.7/README.md
--- old/google-daemon-1.2.4/README.md   2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/README.md   2015-07-11 02:13:30.000000000 +0200
@@ -8,7 +8,7 @@
 
     /usr/share/google/google_daemon/manage_accounts.py
 
-Your users can create ssh keys for accounts on a virtual machine using 
[gcutil](http://developers.google.com/compute/docs/gcutil "gcutil") or manually 
using these steps:
+Your users can create ssh keys for accounts on a virtual machine using [gcloud 
compute](https://cloud.google.com/compute/docs/gcloud-compute/) or manually 
using these steps:
 
     # Generate the ssh keys
     $ ssh-keygen -t rsa -f ~/.ssh/google_compute_engine
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/etc/init/google-clock-sync-manager.conf 
new/google-daemon-1.2.7/etc/init/google-clock-sync-manager.conf
--- old/google-daemon-1.2.4/etc/init/google-clock-sync-manager.conf     
1970-01-01 01:00:00.000000000 +0100
+++ new/google-daemon-1.2.7/etc/init/google-clock-sync-manager.conf     
2015-07-11 02:13:30.000000000 +0200
@@ -0,0 +1,5 @@
+# This service syncs the clock after migration in a Google Compute Engine 
instance.
+start on google-rc-local-has-run
+
+respawn
+exec /usr/share/google/google_daemon/manage_clock_sync.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/etc/init.d/google-clock-sync-manager 
new/google-daemon-1.2.7/etc/init.d/google-clock-sync-manager
--- old/google-daemon-1.2.4/etc/init.d/google-clock-sync-manager        
1970-01-01 01:00:00.000000000 +0100
+++ new/google-daemon-1.2.7/etc/init.d/google-clock-sync-manager        
2015-07-11 02:13:30.000000000 +0200
@@ -0,0 +1,153 @@
+#! /bin/sh
+# Copyright 2015 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+#     Unless required by applicable law or agreed to in writing, software
+#     distributed under the License is distributed on an "AS IS" BASIS,
+#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#     See the License for the specific language governing permissions and
+#     limitations under the License.
+#
+### BEGIN INIT INFO
+# Provides:    google-clock-manager
+# Required-Start:    $network $syslog
+# Required-Stop:     $network
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Example initscript
+# Description:       This file should be used to construct scripts to be
+#        placed in /etc/init.d.
+### END INIT INFO
+
+# Do NOT "set -e"
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/sbin:/usr/sbin:/bin:/usr/bin
+DESC="Google clock sync manager"
+NAME=google-clock-sync-manager
+DAEMON=/usr/share/google/google_daemon/manage_clock_sync.py
+DAEMON_ARGS=""
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Load the VERBOSE setting and other rcS variables
+. /lib/init/vars.sh
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
+# and status_of_proc is working.
+. /lib/lsb/init-functions
+
+# If we're running under upstart, let the upstart config file handle things.
+# Debian 7 and newer have a near-one-liner function to detect this...
+if type init_is_upstart >/dev/null 2>&1; then
+  # ... which we can use if present.
+  init_is_upstart && exit 0
+else
+  # Otherwise, directly include the core line of Debian 7's version.
+  # Authorship credit: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=661109
+  if [ -x /sbin/initctl ] && /sbin/initctl version | /bin/grep -q upstart; then
+    exit 0
+  fi
+fi
+
+#
+# Function that starts the daemon/service
+#
+do_start()
+{
+  # Return
+  #   0 if daemon has been started
+  #   1 if daemon was already running
+  #   2 if daemon could not be started
+  start-stop-daemon --start --quiet --make-pidfile --background \
+    --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
+    || return 1
+  start-stop-daemon --start --quiet --make-pidfile --background \
+    --pidfile $PIDFILE --exec $DAEMON -- \
+    $DAEMON_ARGS || return 2
+}
+
+#
+# Function that stops the daemon/service
+#
+do_stop()
+{
+  # Return
+  #   0 if daemon has been stopped
+  #   1 if daemon was already stopped
+  #   2 if daemon could not be stopped
+  #   other if a failure occurred
+  start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
+  RETVAL="$?"
+  [ "$RETVAL" = 2 ] && return 2
+  # Wait for children to finish too if this is a daemon that forks
+  # and if the daemon is only ever run from this initscript.
+  # If the above conditions are not satisfied then add some other code
+  # that waits for the process to drop all resources that could be
+  # needed by services started subsequently.  A last resort is to
+  # sleep for some time.
+  start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 \
+    --pidfile $PIDFILE
+  [ "$?" = 2 ] && return 2
+  # Many daemons don't delete their pidfiles when they exit.
+  rm -f $PIDFILE
+  return "$RETVAL"
+}
+
+case "$1" in
+  start)
+    [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+    do_start
+    case "$?" in
+      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+    esac
+    ;;
+  stop)
+    [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+    do_stop
+    case "$?" in
+      0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+      2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+    esac
+    ;;
+  status)
+    status_of_proc -p "$PIDFILE" "$DAEMON" "$NAME" && exit 0 || exit $?
+    ;;
+  restart|force-reload)
+    log_daemon_msg "Restarting $DESC" "$NAME"
+    do_stop
+    case "$?" in
+      0|1)
+        do_start
+        case "$?" in
+          0) log_end_msg 0 ;;
+          1) log_end_msg 1 ;; # Old process is still running
+          *) log_end_msg 1 ;; # Failed to start
+        esac
+        ;;
+      *)
+        # Failed to stop
+        log_end_msg 1
+        ;;
+    esac
+    ;;
+  *)
+    echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
+    exit 3
+    ;;
+esac
+
+:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/lib/systemd/system/google-clock-sync-manager.service
 
new/google-daemon-1.2.7/usr/lib/systemd/system/google-clock-sync-manager.service
--- 
old/google-daemon-1.2.4/usr/lib/systemd/system/google-clock-sync-manager.service
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/google-daemon-1.2.7/usr/lib/systemd/system/google-clock-sync-manager.service
    2015-07-11 02:13:30.000000000 +0200
@@ -0,0 +1,11 @@
+[Unit]
+Description=Google Compute Engine Clock Sync Daemon
+After=network.target
+Requires=network.target
+
+[Service]
+Type=simple
+ExecStart=/usr/share/google/google_daemon/manage_clock_sync.py
+
+[Install]
+WantedBy=multi-user.target
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/accounts.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/accounts.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/accounts.py  
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/accounts.py  
2015-07-11 02:13:30.000000000 +0200
@@ -414,8 +414,14 @@
       if available_space < required_space:
         raise IOError('Disk is too full')
 
-    # Override the old authorized keys file with the new one.
-    self.system.MoveFile(new_keys_path, authorized_keys_file)
+    try:
+      # Override the old authorized keys file with the new one.
+      self.system.MoveFile(new_keys_path, authorized_keys_file)
+    finally:
+      try:
+        self.system.DeleteFile(new_keys_path)
+      except:
+        pass
 
     # Make sure the authorized_keys_file has the right perms (u+rw).
     self.os.chmod(authorized_keys_file, 0600)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/accounts_manager.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/accounts_manager.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/accounts_manager.py  
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/accounts_manager.py  
2015-07-11 02:13:30.000000000 +0200
@@ -50,9 +50,9 @@
     while True:
       # Fork and run the key regeneration and account update while the
       # parent waits for the subprocess to finish before continuing.
-      
+
       # Create a pipe used to get the new etag value from child
-      reader, writer = os.pipe() # these are file descriptors, not file 
objects        
+      reader, writer = os.pipe() # these are file descriptors, not file objects
       pid = os.fork()
       if pid:
         # we are the parent
@@ -117,7 +117,7 @@
         for entry in all_accounts
         if os.path.isfile(os.path.join(entry.pw_dir, keyfile_suffix))]
     extra_usernames = set(sshable_usernames) - set(desired_accounts.keys())
-    
+
     if desired_accounts:
       for username, ssh_keys in desired_accounts.iteritems():
         if not username:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/address_manager.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/address_manager.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/address_manager.py   
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/address_manager.py   
2015-07-11 02:13:30.000000000 +0200
@@ -49,6 +49,9 @@
     self.system = system_module
     self.urllib2 = urllib2_module
     self.time = time_module
+    self.ip_path = '/sbin/ip'
+    if not os.path.exists(self.ip_path):
+        self.ip_path = '/bin/ip'
 
     # etag header value is hex, so this is guaranteed to not match.
     self.default_last_etag = 'NONE'
@@ -104,8 +107,8 @@
 
   def ReadLocalConfiguredAddrs(self):
     """Fetch list of addresses we've configured on eth0 already."""
-    cmd = ('/sbin/ip route ls table local type local dev eth0 scope host ' +
-           'proto %d' % GOOGLE_PROTO_ID)
+    cmd = ('{0} route ls table local type local dev eth0 scope host ' +
+           'proto {1:d}').format(self.ip_path, GOOGLE_PROTO_ID)
     result = self.system.RunCommand(cmd.split())
     if self.IPCommandFailed(result, cmd):
       raise InputError('Can''t check local addresses')
@@ -138,8 +141,8 @@
 
   def AddOneAddress(self, addr):
     """Configure one address on eth0."""
-    cmd = '/sbin/ip route add to local %s/32 dev eth0 proto %d' % (
-        addr, GOOGLE_PROTO_ID)
+    cmd = '%s route add to local %s/32 dev eth0 proto %d' % (
+        self.ip_path, addr, GOOGLE_PROTO_ID)
     result = self.system.RunCommand(cmd.split())
     self.IPCommandFailed(result, cmd)  # Ignore return code
 
@@ -152,8 +155,8 @@
     """Delete one address from eth0."""
     # This will fail if it doesn't match exactly the specs listed.
     # That'll help ensure we don't remove one added by someone else.
-    cmd = '/sbin/ip route delete to local %s/32 dev eth0 proto %d' % (
-        addr, GOOGLE_PROTO_ID)
+    cmd = '%s route delete to local %s/32 dev eth0 proto %d' % (
+        self.ip_path, addr, GOOGLE_PROTO_ID)
     result = self.system.RunCommand(cmd.split())
     self.IPCommandFailed(result, cmd)  # Ignore return code
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/desired_accounts.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/desired_accounts.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/desired_accounts.py  
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/desired_accounts.py  
2015-07-11 02:13:30.000000000 +0200
@@ -87,7 +87,7 @@
         expire_str)
     logging.error('Not expiring key.')
     return False
-  
+
   # Expire the key if and only if we have exceeded the expiration timestamp.
   return (datetime.datetime.utcnow() > expire_time)
 
@@ -170,7 +170,7 @@
       return (attribute_value, etag)
     except urllib2.HTTPError as e:
       if e.code == 404:
-        # The attribute doesn't exist. Return None. 
+        # The attribute doesn't exist. Return None.
         # No need to log a warning.
         return None
       # rethrow the exception since we don't know what it is. Let the
@@ -231,6 +231,6 @@
         logging.debug('Project sshKeys attribute not found.')
         # sshKeys doesn't exist for either project or instance.
         account_data = None
-    
+
     self.attributes_etag = attributes_etag_cache
     return AccountDataToDictionary(account_data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/manage_accounts.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/manage_accounts.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/manage_accounts.py   
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/manage_accounts.py   
2015-07-11 02:13:30.000000000 +0200
@@ -18,6 +18,7 @@
 import logging
 import optparse
 import os
+import os.path
 import sys
 
 
@@ -40,21 +41,25 @@
 
 def Main(accounts, desired_accounts, system, logger,
          log_handler, lock_file, lock_fname=None, single_pass=True,
-         daemon_mode=False, debug_mode=False):
-  
+         daemon_mode=False, force_mode=False, debug_mode=False):
+
   if not log_handler:
     log_handler = system.MakeLoggingHandler(
         'accounts-from-metadata', logging.handlers.SysLogHandler.LOG_AUTH)
   system.SetLoggingHandler(logger, log_handler)
-  
+
   if debug_mode:
     system.EnableDebugLogging(logger)
     logging.debug('Running in Debug Mode')
 
+  if not force_mode and os.path.isfile('/usr/share/google/gcua'):
+    logging.error('Google Compute User Accounts is installed.')
+    sys.exit(1)
+
   accounts_manager = AccountsManager(
       accounts, desired_accounts, system, lock_file, lock_fname,
       single_pass)
-  
+
   if daemon_mode:
     manager_daemon = AccountsManagerDaemon(None, accounts_manager)
     manager_daemon.StartDaemon()
@@ -71,10 +76,12 @@
   parser.add_option('--interval', type='int', dest='interval')
   parser.add_option('--single-pass', dest='single_pass', action='store_true')
   parser.add_option('--no-single-pass', dest='single_pass', 
action='store_false')
+  parser.add_option('--force', dest='force', action='store_true')
   parser.add_option('--debug', dest='debug', action='store_true')
   parser.set_defaults(interval=60)
   parser.set_defaults(single_pass=False)
   parser.set_defaults(daemon=False)
+  parser.set_defaults(force=False)
   parser.set_defaults(debug=False)
   (options, args) = parser.parse_args()
 
@@ -84,4 +91,4 @@
 
   Main(Accounts(system_module=System()), DesiredAccounts(),
        System(), logging.getLogger(), None, LockFile(), None, 
options.single_pass,
-       options.daemon, options.debug)
+       options.daemon, options.force, options.debug)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/manage_clock_sync.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/manage_clock_sync.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/manage_clock_sync.py 
1970-01-01 01:00:00.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/manage_clock_sync.py 
2015-07-11 02:13:30.000000000 +0200
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+# Copyright 2015 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Manages clock syncing after migration on GCE instances."""
+
+import logging
+import os
+import sys
+
+def FixPath():
+  parent_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
+  if os.path.isdir(parent_dir):
+    sys.path.append(parent_dir)
+
+
+FixPath()
+
+from utils import LockFile
+from utils import System
+from metadata_watcher import MetadataWatcher
+
+
+LOCKFILE = '/var/lock/google-clock-sync.lock'
+
+
+def HandleClockDriftToken(metadata_watcher, on_change):
+  """Watches for and responds to drift-token changes.
+
+  Args:
+    metadata_watcher: a MetadataWatcher object.
+    on_change: a callable to call for any change.
+  """
+  clock_drift_token_key = 'instance/virtual-clock/drift-token'
+
+  def Handler(event):
+    on_change(event)
+
+  metadata_watcher.WatchMetadataForever(clock_drift_token_key,
+                                        Handler, initial_value='')
+
+
+def OnChange(event):
+  """Called when clock drift token changes.
+
+  Args:
+    event: the new value of the drift token.
+  """
+  system = System()
+  logging.info('Clock drift token has changed: %s', event)
+  logging.info('Syncing system time with hardware clock...')
+  result = system.RunCommand(['/sbin/hwclock', '--hctosys'])
+  if system.RunCommandFailed(result):
+    logging.error('Syncing system time failed.')
+  else:
+    logging.info('Synced system time with hardware clock.')
+
+
+def Main(system=System(), logger=logging.getLogger(), log_handler=None,
+         lock_file=LockFile(), lock_fname=None):
+  if not log_handler:
+    log_handler = system.MakeLoggingHandler(
+        'google-clock-sync', logging.handlers.SysLogHandler.LOG_SYSLOG)
+    system.SetLoggingHandler(logger, log_handler)
+    logging.info('Starting GCE clock sync')
+
+  if not lock_fname:
+    lock_fname = LOCKFILE
+  watcher = MetadataWatcher()
+  lock_file.RunExclusively(lock_fname, HandleClockDriftToken(watcher, 
OnChange))
+
+
+if __name__ == '__main__':
+  Main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/metadata_watcher.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/metadata_watcher.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/metadata_watcher.py  
1970-01-01 01:00:00.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/metadata_watcher.py  
2015-07-11 02:13:30.000000000 +0200
@@ -0,0 +1,97 @@
+#!/usr/bin/python
+# Copyright 2015 Google Inc. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import httplib
+import time
+import urllib
+import urllib2
+
+
+METADATA_URL = 'http://metadata.google.internal/computeMetadata/v1/'
+
+
+class Error(Exception):
+  pass
+
+
+class UnexpectedStatusException(Error):
+  pass
+
+
+class MetadataWatcher(object):
+  """Watches for changing metadata."""
+
+  def __init__(self, httplib_module=httplib, time_module=time,
+               urllib_module=urllib, urllib2_module=urllib2):
+    self.httplib = httplib_module
+    self.time = time_module
+    self.urllib = urllib_module
+    self.urllib2 = urllib2_module
+
+  def WatchMetadataForever(self, metadata_key, handler, initial_value=None):
+    """Watches for a change in the value of metadata.
+
+    Args:
+      metadata_key: The key identifying which metadata to watch for changes.
+      handler: A callable to call when the metadata value changes. Will be 
passed
+        a single parameter, the new value of the metadata.
+      initial_value: The expected initial value for the metadata. The handler 
will
+        not be called on the initial metadata request unless the value differs
+        from this.
+
+    Raises:
+      UnexpectedStatusException: If the http request is unsuccessful for an
+        unexpected reason.
+    """
+    params = {
+        'wait_for_change': 'true',
+        'last_etag': 0,
+        }
+
+    value = initial_value
+    while True:
+      # start a hanging-GET request for metadata key.
+      url = '{base_url}{key}?{params}'.format(
+          base_url=METADATA_URL,
+          key=metadata_key,
+          params=self.urllib.urlencode(params)
+          )
+      req = self.urllib2.Request(url, headers={'Metadata-Flavor': 'Google'})
+
+      try:
+        response = self.urllib2.urlopen(req)
+        content = response.read()
+        status = response.getcode()
+      except self.urllib2.HTTPError as e:
+        content = None
+        status = e.code
+
+      if status == self.httplib.SERVICE_UNAVAILABLE:
+        self.time.sleep(1)
+        continue
+      elif status == self.httplib.OK:
+        # Extract new metadata value and latest etag.
+        new_value = content
+        headers = response.info()
+        params['last_etag'] = headers['ETag']
+      else:
+        raise UnexpectedStatusException(status)
+
+      # If the metadata value changed, call the appropriate handler.
+      if value == initial_value:
+        value = new_value
+      elif value != new_value:
+        value = new_value
+        handler(value)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/google-daemon-1.2.4/usr/share/google/google_daemon/utils.py 
new/google-daemon-1.2.7/usr/share/google/google_daemon/utils.py
--- old/google-daemon-1.2.4/usr/share/google/google_daemon/utils.py     
2015-03-10 02:28:44.000000000 +0100
+++ new/google-daemon-1.2.7/usr/share/google/google_daemon/utils.py     
2015-07-11 02:13:30.000000000 +0200
@@ -66,6 +66,9 @@
   def CreateTempFile(self, delete=True):
     return tempfile.NamedTemporaryFile(delete=delete)
 
+  def DeleteFile(self, name):
+    return os.remove(name)
+
   def UserAdd(self, user, groups):
     logging.info('Creating account %s', user)
 


Reply via email to