Revert "[autotest] Send labels to shards preserving their ids."

This reverts commit 744898f7e2fe4a3d90659d2183119b0d1fddcb28.

Change-Id: I8c8611b1b3095223e527fb465c2030e743ab6152
Reviewed-on: https://chromium-review.googlesource.com/246274
Reviewed-by: Mungyung Ryu <mkryu@google.com>
Commit-Queue: Mungyung Ryu <mkryu@google.com>
Tested-by: Mungyung Ryu <mkryu@google.com>
diff --git a/frontend/afe/rpc_interface.py b/frontend/afe/rpc_interface.py
index 1dbaf38..7a058db 100644
--- a/frontend/afe/rpc_interface.py
+++ b/frontend/afe/rpc_interface.py
@@ -59,6 +59,12 @@
 
 # labels
 
+def add_label(name, kernel_config=None, platform=None, only_if_needed=None):
+    return models.Label.add_object(
+            name=name, kernel_config=kernel_config, platform=platform,
+            only_if_needed=only_if_needed).id
+
+
 def modify_label(id, **data):
     models.Label.smart_get(id).update_object(data)
 
@@ -66,71 +72,23 @@
 def delete_label(id):
     models.Label.smart_get(id).delete()
 
-
-def add_label(name, ignore_exception_if_exists=False, **kwargs):
-    """Add a new label with a given name.
-
-    @param name: label name.
-    @param ignore_exception_if_exists: If True and the exception was
-        thrown due to the duplicated label name when adding a label,
-        then suppress the exception. Default is False.
-    @param kwargs: keyword args that store more info about a label
-        other than the name.
-    @return: int/long id of a new label.
-    """
-    # models.Label.add_object() throws model_logic.ValidationError
-    # when it is given a label name that already exists.
-    # However, ValidationError can be thrown with different errors,
-    # and those errors should be thrown up to the call chain.
-    try:
-        label = models.Label.add_object(name=name, **kwargs)
-    except:
-        if ignore_exception_if_exists:
-            label = rpc_utils.get_label(name)
-            # If the exception is raised not because of duplicated
-            # "name", then raise the original exception.
-            if label is None:
-                raise
-        else:
-            raise
-    return label.id
-
-
-def add_label_to_hosts(id, hosts):
-    """Add a label with the given id to the given hosts only in local DB.
-
-    @param id: id or name of a label. More often a label name.
-    @param hosts: The hostnames of hosts that need the label.
-
-    @raises models.Label.DoesNotExist: If the label with id doesn't exist.
-    """
-    label = models.Label.smart_get(id)
-    host_objs = models.Host.smart_get_bulk(hosts)
-    if label.platform:
-        models.Host.check_no_platform(host_objs)
-    label.host_set.add(*host_objs)
-
-
+@rpc_utils.forward_multi_host_rpc_to_shards
 def label_add_hosts(id, hosts):
-    """Add a label with the given id to the given hosts.
+    """Add the label with the given id to the list of hosts.
 
-    This method should be run only on master not shards.
     The given label will be created if it doesn't exist, provided the `id`
     supplied is a label name not an int/long id.
 
-    @param id: id or name of a label. More often a label name.
+    @param id: An id or label name. More often a label name.
     @param hosts: A list of hostnames or ids. More often hostnames.
 
