Merge release branch 4.18 to main

* 4.18:
  server: remove registered userdata when cleanup an account (#7777)
  server: Use max secondary storage defined on the account during upload  (#7441)
  test: upgrade kubernetes versions to 1.25.0/1.26.0 (#7685)
  kvm: Added VNI Devices as normal bridge slave devs (#7836)
  noVNC: fix JP keyboard on vmware7+ which uses websocket URL (#7694)
diff --git a/api/src/main/java/com/cloud/user/ResourceLimitService.java b/api/src/main/java/com/cloud/user/ResourceLimitService.java
index 41b2c81..f2d87a4 100644
--- a/api/src/main/java/com/cloud/user/ResourceLimitService.java
+++ b/api/src/main/java/com/cloud/user/ResourceLimitService.java
@@ -118,6 +118,15 @@
     public long findDefaultResourceLimitForDomain(ResourceType resourceType);
 
     /**
+     * Finds the resource limit for a specified account, domain and type.
+     *
+     * @param domain
+     * @param type
+     * @return resource limit
+     */
+    public long findCorrectResourceLimitForAccountAndDomain(Account account, Domain domain, ResourceType type);
+
+    /**
      * Increments the resource count
      *
      * @param accountId
diff --git a/engine/schema/src/main/java/com/cloud/user/dao/UserDataDao.java b/engine/schema/src/main/java/com/cloud/user/dao/UserDataDao.java
index f012d41..2733d8d 100644
--- a/engine/schema/src/main/java/com/cloud/user/dao/UserDataDao.java
+++ b/engine/schema/src/main/java/com/cloud/user/dao/UserDataDao.java
@@ -25,4 +25,6 @@
 
     public UserDataVO findByName(long accountId, long domainId, String name);
 
+    int removeByAccountId(long accountId);
+
 }
diff --git a/engine/schema/src/main/java/com/cloud/user/dao/UserDataDaoImpl.java b/engine/schema/src/main/java/com/cloud/user/dao/UserDataDaoImpl.java
index 416c441..ded0cd1 100644
--- a/engine/schema/src/main/java/com/cloud/user/dao/UserDataDaoImpl.java
+++ b/engine/schema/src/main/java/com/cloud/user/dao/UserDataDaoImpl.java
@@ -63,4 +63,11 @@
 
         return findOneBy(sc);
     }
+
+    @Override
+    public int removeByAccountId(long accountId) {
+        SearchCriteria<UserDataVO> sc = userdataSearch.create();
+        sc.setParameters("accountId", accountId);
+        return remove(sc);
+    }
 }
diff --git a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 3411ad4..b1004f0 100644
--- a/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1713,7 +1713,8 @@
             "^enx",
             "^dummy",
             "^lo",
-            "^p\\d+p\\d+"
+            "^p\\d+p\\d+",
+            "^vni"
     };
 
     /**
diff --git a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
index 51b1635..37c135d 100644
--- a/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
+++ b/server/src/main/java/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
@@ -548,6 +548,18 @@
     }
 
     @Override
+    public long findCorrectResourceLimitForAccountAndDomain(Account account, Domain domain, ResourceType type) {
+        long maxSecondaryStorageForAccount = findCorrectResourceLimitForAccount(account, type);
+        long maxSecondaryStorageForDomain = findCorrectResourceLimitForDomain(domain, type);
+
+        if (maxSecondaryStorageForDomain == Resource.RESOURCE_UNLIMITED || maxSecondaryStorageForAccount == Resource.RESOURCE_UNLIMITED) {
+            return Math.max(maxSecondaryStorageForDomain, maxSecondaryStorageForAccount);
+        }
+
+        return Math.min(maxSecondaryStorageForDomain, maxSecondaryStorageForAccount);
+    }
+
+    @Override
     @DB
     public void checkResourceLimit(final Account account, final ResourceType type, long... count) throws ResourceAllocationException {
         final long numResources = ((count.length == 0) ? 1 : count[0]);
diff --git a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
index d0eaebb..814bb48 100644
--- a/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
+++ b/server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
@@ -34,6 +34,7 @@
 
 import javax.inject.Inject;
 
+import com.cloud.domain.dao.DomainDao;
 import org.apache.cloudstack.api.ApiConstants.IoDriverPolicy;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.InternalIdentity;
@@ -332,6 +333,9 @@
     protected SnapshotHelper snapshotHelper;
 
     @Inject
+    protected DomainDao domainDao;
+
+    @Inject
     protected ProjectManager projectManager;
     @Inject
     protected StoragePoolDetailsDao storagePoolDetailsDao;
@@ -486,13 +490,13 @@
                 //using the existing max upload size configuration
                 command.setProcessTimeout(NumbersUtil.parseLong(_configDao.getValue("vmware.package.ova.timeout"), 3600));
                 command.setMaxUploadSize(_configDao.getValue(Config.MaxUploadVolumeSize.key()));
-                command.setAccountId(vol.getAccountId());
-                Account account = _accountDao.findById(vol.getAccountId());
-                if (account.getType().equals(Account.Type.PROJECT)) {
-                    command.setDefaultMaxSecondaryStorageInGB(ResourceLimitService.MaxProjectSecondaryStorage.value());
-                } else {
-                    command.setDefaultMaxSecondaryStorageInGB(ResourceLimitService.MaxAccountSecondaryStorage.value());
-                }
+
+                long accountId = vol.getAccountId();
+                Account account = _accountDao.findById(accountId);
+                Domain domain = domainDao.findById(account.getDomainId());
+
+                command.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage));
+                command.setAccountId(accountId);
                 Gson gson = new GsonBuilder().create();
                 String metadata = EncryptionUtil.encodeData(gson.toJson(command), key);
                 response.setMetadata(metadata);
diff --git a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
index 2204e5a..f5c19ec 100644
--- a/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/main/java/com/cloud/template/HypervisorTemplateAdapter.java
@@ -28,6 +28,7 @@
 
 import javax.inject.Inject;
 
+import com.cloud.domain.Domain;
 import org.apache.cloudstack.agent.directdownload.CheckUrlAnswer;
 import org.apache.cloudstack.agent.directdownload.CheckUrlCommand;
 import org.apache.cloudstack.annotation.AnnotationService;
@@ -93,7 +94,6 @@
 import com.cloud.storage.download.DownloadMonitor;
 import com.cloud.template.VirtualMachineTemplate.State;
 import com.cloud.user.Account;
-import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.Pair;
 import com.cloud.utils.UriUtils;
 import com.cloud.utils.db.DB;
@@ -402,13 +402,13 @@
                             templateOnStore.getDataStore().getRole().toString());
                     //using the existing max template size configuration
                     payload.setMaxUploadSize(_configDao.getValue(Config.MaxTemplateAndIsoSize.key()));
-                    payload.setAccountId(template.getAccountId());
-                    Account account = _accountDao.findById(template.getAccountId());
-                    if (account.getType().equals(Account.Type.PROJECT)) {
-                        payload.setDefaultMaxSecondaryStorageInGB(ResourceLimitService.MaxProjectSecondaryStorage.value());
-                    } else {
-                        payload.setDefaultMaxSecondaryStorageInGB(ResourceLimitService.MaxAccountSecondaryStorage.value());
-                    }
+
+                    Long accountId = template.getAccountId();
+                    Account account = _accountDao.findById(accountId);
+                    Domain domain = _domainDao.findById(account.getDomainId());
+
+                    payload.setDefaultMaxSecondaryStorageInGB(_resourceLimitMgr.findCorrectResourceLimitForAccountAndDomain(account, domain, ResourceType.secondary_storage));
+                    payload.setAccountId(accountId);
                     payload.setRemoteEndPoint(ep.getPublicAddr());
                     payload.setRequiresHvm(template.requiresHvm());
                     payload.setDescription(template.getDisplayText());
diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
index 38b2edd..c20e2fc 100644
--- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java
+++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java
@@ -162,6 +162,7 @@
 import com.cloud.user.dao.SSHKeyPairDao;
 import com.cloud.user.dao.UserAccountDao;
 import com.cloud.user.dao.UserDao;
+import com.cloud.user.dao.UserDataDao;
 import com.cloud.utils.ConstantTimeComparator;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
@@ -292,6 +293,8 @@
     private GlobalLoadBalancerRuleDao _gslbRuleDao;
     @Inject
     private SSHKeyPairDao _sshKeyPairDao;
+    @Inject
+    private UserDataDao userDataDao;
 
     private List<QuerySelector> _querySelectors;
 
@@ -1089,6 +1092,10 @@
             for (SSHKeyPairVO keypair : sshkeypairs) {
                 _sshKeyPairDao.remove(keypair.getId());
             }
+
+            // Delete registered UserData
+            userDataDao.removeByAccountId(accountId);
+
             return true;
         } catch (Exception ex) {
             s_logger.warn("Failed to cleanup account " + account + " due to ", ex);
diff --git a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
index 31a7a8d..27fd258 100644
--- a/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
+++ b/server/src/main/java/org/apache/cloudstack/consoleproxy/ConsoleAccessManagerImpl.java
@@ -385,7 +385,7 @@
         String token = encryptor.encryptObject(ConsoleProxyClientParam.class, param);
         int vncPort = consoleProxyManager.getVncPort();
 
-        String url = generateConsoleAccessUrl(rootUrl, param, token, vncPort, vm);
+        String url = generateConsoleAccessUrl(rootUrl, param, token, vncPort, vm, hostVo, details);
 
         s_logger.debug("Adding allowed session: " + sessionUuid);
         persistConsoleSession(sessionUuid, vm.getId(), hostVo.getId());
@@ -413,7 +413,7 @@
     }
 
     private String generateConsoleAccessUrl(String rootUrl, ConsoleProxyClientParam param, String token, int vncPort,
-                                            VirtualMachine vm) {
+                                            VirtualMachine vm, HostVO hostVo, UserVmDetailVO details) {
         StringBuilder sb = new StringBuilder(rootUrl);
         if (param.getHypervHost() != null || !ConsoleProxyManager.NoVncConsoleDefault.value()) {
             sb.append("/ajax?token=" + token);
@@ -422,6 +422,9 @@
                     .append("?autoconnect=true")
                     .append("&port=" + vncPort)
                     .append("&token=" + token);
+            if (requiresVncOverWebSocketConnection(vm, hostVo) && details != null && details.getValue() != null) {
+                sb.append("&language=" + details.getValue());
+            }
         }
 
         if (StringUtils.isNotBlank(param.getExtraSecurityToken())) {
diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
index 7112713..c79b506 100644
--- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
+++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java
@@ -164,6 +164,7 @@
         sshkeyList.add(sshkey);
         Mockito.when(_sshKeyPairDao.listKeyPairs(Mockito.anyLong(), Mockito.anyLong())).thenReturn(sshkeyList);
         Mockito.when(_sshKeyPairDao.remove(Mockito.anyLong())).thenReturn(true);
+        Mockito.when(userDataDao.removeByAccountId(Mockito.anyLong())).thenReturn(222);
 
         Assert.assertTrue(accountManagerImpl.deleteUserAccount(42l));
         // assert that this was a clean delete
diff --git a/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java b/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java
index 7648ec1..7bc14a4 100644
--- a/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java
+++ b/server/src/test/java/com/cloud/user/AccountManagetImplTestBase.java
@@ -73,6 +73,7 @@
 import com.cloud.user.dao.SSHKeyPairDao;
 import com.cloud.user.dao.UserAccountDao;
 import com.cloud.user.dao.UserDao;
+import com.cloud.user.dao.UserDataDao;
 import com.cloud.vm.VirtualMachineManager;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.InstanceGroupDao;
@@ -193,6 +194,8 @@
     OrchestrationService _orchSrvc;
     @Mock
     SSHKeyPairDao _sshKeyPairDao;
+    @Mock
+    UserDataDao userDataDao;
 
     @Spy
     @InjectMocks
diff --git a/server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java
index 1d1da53..9b091de 100644
--- a/server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java
+++ b/server/src/test/java/com/cloud/vpc/MockResourceLimitManagerImpl.java
@@ -93,6 +93,11 @@
         return 0;
     }
 
+    @Override
+    public long findCorrectResourceLimitForAccountAndDomain(Account account, Domain domain, ResourceType type) {
+        return 0;
+    }
+
     /* (non-Javadoc)
      * @see com.cloud.user.ResourceLimitService#incrementResourceCount(long, com.cloud.configuration.Resource.ResourceType, java.lang.Long[])
      */
diff --git a/systemvm/agent/noVNC/app/ui.js b/systemvm/agent/noVNC/app/ui.js
index ee738c2..c85d9c2 100644
--- a/systemvm/agent/noVNC/app/ui.js
+++ b/systemvm/agent/noVNC/app/ui.js
@@ -1077,6 +1077,7 @@
         UI.rfb = new RFB(document.getElementById('noVNC_container'), url,
                          { shared: UI.getSetting('shared'),
                            repeaterID: UI.getSetting('repeaterID'),
+                           language: WebUtil.getConfigVar('language'),
                            credentials: { password: password } });
         UI.rfb.addEventListener("connect", UI.connectFinished);
         UI.rfb.addEventListener("disconnect", UI.disconnectFinished);
diff --git a/systemvm/agent/noVNC/core/rfb.js b/systemvm/agent/noVNC/core/rfb.js
index b795aaa..a8d63ff 100644
--- a/systemvm/agent/noVNC/core/rfb.js
+++ b/systemvm/agent/noVNC/core/rfb.js
@@ -37,6 +37,7 @@
 import TightPNGDecoder from "./decoders/tightpng.js";
 import ZRLEDecoder from "./decoders/zrle.js";
 import JPEGDecoder from "./decoders/jpeg.js";
+import SCANCODES_JP from "../keymaps/keymap-ja-atset1.js"
 
 // How many seconds to wait for a disconnect to finish
 const DISCONNECT_TIMEOUT = 3;
@@ -118,8 +119,15 @@
         this._rfbCredentials = options.credentials || {};
         this._shared = 'shared' in options ? !!options.shared : true;
         this._repeaterID = options.repeaterID || '';
+        this._language = options.language || '';
         this._wsProtocols = ['binary'];
 
+        // Keymaps
+        this._scancodes = {};
+        if (this._language === "jp") {
+            this._scancodes = SCANCODES_JP;
+        }
+
         // Internal state
         this._rfbConnectionState = '';
         this._rfbInitState = '';
@@ -181,6 +189,10 @@
             encoding: null,
         };
 
+        // Keys
+        this._shiftPressed = false;
+        this._shiftKey = KeyTable.XK_Shift_L;
+
         // Mouse state
         this._mousePos = {};
         this._mouseButtonMask = 0;
@@ -506,6 +518,11 @@
 
         const scancode = XtScancode[code];
 
+        if (keysym === KeyTable.XK_Shift_L || keysym === KeyTable.XK_Shift_R) {
+            this._shiftPressed = down;
+            this._shiftKey = down ? keysym : KeyTable.XK_Shift_L;
+        }
+
         if (this._qemuExtKeyEventSupported && scancode) {
             // 0 is NoSymbol
             keysym = keysym || 0;
@@ -513,6 +530,31 @@
             Log.Info("Sending key (" + (down ? "down" : "up") + "): keysym " + keysym + ", scancode " + scancode);
 
             RFB.messages.QEMUExtendedKeyEvent(this._sock, keysym, down, scancode);
+        } else if (Object.keys(this._scancodes).length > 0) {
+            let vscancode = this._scancodes[keysym]
+            if (vscancode) {
+                let shifted = vscancode.includes("shift");
+                let vscancode_int = parseInt(vscancode);
+                let isLetter = (keysym >= 65 && keysym <=90) || (keysym >=97 && keysym <=122);
+                if (shifted && ! this._shiftPressed && ! isLetter) {
+                    RFB.messages.keyEvent(this._sock, this._shiftKey, 1);
+                }
+                if (! shifted && this._shiftPressed && ! isLetter) {
+                    RFB.messages.keyEvent(this._sock, this._shiftKey, 0);
+                }
+                RFB.messages.VMwareExtendedKeyEvent(this._sock, keysym, down, vscancode_int);
+                if (shifted && ! this._shiftPressed && ! isLetter) {
+                    RFB.messages.keyEvent(this._sock, this._shiftKey, 0);
+                }
+                if (! shifted && this._shiftPressed && ! isLetter) {
+                    RFB.messages.keyEvent(this._sock, this._shiftKey, 1);
+                }
+            } else {
+                if (this._language === "jp" && keysym === 65328) {
+                    keysym = 65509; // Caps lock
+                }
+                RFB.messages.keyEvent(this._sock, keysym, down ? 1 : 0);
+            }
         } else {
             if (!keysym) {
                 return;
@@ -3031,6 +3073,26 @@
         sock.flush();
     },
 
+    VMwareExtendedKeyEvent(sock, keysym, down, keycode) {
+        const buff = sock._sQ;
+        const offset = sock._sQlen;
+
+        buff[offset] = 127;     // msgVMWClientMessage
+        buff[offset + 1] = 0;   // msgVMWKeyEvent
+
+        buff[offset + 2] = 0;
+        buff[offset + 3] = 8;
+
+        buff[offset + 4] = (keycode >> 8);
+        buff[offset + 5] = keycode;
+
+        buff[offset + 6] = down;
+        buff[offset + 7] = 0;
+
+        sock._sQlen += 8;
+        sock.flush();
+    },
+
     pointerEvent(sock, x, y, mask) {
         const buff = sock._sQ;
         const offset = sock._sQlen;
diff --git a/systemvm/agent/noVNC/keymaps/generate-language-keymaps.py b/systemvm/agent/noVNC/keymaps/generate-language-keymaps.py
new file mode 100755
index 0000000..1818037
--- /dev/null
+++ b/systemvm/agent/noVNC/keymaps/generate-language-keymaps.py
@@ -0,0 +1,127 @@
+#!/usr/bin/env python
+
+# This script
+# (1) loads keysym name and keycode mappings from noVNC/core/input/keysym.js and
+# (2) loads keysyn name to atset1 code mappings from keymap files which can be downloadeded from https://github.com/qemu/qemu/blob/master/pc-bios/keymaps
+# (3) generates the mappings of keycode and atset1 code
+#
+# Note: please add language specific mappings if needed.
+
+import os
+import sys
+
+keycode_to_x11name = {}
+x11name_to_atset1 = {}
+layout = ""
+result_mappings = {}
+js_config = []
+
+
+def generate_x11name_to_atset1_map(keymap_file):
+    # keymap files can be downloadeded from
+    # https://github.com/qemu/qemu/blob/master/pc-bios/keymaps
+    global layout
+    try:
+        for c in open(keymap_file):
+            if len(c.strip()) == 0:
+                continue
+            if c.startswith("# quirks section start"):
+                # Stop at the quirks section
+                break
+            if c.startswith("#"):
+                if "layout" in c and ":" in c:
+                    layout = c.split(":")[1].strip()
+                continue
+            if "map " in c:
+                continue
+            values = c.strip().split(" ")
+            if len(values) >= 2:
+                keyname = 'XK_' + values[0]
+                keycode = ' '.join(values[1:]).strip()
+                if keyname not in x11name_to_atset1:
+                    x11name_to_atset1[keyname] = keycode
+                else:
+                    print("Duplicated atset1 code for x11name '%s': '%s' and '%s'" % (
+                    keyname, x11name_to_atset1[keyname], keycode))
+
+    except IOError:
+        print(
+            "File '%s' does not exist. \nkeymaps can be downloaded from https://github.com/qemu/qemu/tree/master/pc-bios/keymaps" % keymap_file)
+        sys.exit(2)
+
+
+def generate_keycode_to_x11name():
+    for k in open("../core/input/keysym.js"):
+        k = k.strip()
+        if k.startswith("/") or k.startswith("*"):
+            continue
+        values = k.split(":")
+        if len(values) >= 2:
+            keyname = values[0]
+            keycode = values[1].strip().split(",")[0].lower()
+            keycode_int = int(keycode, 16)
+            if str(keycode_int) not in keycode_to_x11name:
+                keycode_to_x11name[str(keycode_int)] = keyname
+
+
+def translate(keysym):
+    x11name = keycode_to_x11name[str(keysym)]
+    if x11name not in x11name_to_atset1:
+        print("Cannot find atset1 code for keysym (%s) / x11name (%s) in keymaps" % (keysym, x11name))
+        return "", ""
+    atset1 = x11name_to_atset1[x11name]
+    values = atset1.split(" ")
+    rest = ""
+    if len(values) >= 2:
+        atset1 = values[0]
+        rest = " ".join(values[1:])
+    return str(int(atset1, 16)), rest
+
+
+def add_language_specific_mappings():
+    if layout == "jp":
+        add_specific_mapping("124", "125", "shift")     # bar
+
+
+def add_specific_mapping(keycode, atset1, rest):
+    result_mappings[keycode] = "%s %s" % (str(atset1).ljust(10), rest)
+
+
+def generate_js_file(keymap_file):
+    generated_filename = keymap_file + "-atset1.js"
+    handle = open(generated_filename, "w")
+    js_config.append("/* This file is auto-generated by generate-language-keymaps.py\n")
+    js_config.append(" * command    : %s\n" % (" ".join(sys.argv)))
+    js_config.append(" * layout     : %s\n" % layout)
+    js_config.append(" */\n")
+    js_config.append("export default {\n")
+    for keycode in dict(sorted(result_mappings.items(), key=lambda item: int(item[0]))):
+        js_config.append("%10s : \"%s\",\n" % ("\"" + str(keycode) + "\"", result_mappings[keycode].strip()))
+    js_config.append("}")
+    for line in js_config:
+        handle.write(line)
+    handle.close()
+    print("Created file %s" % generated_filename)
+
+
+def main(argv):
+    if len(argv) < 1:
+        print("Usage:   %s <keymap file>" % (sys.argv[0]))
+        sys.exit(1)
+    keymap_file = argv[0]
+    generate_keycode_to_x11name()
+    generate_x11name_to_atset1_map(keymap_file)
+
+    # insert language-specific mappings at beginning
+    add_language_specific_mappings()
+
+    for keycode in keycode_to_x11name:
+        atset1, rest = translate(keycode)
+        if atset1 and keycode not in result_mappings and int(keycode) < 65000:
+            result_mappings[keycode] = "%s %s" % (str(atset1).ljust(10), rest)
+
+    generate_js_file(keymap_file)
+
+
+if __name__ == "__main__":
+    main(sys.argv[1:])
diff --git a/systemvm/agent/noVNC/keymaps/keymap-ja b/systemvm/agent/noVNC/keymaps/keymap-ja
new file mode 100644
index 0000000..4589dd2
--- /dev/null
+++ b/systemvm/agent/noVNC/keymaps/keymap-ja
@@ -0,0 +1,995 @@
+#
+# generated by qemu-keymap
+#    model   : jp106
+#    layout  : jp
+#    variant : -
+#    options : -
+
+# name: "Japanese"
+
+# modifiers
+#     0: Shift
+#     1: Lock
+#     2: Control
+#     3: Mod1
+#     4: Mod2
+#     5: Mod3
+#     6: Mod4
+#     7: Mod5
+#     8: NumLock
+#     9: Alt
+#    10: LevelThree
+#    11: LAlt
+#    12: RAlt
+#    13: RControl
+#    14: LControl
+#    15: ScrollLock
+#    16: LevelFive
+#    17: AltGr
+#    18: Meta
+#    19: Super
+#    20: Hyper
+
+# evdev 1 (0x1), QKeyCode "esc", number 0x1
+Escape 0x01
+
+# evdev 2 (0x2), QKeyCode "1", number 0x2
+1 0x02
+exclam 0x02 shift
+
+# evdev 3 (0x3), QKeyCode "2", number 0x3
+2 0x03
+quotedbl 0x03 shift
+
+# evdev 4 (0x4), QKeyCode "3", number 0x4
+3 0x04
+numbersign 0x04 shift
+
+# evdev 5 (0x5), QKeyCode "4", number 0x5
+4 0x05
+dollar 0x05 shift
+
+# evdev 6 (0x6), QKeyCode "5", number 0x6
+5 0x06
+percent 0x06 shift
+
+# evdev 7 (0x7), QKeyCode "6", number 0x7
+6 0x07
+ampersand 0x07 shift
+
+# evdev 8 (0x8), QKeyCode "7", number 0x8
+7 0x08
+apostrophe 0x08 shift
+
+# evdev 9 (0x9), QKeyCode "8", number 0x9
+8 0x09
+parenleft 0x09 shift
+
+# evdev 10 (0xa), QKeyCode "9", number 0xa
+9 0x0a
+parenright 0x0a shift
+
+# evdev 11 (0xb), QKeyCode "0", number 0xb
+0 0x0b
+asciitilde 0x0b shift
+
+# evdev 12 (0xc), QKeyCode "minus", number 0xc
+minus 0x0c
+equal 0x0c shift
+
+# evdev 13 (0xd), QKeyCode "equal", number 0xd
+asciicircum 0x0d
+asciitilde 0x0d shift
+
+# evdev 14 (0xe), QKeyCode "backspace", number 0xe
+BackSpace 0x0e
+
+# evdev 15 (0xf), QKeyCode "tab", number 0xf
+Tab 0x0f
+ISO_Left_Tab 0x0f shift
+
+# evdev 16 (0x10), QKeyCode "q", number 0x10
+q 0x10
+Q 0x10 shift
+
+# evdev 17 (0x11), QKeyCode "w", number 0x11
+w 0x11
+W 0x11 shift
+
+# evdev 18 (0x12), QKeyCode "e", number 0x12
+e 0x12
+E 0x12 shift
+
+# evdev 19 (0x13), QKeyCode "r", number 0x13
+r 0x13
+R 0x13 shift
+
+# evdev 20 (0x14), QKeyCode "t", number 0x14
+t 0x14
+T 0x14 shift
+
+# evdev 21 (0x15), QKeyCode "y", number 0x15
+y 0x15
+Y 0x15 shift
+
+# evdev 22 (0x16), QKeyCode "u", number 0x16
+u 0x16
+U 0x16 shift
+
+# evdev 23 (0x17), QKeyCode "i", number 0x17
+i 0x17
+I 0x17 shift
+
+# evdev 24 (0x18), QKeyCode "o", number 0x18
+o 0x18
+O 0x18 shift
+
+# evdev 25 (0x19), QKeyCode "p", number 0x19
+p 0x19
+P 0x19 shift
+
+# evdev 26 (0x1a), QKeyCode "bracket_left", number 0x1a
+at 0x1a
+grave 0x1a shift
+
+# evdev 27 (0x1b), QKeyCode "bracket_right", number 0x1b
+bracketleft 0x1b
+braceleft 0x1b shift
+
+# evdev 28 (0x1c), QKeyCode "ret", number 0x1c
+Return 0x1c
+
+# evdev 29 (0x1d), QKeyCode "ctrl", number 0x1d
+Control_L 0x1d
+
+# evdev 30 (0x1e), QKeyCode "a", number 0x1e
+a 0x1e
+A 0x1e shift
+
+# evdev 31 (0x1f), QKeyCode "s", number 0x1f
+s 0x1f
+S 0x1f shift
+
+# evdev 32 (0x20), QKeyCode "d", number 0x20
+d 0x20
+D 0x20 shift
+
+# evdev 33 (0x21), QKeyCode "f", number 0x21
+f 0x21
+F 0x21 shift
+
+# evdev 34 (0x22), QKeyCode "g", number 0x22
+g 0x22
+G 0x22 shift
+
+# evdev 35 (0x23), QKeyCode "h", number 0x23
+h 0x23
+H 0x23 shift
+
+# evdev 36 (0x24), QKeyCode "j", number 0x24
+j 0x24
+J 0x24 shift
+
+# evdev 37 (0x25), QKeyCode "k", number 0x25
+k 0x25
+K 0x25 shift
+
+# evdev 38 (0x26), QKeyCode "l", number 0x26
+l 0x26
+L 0x26 shift
+
+# evdev 39 (0x27), QKeyCode "semicolon", number 0x27
+semicolon 0x27
+plus 0x27 shift
+
+# evdev 40 (0x28), QKeyCode "apostrophe", number 0x28
+colon 0x28
+asterisk 0x28 shift
+
+# evdev 41 (0x29), QKeyCode "grave_accent", number 0x29
+Zenkaku_Hankaku 0x29
+
+# evdev 42 (0x2a), QKeyCode "shift", number 0x2a
+Shift_L 0x2a
+
+# evdev 43 (0x2b), QKeyCode "backslash", number 0x2b
+bracketright 0x2b
+braceright 0x2b shift
+
+# evdev 44 (0x2c), QKeyCode "z", number 0x2c
+z 0x2c
+Z 0x2c shift
+
+# evdev 45 (0x2d), QKeyCode "x", number 0x2d
+x 0x2d
+X 0x2d shift
+
+# evdev 46 (0x2e), QKeyCode "c", number 0x2e
+c 0x2e
+C 0x2e shift
+
+# evdev 47 (0x2f), QKeyCode "v", number 0x2f
+v 0x2f
+V 0x2f shift
+
+# evdev 48 (0x30), QKeyCode "b", number 0x30
+b 0x30
+B 0x30 shift
+
+# evdev 49 (0x31), QKeyCode "n", number 0x31
+n 0x31
+N 0x31 shift
+
+# evdev 50 (0x32), QKeyCode "m", number 0x32
+m 0x32
+M 0x32 shift
+
+# evdev 51 (0x33), QKeyCode "comma", number 0x33
+comma 0x33
+less 0x33 shift
+
+# evdev 52 (0x34), QKeyCode "dot", number 0x34
+period 0x34
+greater 0x34 shift
+
+# evdev 53 (0x35), QKeyCode "slash", number 0x35
+slash 0x35
+question 0x35 shift
+
+# evdev 54 (0x36), QKeyCode "shift_r", number 0x36
+Shift_R 0x36
+
+# evdev 55 (0x37), QKeyCode "kp_multiply", number 0x37
+KP_Multiply 0x37
+
+# evdev 56 (0x38), QKeyCode "alt", number 0x38
+Alt_L 0x38
+Meta_L 0x38 shift
+
+# evdev 57 (0x39), QKeyCode "spc", number 0x39
+space 0x39
+
+# evdev 58 (0x3a), QKeyCode "caps_lock", number 0x3a
+Eisu_toggle 0x3a
+Caps_Lock 0x3a shift
+
+# evdev 59 (0x3b), QKeyCode "f1", number 0x3b
+F1 0x3b
+
+# evdev 60 (0x3c), QKeyCode "f2", number 0x3c
+F2 0x3c
+
+# evdev 61 (0x3d), QKeyCode "f3", number 0x3d
+F3 0x3d
+
+# evdev 62 (0x3e), QKeyCode "f4", number 0x3e
+F4 0x3e
+
+# evdev 63 (0x3f), QKeyCode "f5", number 0x3f
+F5 0x3f
+
+# evdev 64 (0x40), QKeyCode "f6", number 0x40
+F6 0x40
+
+# evdev 65 (0x41), QKeyCode "f7", number 0x41
+F7 0x41
+
+# evdev 66 (0x42), QKeyCode "f8", number 0x42
+F8 0x42
+
+# evdev 67 (0x43), QKeyCode "f9", number 0x43
+F9 0x43
+
+# evdev 68 (0x44), QKeyCode "f10", number 0x44
+F10 0x44
+
+# evdev 69 (0x45), QKeyCode "num_lock", number 0x45
+Num_Lock 0x45
+
+# evdev 70 (0x46), QKeyCode "scroll_lock", number 0x46
+Scroll_Lock 0x46
+
+# evdev 71 (0x47), QKeyCode "kp_7", number 0x47
+KP_Home 0x47
+KP_7 0x47 numlock
+
+# evdev 72 (0x48), QKeyCode "kp_8", number 0x48
+KP_Up 0x48
+KP_8 0x48 numlock
+
+# evdev 73 (0x49), QKeyCode "kp_9", number 0x49
+KP_Prior 0x49
+KP_9 0x49 numlock
+
+# evdev 74 (0x4a), QKeyCode "kp_subtract", number 0x4a
+KP_Subtract 0x4a
+
+# evdev 75 (0x4b), QKeyCode "kp_4", number 0x4b
+KP_Left 0x4b
+KP_4 0x4b numlock
+
+# evdev 76 (0x4c), QKeyCode "kp_5", number 0x4c
+KP_Begin 0x4c
+KP_5 0x4c numlock
+
+# evdev 77 (0x4d), QKeyCode "kp_6", number 0x4d
+KP_Right 0x4d
+KP_6 0x4d numlock
+
+# evdev 78 (0x4e), QKeyCode "kp_add", number 0x4e
+KP_Add 0x4e
+
+# evdev 79 (0x4f), QKeyCode "kp_1", number 0x4f
+KP_End 0x4f
+KP_1 0x4f numlock
+
+# evdev 80 (0x50), QKeyCode "kp_2", number 0x50
+KP_Down 0x50
+KP_2 0x50 numlock
+
+# evdev 81 (0x51), QKeyCode "kp_3", number 0x51
+KP_Next 0x51
+KP_3 0x51 numlock
+
+# evdev 82 (0x52), QKeyCode "kp_0", number 0x52
+KP_Insert 0x52
+KP_0 0x52 numlock
+
+# evdev 83 (0x53), QKeyCode "kp_decimal", number 0x53
+KP_Delete 0x53
+KP_Decimal 0x53 numlock
+
+# evdev 84 (0x54): no evdev -> QKeyCode mapping (xkb keysym ISO_Level3_Shift)
+
+# evdev 85 (0x55): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 86 (0x56), QKeyCode "less", number 0x56
+less 0x56
+greater 0x56 shift
+bar 0x56 altgr
+brokenbar 0x56 shift altgr
+
+# evdev 87 (0x57), QKeyCode "f11", number 0x57
+F11 0x57
+
+# evdev 88 (0x58), QKeyCode "f12", number 0x58
+F12 0x58
+
+# evdev 89 (0x59), QKeyCode "ro", number 0x73
+backslash 0x73
+underscore 0x73 shift
+
+# evdev 90 (0x5a): no evdev -> QKeyCode mapping (xkb keysym Katakana)
+
+# evdev 91 (0x5b), QKeyCode "hiragana", number 0x77
+Hiragana 0x77
+
+# evdev 92 (0x5c), QKeyCode "henkan", number 0x79
+Henkan_Mode 0x79
+
+# evdev 93 (0x5d), QKeyCode "katakanahiragana", number 0x70
+Hiragana_Katakana 0x70
+
+# evdev 94 (0x5e), QKeyCode "muhenkan", number 0x7b
+Muhenkan 0x7b
+
+# evdev 95 (0x5f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 96 (0x60), QKeyCode "kp_enter", number 0x9c
+KP_Enter 0x9c
+
+# evdev 97 (0x61), QKeyCode "ctrl_r", number 0x9d
+Control_R 0x9d
+
+# evdev 98 (0x62), QKeyCode "kp_divide", number 0xb5
+KP_Divide 0xb5
+
+# evdev 99 (0x63), QKeyCode "sysrq", number 0x54
+Print 0x54
+
+# evdev 100 (0x64), QKeyCode "alt_r", number 0xb8
+Alt_R 0xb8
+Meta_R 0xb8 shift
+
+# evdev 101 (0x65), QKeyCode "lf", number 0x5b
+Linefeed 0x5b
+
+# evdev 102 (0x66), QKeyCode "home", number 0xc7
+Home 0xc7
+
+# evdev 103 (0x67), QKeyCode "up", number 0xc8
+Up 0xc8
+
+# evdev 104 (0x68), QKeyCode "pgup", number 0xc9
+Prior 0xc9
+
+# evdev 105 (0x69), QKeyCode "left", number 0xcb
+Left 0xcb
+
+# evdev 106 (0x6a), QKeyCode "right", number 0xcd
+Right 0xcd
+
+# evdev 107 (0x6b), QKeyCode "end", number 0xcf
+End 0xcf
+
+# evdev 108 (0x6c), QKeyCode "down", number 0xd0
+Down 0xd0
+
+# evdev 109 (0x6d), QKeyCode "pgdn", number 0xd1
+Next 0xd1
+
+# evdev 110 (0x6e), QKeyCode "insert", number 0xd2
+Insert 0xd2
+
+# evdev 111 (0x6f), QKeyCode "delete", number 0xd3
+Delete 0xd3
+
+# evdev 112 (0x70): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 113 (0x71), QKeyCode "audiomute", number 0xa0
+XF86AudioMute 0xa0
+
+# evdev 114 (0x72), QKeyCode "volumedown", number 0xae
+XF86AudioLowerVolume 0xae
+
+# evdev 115 (0x73), QKeyCode "volumeup", number 0xb0
+XF86AudioRaiseVolume 0xb0
+
+# evdev 116 (0x74), QKeyCode "power", number 0xde
+XF86PowerOff 0xde
+
+# evdev 117 (0x75), QKeyCode "kp_equals", number 0x59
+KP_Equal 0x59
+
+# evdev 118 (0x76): no evdev -> QKeyCode mapping (xkb keysym plusminus)
+
+# evdev 119 (0x77), QKeyCode "pause", number 0xc6
+Pause 0xc6
+
+# evdev 120 (0x78): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchA)
+
+# evdev 121 (0x79), QKeyCode "kp_comma", number 0x7e
+KP_Decimal 0x7e
+
+# evdev 122 (0x7a): no evdev -> QKeyCode mapping (xkb keysym Hangul)
+
+# evdev 123 (0x7b): no evdev -> QKeyCode mapping (xkb keysym Hangul_Hanja)
+
+# evdev 124 (0x7c), QKeyCode "yen", number 0x7d
+backslash 0x7d
+bar 0x7d shift
+
+# evdev 125 (0x7d), QKeyCode "meta_l", number 0xdb
+Super_L 0xdb
+
+# evdev 126 (0x7e), QKeyCode "meta_r", number 0xdc
+Super_R 0xdc
+
+# evdev 127 (0x7f), QKeyCode "compose", number 0xdd
+Menu 0xdd
+
+# evdev 128 (0x80), QKeyCode "stop", number 0xe8
+Cancel 0xe8
+
+# evdev 129 (0x81), QKeyCode "again", number 0x85
+Redo 0x85
+
+# evdev 130 (0x82), QKeyCode "props", number 0x86
+SunProps 0x86
+
+# evdev 131 (0x83), QKeyCode "undo", number 0x87
+Undo 0x87
+
+# evdev 132 (0x84), QKeyCode "front", number 0x8c
+SunFront 0x8c
+
+# evdev 133 (0x85), QKeyCode "copy", number 0xf8
+XF86Copy 0xf8
+
+# evdev 134 (0x86), QKeyCode "open", number 0x64
+XF86Open 0x64
+
+# evdev 135 (0x87), QKeyCode "paste", number 0x65
+XF86Paste 0x65
+
+# evdev 136 (0x88), QKeyCode "find", number 0xc1
+Find 0xc1
+
+# evdev 137 (0x89), QKeyCode "cut", number 0xbc
+XF86Cut 0xbc
+
+# evdev 138 (0x8a), QKeyCode "help", number 0xf5
+Help 0xf5
+
+# evdev 139 (0x8b), QKeyCode "menu", number 0x9e
+XF86MenuKB 0x9e
+
+# evdev 140 (0x8c), QKeyCode "calculator", number 0xa1
+XF86Calculator 0xa1
+
+# evdev 141 (0x8d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 142 (0x8e), QKeyCode "sleep", number 0xdf
+XF86Sleep 0xdf
+
+# evdev 143 (0x8f), QKeyCode "wake", number 0xe3
+XF86WakeUp 0xe3
+
+# evdev 144 (0x90): no evdev -> QKeyCode mapping (xkb keysym XF86Explorer)
+
+# evdev 145 (0x91): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
+
+# evdev 146 (0x92): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 147 (0x93): no evdev -> QKeyCode mapping (xkb keysym XF86Xfer)
+
+# evdev 148 (0x94): no evdev -> QKeyCode mapping (xkb keysym XF86Launch1)
+
+# evdev 149 (0x95): no evdev -> QKeyCode mapping (xkb keysym XF86Launch2)
+
+# evdev 150 (0x96): no evdev -> QKeyCode mapping (xkb keysym XF86WWW)
+
+# evdev 151 (0x97): no evdev -> QKeyCode mapping (xkb keysym XF86DOS)
+
+# evdev 152 (0x98): no evdev -> QKeyCode mapping (xkb keysym XF86ScreenSaver)
+
+# evdev 153 (0x99): no evdev -> QKeyCode mapping (xkb keysym XF86RotateWindows)
+
+# evdev 154 (0x9a): no evdev -> QKeyCode mapping (xkb keysym XF86TaskPane)
+
+# evdev 155 (0x9b), QKeyCode "mail", number 0xec
+XF86Mail 0xec
+
+# evdev 156 (0x9c), QKeyCode "ac_bookmarks", number 0xe6
+XF86Favorites 0xe6
+
+# evdev 157 (0x9d), QKeyCode "computer", number 0xeb
+XF86MyComputer 0xeb
+
+# evdev 158 (0x9e), QKeyCode "ac_back", number 0xea
+XF86Back 0xea
+
+# evdev 159 (0x9f), QKeyCode "ac_forward", number 0xe9
+XF86Forward 0xe9
+
+# evdev 160 (0xa0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 161 (0xa1): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
+
+# evdev 162 (0xa2): no evdev -> QKeyCode mapping (xkb keysym XF86Eject)
+
+# evdev 163 (0xa3), QKeyCode "audionext", number 0x99
+XF86AudioNext 0x99
+
+# evdev 164 (0xa4), QKeyCode "audioplay", number 0xa2
+XF86AudioPlay 0xa2
+XF86AudioPause 0xa2 shift
+
+# evdev 165 (0xa5), QKeyCode "audioprev", number 0x90
+XF86AudioPrev 0x90
+
+# evdev 166 (0xa6), QKeyCode "audiostop", number 0xa4
+XF86AudioStop 0xa4
+XF86Eject 0xa4 shift
+
+# evdev 167 (0xa7): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRecord)
+
+# evdev 168 (0xa8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioRewind)
+
+# evdev 169 (0xa9): no evdev -> QKeyCode mapping (xkb keysym XF86Phone)
+
+# evdev 170 (0xaa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 171 (0xab): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
+
+# evdev 172 (0xac), QKeyCode "ac_home", number 0xb2
+XF86HomePage 0xb2
+
+# evdev 173 (0xad), QKeyCode "ac_refresh", number 0xe7
+XF86Reload 0xe7
+
+# evdev 174 (0xae): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
+
+# evdev 175 (0xaf): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 176 (0xb0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 177 (0xb1): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollUp)
+
+# evdev 178 (0xb2): no evdev -> QKeyCode mapping (xkb keysym XF86ScrollDown)
+
+# evdev 179 (0xb3): no evdev -> QKeyCode mapping (xkb keysym parenleft)
+
+# evdev 180 (0xb4): no evdev -> QKeyCode mapping (xkb keysym parenright)
+
+# evdev 181 (0xb5): no evdev -> QKeyCode mapping (xkb keysym XF86New)
+
+# evdev 182 (0xb6): no evdev -> QKeyCode mapping (xkb keysym Redo)
+
+# evdev 183 (0xb7): no evdev -> QKeyCode mapping (xkb keysym XF86Tools)
+
+# evdev 184 (0xb8): no evdev -> QKeyCode mapping (xkb keysym XF86Launch5)
+
+# evdev 185 (0xb9): no evdev -> QKeyCode mapping (xkb keysym XF86Launch6)
+
+# evdev 186 (0xba): no evdev -> QKeyCode mapping (xkb keysym XF86Launch7)
+
+# evdev 187 (0xbb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch8)
+
+# evdev 188 (0xbc): no evdev -> QKeyCode mapping (xkb keysym XF86Launch9)
+
+# evdev 189 (0xbd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 190 (0xbe): no evdev -> QKeyCode mapping (xkb keysym XF86AudioMicMute)
+
+# evdev 191 (0xbf): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadToggle)
+
+# evdev 192 (0xc0): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOn)
+
+# evdev 193 (0xc1): no evdev -> QKeyCode mapping (xkb keysym XF86TouchpadOff)
+
+# evdev 194 (0xc2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 195 (0xc3): no evdev -> QKeyCode mapping (xkb keysym Mode_switch)
+
+# evdev 196 (0xc4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 197 (0xc5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 198 (0xc6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 199 (0xc7): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 200 (0xc8): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
+
+# evdev 201 (0xc9): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPause)
+
+# evdev 202 (0xca): no evdev -> QKeyCode mapping (xkb keysym XF86Launch3)
+
+# evdev 203 (0xcb): no evdev -> QKeyCode mapping (xkb keysym XF86Launch4)
+
+# evdev 204 (0xcc): no evdev -> QKeyCode mapping (xkb keysym XF86LaunchB)
+
+# evdev 205 (0xcd): no evdev -> QKeyCode mapping (xkb keysym XF86Suspend)
+
+# evdev 206 (0xce): no evdev -> QKeyCode mapping (xkb keysym XF86Close)
+
+# evdev 207 (0xcf): no evdev -> QKeyCode mapping (xkb keysym XF86AudioPlay)
+
+# evdev 208 (0xd0): no evdev -> QKeyCode mapping (xkb keysym XF86AudioForward)
+
+# evdev 209 (0xd1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 210 (0xd2): no evdev -> QKeyCode mapping (xkb keysym Print)
+
+# evdev 211 (0xd3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 212 (0xd4): no evdev -> QKeyCode mapping (xkb keysym XF86WebCam)
+
+# evdev 213 (0xd5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 214 (0xd6): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 215 (0xd7): no evdev -> QKeyCode mapping (xkb keysym XF86Mail)
+
+# evdev 216 (0xd8): no evdev -> QKeyCode mapping (xkb keysym XF86Messenger)
+
+# evdev 217 (0xd9): no evdev -> QKeyCode mapping (xkb keysym XF86Search)
+
+# evdev 218 (0xda): no evdev -> QKeyCode mapping (xkb keysym XF86Go)
+
+# evdev 219 (0xdb): no evdev -> QKeyCode mapping (xkb keysym XF86Finance)
+
+# evdev 220 (0xdc): no evdev -> QKeyCode mapping (xkb keysym XF86Game)
+
+# evdev 221 (0xdd): no evdev -> QKeyCode mapping (xkb keysym XF86Shop)
+
+# evdev 222 (0xde): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 223 (0xdf): no evdev -> QKeyCode mapping (xkb keysym Cancel)
+
+# evdev 224 (0xe0): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessDown)
+
+# evdev 225 (0xe1): no evdev -> QKeyCode mapping (xkb keysym XF86MonBrightnessUp)
+
+# evdev 226 (0xe2), QKeyCode "mediaselect", number 0xed
+XF86AudioMedia 0xed
+
+# evdev 227 (0xe3): no evdev -> QKeyCode mapping (xkb keysym XF86Display)
+
+# evdev 228 (0xe4): no evdev -> QKeyCode mapping (xkb keysym XF86KbdLightOnOff)
+
+# evdev 229 (0xe5): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessDown)
+
+# evdev 230 (0xe6): no evdev -> QKeyCode mapping (xkb keysym XF86KbdBrightnessUp)
+
+# evdev 231 (0xe7): no evdev -> QKeyCode mapping (xkb keysym XF86Send)
+
+# evdev 232 (0xe8): no evdev -> QKeyCode mapping (xkb keysym XF86Reply)
+
+# evdev 233 (0xe9): no evdev -> QKeyCode mapping (xkb keysym XF86MailForward)
+
+# evdev 234 (0xea): no evdev -> QKeyCode mapping (xkb keysym XF86Save)
+
+# evdev 235 (0xeb): no evdev -> QKeyCode mapping (xkb keysym XF86Documents)
+
+# evdev 236 (0xec): no evdev -> QKeyCode mapping (xkb keysym XF86Battery)
+
+# evdev 237 (0xed): no evdev -> QKeyCode mapping (xkb keysym XF86Bluetooth)
+
+# evdev 238 (0xee): no evdev -> QKeyCode mapping (xkb keysym XF86WLAN)
+
+# evdev 239 (0xef): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 240 (0xf0): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 241 (0xf1): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 242 (0xf2): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 243 (0xf3): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 244 (0xf4): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 245 (0xf5): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 246 (0xf6): no evdev -> QKeyCode mapping (xkb keysym XF86WWAN)
+
+# evdev 247 (0xf7): no evdev -> QKeyCode mapping (xkb keysym XF86RFKill)
+
+# evdev 248 (0xf8): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 249 (0xf9): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 250 (0xfa): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 251 (0xfb): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 252 (0xfc): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 253 (0xfd): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 254 (0xfe): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 255 (0xff): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 256 (0x100): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 257 (0x101): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 258 (0x102): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 259 (0x103): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 260 (0x104): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 261 (0x105): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 262 (0x106): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 263 (0x107): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 264 (0x108): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 265 (0x109): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 266 (0x10a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 267 (0x10b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 268 (0x10c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 269 (0x10d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 270 (0x10e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 271 (0x10f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 272 (0x110): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 273 (0x111): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 274 (0x112): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 275 (0x113): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 276 (0x114): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 277 (0x115): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 278 (0x116): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 279 (0x117): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 280 (0x118): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 281 (0x119): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 282 (0x11a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 283 (0x11b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 284 (0x11c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 285 (0x11d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 286 (0x11e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 287 (0x11f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 288 (0x120): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 289 (0x121): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 290 (0x122): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 291 (0x123): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 292 (0x124): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 293 (0x125): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 294 (0x126): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 295 (0x127): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 296 (0x128): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 297 (0x129): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 298 (0x12a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 299 (0x12b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 300 (0x12c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 301 (0x12d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 302 (0x12e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 303 (0x12f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 304 (0x130): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 305 (0x131): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 306 (0x132): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 307 (0x133): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 308 (0x134): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 309 (0x135): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 310 (0x136): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 311 (0x137): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 312 (0x138): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 313 (0x139): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 314 (0x13a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 315 (0x13b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 316 (0x13c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 317 (0x13d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 318 (0x13e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 319 (0x13f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 320 (0x140): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 321 (0x141): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 322 (0x142): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 323 (0x143): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 324 (0x144): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 325 (0x145): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 326 (0x146): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 327 (0x147): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 328 (0x148): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 329 (0x149): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 330 (0x14a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 331 (0x14b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 332 (0x14c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 333 (0x14d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 334 (0x14e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 335 (0x14f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 336 (0x150): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 337 (0x151): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 338 (0x152): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 339 (0x153): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 340 (0x154): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 341 (0x155): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 342 (0x156): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 343 (0x157): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 344 (0x158): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 345 (0x159): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 346 (0x15a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 347 (0x15b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 348 (0x15c): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 349 (0x15d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 350 (0x15e): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 351 (0x15f): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 352 (0x160): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 353 (0x161): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 354 (0x162): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 355 (0x163): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 356 (0x164): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 357 (0x165): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 358 (0x166): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 359 (0x167): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 360 (0x168): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 361 (0x169): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 362 (0x16a): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 363 (0x16b): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 364 (0x16c): no evdev -> QKeyCode mapping (xkb keysym XF86Favorites)
+
+# evdev 365 (0x16d): no evdev -> QKeyCode mapping (xkb keysym NoSymbol)
+
+# evdev 366 (0x16e): no evdev -> QKeyCode mapping (xkb keysym XF86Keyboard)
+
+#
+# quirks section start
+#
+# Sometimes multiple keysyms map to the same keycodes.
+# The keycode -> keysym lookup finds only one of the
+# keysyms.  So append them here.
+#
+
+Print 0x54
+Sys_Req 0x54
+Execute 0x54
+KP_Decimal 0x53 numlock
+KP_Separator 0x53 numlock
+Alt_R 0xb8
+ISO_Level3_Shift 0xb8
+Mode_switch 0xb8
+
+# quirks section end
diff --git a/systemvm/agent/noVNC/keymaps/keymap-ja-atset1.js b/systemvm/agent/noVNC/keymaps/keymap-ja-atset1.js
new file mode 100644
index 0000000..847ce2b
--- /dev/null
+++ b/systemvm/agent/noVNC/keymaps/keymap-ja-atset1.js
@@ -0,0 +1,102 @@
+/* This file is auto-generated by generate-language-keymaps.py
+ * command    : ./generate-language-keymaps.py keymap-ja
+ * layout     : jp
+ */
+export default {
+      "32" : "57",
+      "33" : "2          shift",
+      "34" : "3          shift",
+      "35" : "4          shift",
+      "36" : "5          shift",
+      "37" : "6          shift",
+      "38" : "7          shift",
+      "39" : "8          shift",
+      "40" : "9          shift",
+      "41" : "10         shift",
+      "42" : "40         shift",
+      "43" : "39         shift",
+      "44" : "51",
+      "45" : "12",
+      "46" : "52",
+      "47" : "53",
+      "48" : "11",
+      "49" : "2",
+      "50" : "3",
+      "51" : "4",
+      "52" : "5",
+      "53" : "6",
+      "54" : "7",
+      "55" : "8",
+      "56" : "9",
+      "57" : "10",
+      "58" : "40",
+      "59" : "39",
+      "60" : "51         shift",
+      "61" : "12         shift",
+      "62" : "52         shift",
+      "63" : "53         shift",
+      "64" : "26",
+      "65" : "30         shift",
+      "66" : "48         shift",
+      "67" : "46         shift",
+      "68" : "32         shift",
+      "69" : "18         shift",
+      "70" : "33         shift",
+      "71" : "34         shift",
+      "72" : "35         shift",
+      "73" : "23         shift",
+      "74" : "36         shift",
+      "75" : "37         shift",
+      "76" : "38         shift",
+      "77" : "50         shift",
+      "78" : "49         shift",
+      "79" : "24         shift",
+      "80" : "25         shift",
+      "81" : "16         shift",
+      "82" : "19         shift",
+      "83" : "31         shift",
+      "84" : "20         shift",
+      "85" : "22         shift",
+      "86" : "47         shift",
+      "87" : "17         shift",
+      "88" : "45         shift",
+      "89" : "21         shift",
+      "90" : "44         shift",
+      "91" : "27",
+      "92" : "115",
+      "93" : "43",
+      "94" : "13",
+      "95" : "115        shift",
+      "96" : "26         shift",
+      "97" : "30",
+      "98" : "48",
+      "99" : "46",
+     "100" : "32",
+     "101" : "18",
+     "102" : "33",
+     "103" : "34",
+     "104" : "35",
+     "105" : "23",
+     "106" : "36",
+     "107" : "37",
+     "108" : "38",
+     "109" : "50",
+     "110" : "49",
+     "111" : "24",
+     "112" : "25",
+     "113" : "16",
+     "114" : "19",
+     "115" : "31",
+     "116" : "20",
+     "117" : "22",
+     "118" : "47",
+     "119" : "17",
+     "120" : "45",
+     "121" : "21",
+     "122" : "44",
+     "123" : "27         shift",
+     "124" : "125        shift",
+     "125" : "43         shift",
+     "126" : "11         shift",
+     "166" : "86         shift altgr",
+}
\ No newline at end of file
diff --git a/test/integration/smoke/test_kubernetes_clusters.py b/test/integration/smoke/test_kubernetes_clusters.py
index 3b45347..c18711e 100644
--- a/test/integration/smoke/test_kubernetes_clusters.py
+++ b/test/integration/smoke/test_kubernetes_clusters.py
@@ -92,6 +92,9 @@
         cls.vpcAllowAllAclDetailsMap = {}
         cls.initial_configuration_cks_enabled = None
 
+        cls.k8s_version_from = cls.services["cks_kubernetes_version_upgrade_from"]
+        cls.k8s_version_to = cls.services["cks_kubernetes_version_upgrade_to"]
+
         if cls.hypervisorNotSupported == False:
             cls.endpoint_url = Configurations.list(cls.apiclient, name="endpoint.url")[0].value
             if "localhost" in cls.endpoint_url:
@@ -110,20 +113,20 @@
 
             if cls.setup_failed == False:
                 try:
-                    cls.kubernetes_version_1_23_3 = cls.addKubernetesSupportedVersion(cls.services["cks_kubernetes_versions"]["1.23.3"])
-                    cls.kubernetes_version_ids.append(cls.kubernetes_version_1_23_3.id)
+                    cls.kubernetes_version_v1 = cls.addKubernetesSupportedVersion(cls.services["cks_kubernetes_versions"][cls.k8s_version_from])
+                    cls.kubernetes_version_ids.append(cls.kubernetes_version_v1.id)
                 except Exception as e:
                     cls.setup_failed = True
                     cls.debug("Failed to get Kubernetes version ISO in ready state, version=%s, url=%s, %s" %
-                        (cls.services["cks_kubernetes_versions"]["1.23.3"]["semanticversion"], cls.services["cks_kubernetes_versions"]["1.23.3"]["url"], e))
+                        (cls.services["cks_kubernetes_versions"][cls.k8s_version_from]["semanticversion"], cls.services["cks_kubernetes_versions"][cls.k8s_version_from]["url"], e))
             if cls.setup_failed == False:
                 try:
-                    cls.kubernetes_version_1_24_0 = cls.addKubernetesSupportedVersion(cls.services["cks_kubernetes_versions"]["1.24.0"])
-                    cls.kubernetes_version_ids.append(cls.kubernetes_version_1_24_0.id)
+                    cls.kubernetes_version_v2 = cls.addKubernetesSupportedVersion(cls.services["cks_kubernetes_versions"][cls.k8s_version_to])
+                    cls.kubernetes_version_ids.append(cls.kubernetes_version_v2.id)
                 except Exception as e:
                     cls.setup_failed = True
                     cls.debug("Failed to get Kubernetes version ISO in ready state, version=%s, url=%s, %s" %
-                        (cls.services["cks_kubernetes_versions"]["1.24.0"]["semanticversion"], cls.services["cks_kubernetes_versions"]["1.24.0"]["url"], e))
+                        (cls.services["cks_kubernetes_versions"][cls.k8s_version_to]["semanticversion"], cls.services["cks_kubernetes_versions"][cls.k8s_version_to]["url"], e))
 
             if cls.setup_failed == False:
                 cks_offering_data = cls.services["cks_service_offering"]
@@ -371,20 +374,20 @@
         if self.setup_failed == True:
             self.fail("Setup incomplete")
         global k8s_cluster
-        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_1_24_0)
+        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_v2)
 
         self.debug("Downgrading Kubernetes cluster with ID: %s to a lower version. This should fail!" % k8s_cluster.id)
 
         try:
-            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_1_23_3.id)
-            self.debug("Invalid CKS Kubernetes HA cluster deployed with ID: %s. Deleting it and failing test." % self.kubernetes_version_1_23_3.id)
+            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_v1.id)
+            self.debug("Invalid CKS Kubernetes HA cluster deployed with ID: %s. Deleting it and failing test." % self.kubernetes_version_v1.id)
             self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
             self.fail("Kubernetes cluster downgrade to a lower Kubernetes supported version. Must be an error.")
         except Exception as e:
             self.debug("Upgrading Kubernetes cluster with invalid Kubernetes supported version check successful, API failure: %s" % e)
             self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
 
