summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Estabrook <jestabro@vyos.io>2020-01-14 09:18:16 -0600
committerGitHub <noreply@github.com>2020-01-14 09:18:16 -0600
commit29e3f990303c6d01c37f4fafc44d0d3cbcd4558e (patch)
tree2828d034d5ae467abbfb155015f40685d2518424
parent91de4ec9d95a6a99df0ad5363633251bcb5f4874 (diff)
parent29e438755c8bd2b9598a2016a3c42891f0cbfa1d (diff)
downloadvyos-1x-29e3f990303c6d01c37f4fafc44d0d3cbcd4558e.tar.gz
vyos-1x-29e3f990303c6d01c37f4fafc44d0d3cbcd4558e.zip
Merge pull request #205 from jestabro/syntax-version
Syntax version
-rw-r--r--Makefile8
-rw-r--r--python/vyos/defaults.py2
-rw-r--r--python/vyos/systemversions.py28
-rw-r--r--schema/interface_definition.rnc17
-rw-r--r--schema/interface_definition.rng18
-rwxr-xr-xscripts/build-command-templates2
-rwxr-xr-xscripts/build-component-versions47
7 files changed, 119 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 61e603612..d05a0adbe 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
TMPL_DIR := templates-cfg
OP_TMPL_DIR := templates-op
BUILD_DIR := build
+DATA_DIR := data
CFLAGS :=
src = $(wildcard interface-definitions/*.xml.in)
@@ -77,8 +78,13 @@ op_mode_definitions:
rm -f $(OP_TMPL_DIR)/reset/vpn/node.def
rm -f $(OP_TMPL_DIR)/show/system/node.def
+.PHONY: component_versions
+.ONESHELL:
+component_versions: $(BUILD_DIR) $(obj)
+ $(CURDIR)/scripts/build-component-versions $(BUILD_DIR)/interface-definitions $(DATA_DIR)
+
.PHONY: all
-all: clean interface_definitions op_mode_definitions
+all: clean interface_definitions op_mode_definitions component_versions
.PHONY: clean
clean:
diff --git a/python/vyos/defaults.py b/python/vyos/defaults.py
index dedb929b4..a2ad142bc 100644
--- a/python/vyos/defaults.py
+++ b/python/vyos/defaults.py
@@ -29,6 +29,8 @@ cfg_vintage = 'vyatta'
commit_lock = '/opt/vyatta/config/.lock'
+version_file = '/usr/share/vyos/component-versions.json'
+
https_data = {
'listen_addresses' : { '*': ['_'] }
}
diff --git a/python/vyos/systemversions.py b/python/vyos/systemversions.py
index 9b3f4f413..5c4deca29 100644
--- a/python/vyos/systemversions.py
+++ b/python/vyos/systemversions.py
@@ -16,12 +16,15 @@
import os
import re
import sys
+import json
+
import vyos.defaults
def get_system_versions():
"""
- Get component versions from running system; critical failure if
- unable to read migration directory.
+ Get component versions from running system: read vyatta directory
+ structure for versions, then read vyos JSON file. It is a critical
+ error if either migration directory or JSON file is unreadable.
"""
system_versions = {}
@@ -36,4 +39,25 @@ def get_system_versions():
pair = info.split('@')
system_versions[pair[0]] = int(pair[1])
+ version_dict = {}
+ path = vyos.defaults.version_file
+
+ if os.path.isfile(path):
+ with open(path, 'r') as f:
+ try:
+ version_dict = json.load(f)
+ except ValueError as err:
+ print(f"\nValue error in {path}: {err}")
+ sys.exit(1)
+
+ for k, v in version_dict.items():
+ if not isinstance(v, int):
+ print(f"\nType error in {path}; expecting Dict[str, int]")
+ sys.exit(1)
+ existing = system_versions.get(k)
+ if existing is None:
+ system_versions[k] = v
+ elif v > existing:
+ system_versions[k] = v
+
return system_versions
diff --git a/schema/interface_definition.rnc b/schema/interface_definition.rnc
index 02175fec8..0ce8226cd 100644
--- a/schema/interface_definition.rnc
+++ b/schema/interface_definition.rnc
@@ -24,9 +24,16 @@
# Interface definition starts with interfaceDefinition tag that may contain node tags
start = element interfaceDefinition
{
+ syntaxVersion*,
node*
}
+# interfaceDefinition may contain syntax version attribute lists.
+syntaxVersion = element syntaxVersion
+{
+ (componentAttr & versionAttr)
+}
+
# node tag may contain node, leafNode, or tagNode tags
# Those are intermediate configuration nodes that may only contain
# other nodes and must not have values
@@ -97,6 +104,16 @@ properties = element properties
(element keepChildOrder { empty })?
}
+componentAttr = attribute component
+{
+ text
+}
+
+versionAttr = attribute version
+{
+ text
+}
+
# All nodes must have "name" attribute
nodeNameAttr = attribute name
{
diff --git a/schema/interface_definition.rng b/schema/interface_definition.rng
index 195ef27f4..bfd8d376f 100644
--- a/schema/interface_definition.rng
+++ b/schema/interface_definition.rng
@@ -29,10 +29,22 @@
<start>
<element name="interfaceDefinition">
<zeroOrMore>
+ <ref name="syntaxVersion"/>
+ </zeroOrMore>
+ <zeroOrMore>
<ref name="node"/>
</zeroOrMore>
</element>
</start>
+ <!-- interfaceDefinition may contain syntax version attribute lists. -->
+ <define name="syntaxVersion">
+ <element name="syntaxVersion">
+ <interleave>
+ <ref name="componentAttr"/>
+ <ref name="versionAttr"/>
+ </interleave>
+ </element>
+ </define>
<!--
node tag may contain node, leafNode, or tagNode tags
Those are intermediate configuration nodes that may only contain
@@ -184,6 +196,12 @@
</interleave>
</element>
</define>
+ <define name="componentAttr">
+ <attribute name="component"/>
+ </define>
+ <define name="versionAttr">
+ <attribute name="version"/>
+ </define>
<!-- All nodes must have "name" attribute -->
<define name="nodeNameAttr">
<attribute name="name"/>
diff --git a/scripts/build-command-templates b/scripts/build-command-templates
index 4fcdb8ade..dbf4ad9c5 100755
--- a/scripts/build-command-templates
+++ b/scripts/build-command-templates
@@ -295,4 +295,6 @@ root = xml.getroot()
nodes = root.iterfind("*")
for n in nodes:
+ if n.tag == "syntaxVersion":
+ continue
process_node(n, [output_dir])
diff --git a/scripts/build-component-versions b/scripts/build-component-versions
new file mode 100755
index 000000000..5362dbdd4
--- /dev/null
+++ b/scripts/build-component-versions
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+
+import sys
+import os
+import argparse
+import json
+
+from lxml import etree as ET
+
+parser = argparse.ArgumentParser()
+parser.add_argument('INPUT_DIR', type=str,
+ help="Directory containing XML interface definition files")
+parser.add_argument('OUTPUT_DIR', type=str,
+ help="Output directory for JSON file")
+
+args = parser.parse_args()
+
+input_dir = args.INPUT_DIR
+output_dir = args.OUTPUT_DIR
+
+version_dict = {}
+
+for filename in os.listdir(input_dir):
+ filepath = os.path.join(input_dir, filename)
+ print(filepath)
+ try:
+ xml = ET.parse(filepath)
+ except Exception as e:
+ print("Failed to load interface definition file {0}".format(filename))
+ print(e)
+ sys.exit(1)
+
+ root = xml.getroot()
+ version_data = root.iterfind("syntaxVersion")
+ for ver in version_data:
+ component = ver.get("component")
+ version = int(ver.get("version"))
+
+ v = version_dict.get(component)
+ if v is None:
+ version_dict[component] = version
+ elif version > v:
+ version_dict[component] = version
+
+out_file = os.path.join(output_dir, 'component-versions.json')
+with open(out_file, 'w') as f:
+ json.dump(version_dict, f, indent=4, sort_keys=True)