-    @raises Exception: If this RPC is called other than master.
-    @raises ValueError: If the id specified is an int/long (label id)
-                        while the label does not exist.
+    @raises models.Label.DoesNotExist: If the id specified is an int/long
+        and a label with that id doesn't exist.
     """
-    # This RPC call should be accepted only by master.
-    if utils.is_shard():
-        raise Exception('RPC label_add_hosts should be called only on matser')
-
     host_objs = models.Host.smart_get_bulk(hosts)
     try:
+        # In the rare event that we're given an id and not a label name,
+        # it should already exist.
         label = models.Label.smart_get(id)
     except models.Label.DoesNotExist:
         # This matches the type checks in smart_get, which is a hack
@@ -139,18 +97,11 @@
         if isinstance(id, basestring):
             label = models.Label.smart_get(add_label(id))
         else:
-            raise ValueError('Label id (%s) does not exist. Please specify '
-                             'the argument, id, as a string (label name).'
-                             % id)
-    add_label_to_hosts(id, hosts)
-    # Make sure the label exists on the shard with the same id
-    # as it is on the master.
-    # It is possible that the label is already in a shard.
-    # We ignore exception in such a case.
-    rpc_utils.fanout_rpc(
-            host_objs, 'add_label', name=label.name, id=label.id,
-            include_hostnames=False, ignore_exception_if_exists=True)
-    rpc_utils.fanout_rpc(host_objs, 'add_label_to_hosts', id=id)
+            raise
+
+    if label.platform:
+        models.Host.check_no_platform(host_objs)
+    label.host_set.add(*host_objs)
 
 
 @rpc_utils.forward_multi_host_rpc_to_shards
diff --git a/frontend/afe/rpc_utils.py b/frontend/afe/rpc_utils.py
index 3a41ca6..02f425f 100644
--- a/frontend/afe/rpc_utils.py
+++ b/frontend/afe/rpc_utils.py
@@ -1077,32 +1077,6 @@
     return replacement
 
 
-def fanout_rpc(host_objs, rpc_name, include_hostnames=True, **kwargs):
-    """Fanout the give rpc to all shards.
-
-    @param host_objs: Host objects for the rpc.
-    @param rpc_name: The name of the rpc.
-    @param include_hostnames: If True, include the hostnames in the kwargs.
-        Hostnames are not always necessary, this functions is designed to
-        send rpcs to the shard a host is on, the rpcs themselves could be
-        related to labels, acls etc.
-    @param kwargs: The kwargs for the rpc.
-    """
-    # Fanout should only happen from the master to the shards.
-    if server_utils.is_shard():
-        return
-
-    # Figure out which hosts are on which shards.
-    shard_host_map = bucket_hosts_by_shard(
-            host_objs, rpc_hostnames=True)
-
-    # Execute the rpc against the appropriate shards.
-    for shard, hostnames in shard_host_map.iteritems():
-        if include_hostnames:
-            kwargs['hosts'] = hostnames
-        run_rpc_on_multiple_hostnames(rpc_name, [shard], **kwargs)
-
-
 def forward_multi_host_rpc_to_shards(func):
     """This decorator forwards rpc calls that modify multiple hosts.
 
@@ -1125,9 +1099,18 @@
     @returns: The function to replace func with.
     """
     def replacement(**kwargs):
-        fanout_rpc(
-                models.Host.smart_get_bulk(kwargs['hosts']),
-                func.func_name, **kwargs)
+        if not server_utils.is_shard():
+
+            # Figure out which hosts are on which shards.
+            shard_host_map = bucket_hosts_by_shard(
+                    models.Host.smart_get_bulk(kwargs['hosts']),
+                    rpc_hostnames=True)
+
+            # Execute the rpc against the appropriate shards.
+            for shard, hostnames in shard_host_map.iteritems():
+                kwargs['hosts'] = hostnames
+                run_rpc_on_multiple_hostnames(func.func_name, [shard],
+                                              **kwargs)
         return func(**kwargs)
 
     return replacement
@@ -1146,18 +1129,3 @@
     for shard_hostname in shard_hostnames:
         afe = frontend.AFE(server=shard_hostname)
         afe.run(rpc_call, **kwargs)
-
-
-def get_label(name):
-    """Gets a label object using a given name.
-
-    @param name: Label name.
-    @raises model.Label.DoesNotExist: when there is no label matching
-                                      the given name.
-    @return: a label object matching the given name.
-    """
-    try:
-        label = models.Label.smart_get(name)
-    except models.Label.DoesNotExist:
-        return None
-    return label