-        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_1_24_0.id)
+        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_v2.id)
         return
 
     @attr(tags=["advanced", "smoke"], required_hardware="true")
@@ -398,17 +401,17 @@
         if self.setup_failed == True:
             self.fail("Setup incomplete")
         global k8s_cluster
-        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_1_23_3)
+        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_v1)
 
         time.sleep(self.services["sleep"])
         self.debug("Upgrading Kubernetes cluster with ID: %s" % k8s_cluster.id)
         try:
-            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_1_24_0.id)
+            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_v2.id)
         except Exception as e:
             self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
             self.fail("Failed to upgrade Kubernetes cluster due to: %s" % e)
 
-        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_1_24_0.id)
+        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_v2.id)
         return
 
     @attr(tags=["advanced", "smoke"], required_hardware="true")
@@ -456,7 +459,7 @@
         if self.setup_failed == True:
             self.fail("Setup incomplete")
         global k8s_cluster
-        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_1_24_0)
+        k8s_cluster = self.getValidKubernetesCluster(version=self.kubernetes_version_v2)
 
         self.debug("Autoscaling Kubernetes cluster with ID: %s" % k8s_cluster.id)
         try:
@@ -556,17 +559,17 @@
         if self.default_network:
             self.skipTest("HA cluster on shared network requires external ip address, skipping it")
         global k8s_cluster
