diff --git a/lib/backend.py b/lib/backend.py
index 0c023c5f505f8acda7cc1ad570e99c0e2b870442..ab013366d7e01f0ec752aaea2fa205d5874283d7 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -1,7 +1,7 @@
 #
 #
 
-# Copyright (C) 2006, 2007, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -1945,9 +1945,11 @@ def OSFromDisk(name, base_dir=None):
   return payload
 
 
-def OSCoreEnv(inst_os, os_params, debug=0):
+def OSCoreEnv(os_name, inst_os, os_params, debug=0):
   """Calculate the basic environment for an os script.
 
+  @type os_name: str
+  @param os_name: full operating system name (including variant)
   @type inst_os: L{objects.OS}
   @param inst_os: operating system for which the environment is being built
   @type os_params: dict
@@ -1970,7 +1972,7 @@ def OSCoreEnv(inst_os, os_params, debug=0):
   # OS variants
   if api_version >= constants.OS_API_V15:
     try:
-      variant = inst_os.name.split('+', 1)[1]
+      variant = os_name.split('+', 1)[1]
     except IndexError:
       variant = inst_os.supported_variants[0]
     result['OS_VARIANT'] = variant
@@ -1997,7 +1999,7 @@ def OSEnvironment(instance, inst_os, debug=0):
       cannot be found
 
   """
-  result = OSCoreEnv(inst_os, instance.osparams, debug=debug)
+  result = OSCoreEnv(instance.os, inst_os, instance.osparams, debug=debug)
 
   result['INSTANCE_NAME'] = instance.name
   result['INSTANCE_OS'] = instance.os
@@ -2536,7 +2538,7 @@ def ValidateOS(required, osname, checks, osparams):
   if constants.OS_VALIDATE_PARAMETERS in checks:
     _CheckOSPList(tbv, osparams.keys())
 
-  validate_env = OSCoreEnv(tbv, osparams)
+  validate_env = OSCoreEnv(osname, tbv, osparams)
   result = utils.RunCmd([tbv.verify_script] + checks, env=validate_env,
                         cwd=tbv.path)
   if result.failed:
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 91957b799633f7a0eaf5088b0efe314c73902db8..7fab9043745e3159660d51ff704e90afa30f7046 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -9739,7 +9739,8 @@ class LUGetTags(TagsLU):
   """
   _OP_PARAMS = [
     ("kind", _NoDefault, _TElemOf(constants.VALID_TAG_TYPES)),
-    ("name", _NoDefault, _TNonEmptyString),
+    # Name is only meaningful for nodes and instances
+    ("name", _NoDefault, _TMaybeString),
     ]
   REQ_BGL = False
 
@@ -9798,7 +9799,8 @@ class LUAddTags(TagsLU):
   """
   _OP_PARAMS = [
     ("kind", _NoDefault, _TElemOf(constants.VALID_TAG_TYPES)),
-    ("name", _NoDefault, _TNonEmptyString),
+    # Name is only meaningful for nodes and instances
+    ("name", _NoDefault, _TMaybeString),
     ("tags", _NoDefault, _TListOf(_TNonEmptyString)),
     ]
   REQ_BGL = False
