let match_res;
- if ((match_res = p.match(/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|vmxnet3|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i)) !== null) {
+ if ((match_res = p.match(/^(ne2k_pci|e1000e?|e1000-82540em|e1000-82544gc|e1000-82545em|vmxnet3|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i)) !== null) {
res.model = match_res[1].toLowerCase();
if (match_res[3]) {
res.macaddr = match_res[3];
}
} else if ((match_res = p.match(/^bridge=(\S+)$/)) !== null) {
res.bridge = match_res[1];
- } else if ((match_res = p.match(/^rate=(\d+(\.\d+)?)$/)) !== null) {
+ } else if ((match_res = p.match(/^rate=(\d+(\.\d+)?|\.\d+)$/)) !== null) {
res.rate = match_res[1];
} else if ((match_res = p.match(/^tag=(\d+(\.\d+)?)$/)) !== null) {
res.tag = match_res[1];
data[match_res[1]] = match_res[2];
} else if ((match_res = p.match(/^firewall=(\d+)$/)) !== null) {
data.firewall = PVE.Parser.parseBoolean(match_res[1]);
+ } else if ((match_res = p.match(/^link_down=(\d+)$/)) !== null) {
+ data.link_down = PVE.Parser.parseBoolean(match_res[1]);
} else if (!p.match(/^type=\S+$/)) {
console.warn(`could not parse LXC network string ${p}`);
}
name: 1,
rate: 1,
tag: 1,
+ link_down: 1,
};
return Object.entries(config)
.filter(([k, v]) => v !== undefined && v !== '' && knownKeys[k])
parseSSHKey: function(key) {
// |--- options can have quotes--| type key comment
let keyre = /^(?:((?:[^\s"]|"(?:\\.|[^"\\])*")+)\s+)?(\S+)\s+(\S+)(?:\s+(.*))?$/;
- let typere = /^(?:(?:sk-)?ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)$/;
+ let typere = /^(?:(?:sk-)?(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)(?:@(?:[a-z0-9_-]+\.)+[a-z]{2,})?)$/;
let m = key.match(keyre);
if (!m || m.length < 3 || !m[2]) { // [2] is always either type or key
});
return [res, extradata];
},
+
+ filterPropertyStringList: function(list, filterFn, defaultKey) {
+ return list.filter((entry) => filterFn(PVE.Parser.parsePropertyString(entry, defaultKey)));
+ },
},
});