-        k8s_cluster = self.getValidKubernetesCluster(1, 2, version=self.kubernetes_version_1_23_3)
+        k8s_cluster = self.getValidKubernetesCluster(1, 2, version=self.kubernetes_version_v1)
         time.sleep(self.services["sleep"])
 
         self.debug("Upgrading HA Kubernetes cluster with ID: %s" % k8s_cluster.id)
         try:
-            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_1_24_0.id)
+            k8s_cluster = self.upgradeKubernetesCluster(k8s_cluster.id, self.kubernetes_version_v2.id)
         except Exception as e:
             self.deleteKubernetesClusterAndVerify(k8s_cluster.id, False, True)
             self.fail("Failed to upgrade Kubernetes HA cluster due to: %s" % e)
 
-        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_1_24_0.id)
+        self.verifyKubernetesClusterUpgrade(k8s_cluster, self.kubernetes_version_v2.id)
         self.debug("Kubernetes cluster with ID: %s successfully upgraded" % k8s_cluster.id)
         return
 
@@ -772,7 +775,7 @@
         # Does a cluster already exist ?
         if cluster == None or cluster.id == None:
             if not version:
-                version = self.kubernetes_version_1_24_0
+                version = self.kubernetes_version_v2
             self.debug("No existing cluster available, k8s_cluster: %s" % cluster)
             return self.createNewKubernetesCluster(version, size, control_nodes)
 