@@ -9831,7 +9833,8 @@ class LUDelTags(TagsLU):
   """
   _OP_PARAMS = [
     ("kind", _NoDefault, _TElemOf(constants.VALID_TAG_TYPES)),
-    ("name", _NoDefault, _TNonEmptyString),
+    # Name is only meaningful for nodes and instances
+    ("name", _NoDefault, _TMaybeString),
     ("tags", _NoDefault, _TListOf(_TNonEmptyString)),
     ]
   REQ_BGL = False
diff --git a/lib/opcodes.py b/lib/opcodes.py
index 043f8288c1b13471bcfd9b35ce00f68ade4283ed..7a2ccf80c6f5b61592f7cfc4a6d387cb17f5f92a 100644
--- a/lib/opcodes.py
+++ b/lib/opcodes.py
@@ -176,6 +176,8 @@ class OpCode(BaseOpCode):
     field_name = getattr(self, "OP_DSC_FIELD", None)
     if field_name:
       field_value = getattr(self, field_name, None)
+      if isinstance(field_value, (list, tuple)):
+        field_value = ",".join(str(i) for i in field_value)
       txt = "%s(%s)" % (txt, field_value)
     return txt
 
diff --git a/lib/rapi/rlib2.py b/lib/rapi/rlib2.py
index b7e9b9bf453bc6b7bead5624c83cf7f2a9dc31a1..eed96400e1795af56774b913048a6b5ca355214a 100644
--- a/lib/rapi/rlib2.py
+++ b/lib/rapi/rlib2.py
@@ -1122,10 +1122,10 @@ class _R_Tags(baserlib.R_Generic):
     """
     baserlib.R_Generic.__init__(self, items, queryargs, req)
 
-    if self.TAG_LEVEL != constants.TAG_CLUSTER:
-      self.name = items[0]
+    if self.TAG_LEVEL == constants.TAG_CLUSTER:
+      self.name = None
     else:
-      self.name = ""
+      self.name = items[0]
 
   def GET(self):
     """Returns a list of tags.
diff --git a/qa/qa_rapi.py b/qa/qa_rapi.py
index 16a7a926a4b95a42435c5e7859be6ae228287a99..7e87ad2d113d1dcdd96ce7e391df03cec387d6e6 100644
--- a/qa/qa_rapi.py
+++ b/qa/qa_rapi.py
@@ -116,6 +116,7 @@ def _DoTests(uris):
   for uri, verify, method, body in uris:
     assert uri.startswith("/")
 
+    print "%s %s" % (method, uri)
     data = _rapi_client._SendRequest(method, uri, None, body)
 
     if verify is not None:
@@ -124,7 +125,7 @@ def _DoTests(uris):
       else:
         AssertEqual(data, verify)
 
-      results.append(data)
+    results.append(data)
 
   return results
 
@@ -259,10 +260,25 @@ def TestTags(kind, name, tags):
   def _VerifyTags(data):
     AssertEqual(sorted(tags), sorted(data))
 
+  query = "&".join("tag=%s" % i for i in tags)
+
+  # Add tags
+  (job_id, ) = _DoTests([
+    ("%s?%s" % (uri, query), _VerifyReturnsJob, "PUT", None),
+    ])
+  _WaitForRapiJob(job_id)
+
+  # Retrieve tags
   _DoTests([
     (uri, _VerifyTags, 'GET', None),
     ])
 
+  # Remove tags
+  (job_id, ) = _DoTests([
+    ("%s?%s" % (uri, query), _VerifyReturnsJob, "DELETE", None),
+    ])
+  _WaitForRapiJob(job_id)
+
 
 def _WaitForRapiJob(job_id):
   """Waits for a job to finish.
diff --git a/qa/qa_tags.py b/qa/qa_tags.py
index ae19f2e31539d7488b57f6b034c71e3ecbad1f47..d438ab9ac613bc6d11443cf7b00f6d5c83ff11b1 100644
--- a/qa/qa_tags.py
+++ b/qa/qa_tags.py
@@ -66,13 +66,13 @@ def _TestTags(kind, name):
   AssertEqual(StartSSH(master['primary'],
                        utils.ShellQuoteArgs(cmd)).wait(), 0)
 
-  if qa_rapi.Enabled():
-    qa_rapi.TestTags(kind, name, _TEMP_TAG_NAMES)
-
   cmd = cmdfn('remove-tags') + _TEMP_TAG_NAMES
   AssertEqual(StartSSH(master['primary'],
                        utils.ShellQuoteArgs(cmd)).wait(), 0)
 
+  if qa_rapi.Enabled():
+    qa_rapi.TestTags(kind, name, _TEMP_TAG_NAMES)
+
 
 def TestClusterTags():
   """gnt-cluster tags"""