@@ -782,7 +785,7 @@
             # Check the version only if specified
             valid = valid and cluster.kubernetesversionid == version.id
         else:
-            version = self.kubernetes_version_1_24_0
+            version = self.kubernetes_version_v2
 
         if valid:
             cluster_id = cluster.id
diff --git a/test/integration/smoke/test_kubernetes_supported_versions.py b/test/integration/smoke/test_kubernetes_supported_versions.py
index 229fff9..6acf7f2 100644
--- a/test/integration/smoke/test_kubernetes_supported_versions.py
+++ b/test/integration/smoke/test_kubernetes_supported_versions.py
@@ -45,7 +45,8 @@
         cls.services = cls.testClient.getParsedTestDataConfig()
         cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
         cls.mgtSvrDetails = cls.config.__dict__["mgtSvr"][0].__dict__
-        cls.kubernetes_version_iso_url = 'http://download.cloudstack.org/cks/setup-1.24.0.iso'
+        cls.kubernetes_version = cls.services["cks_kubernetes_version"]
+        cls.kubernetes_version_iso_url = cls.services["cks_kubernetes_versions"][cls.kubernetes_version]["url"]
 
         cls.initial_configuration_cks_enabled = Configurations.list(cls.apiclient,
                                                                     name="cloud.kubernetes.service.enabled")[0].value
diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py
index 3a88d08..c4ac600 100644
--- a/tools/marvin/marvin/config/test_data.py
+++ b/tools/marvin/marvin/config/test_data.py
@@ -2248,8 +2248,23 @@
             "url": "http://download.cloudstack.org/cks/setup-1.24.0.iso",
             "mincpunumber": 2,
             "minmemory": 2048
+        },
+        "1.25.0": {
+            "semanticversion": "1.25.0",
+            "url": "http://download.cloudstack.org/cks/setup-1.25.0.iso",
+            "mincpunumber": 2,
+            "minmemory": 2048
+        },
+        "1.26.0": {
+            "semanticversion": "1.26.0",
+            "url": "http://download.cloudstack.org/cks/setup-1.26.0.iso",
+            "mincpunumber": 2,
+            "minmemory": 2048
         }
     },
+    "cks_kubernetes_version": "1.26.0",
+    "cks_kubernetes_version_upgrade_from": "1.25.0",
+    "cks_kubernetes_version_upgrade_to": "1.26.0",
     "cks_service_offering": {
         "name": "CKS-Instance",
         "displaytext": "CKS Instance",