czechlight-cfg-fs: migration scripts and tests

Sometimes we need to make alterations to the startup datastore (for
instance when new feature to the YANG model is added). This commit
introduces a migration script that is to be run after the machine boots.

The persistent /cfg now stores not just the data, but also the system
SW version which produced the stored configuration. Upon boot, the
current system looks at the previous config (the startup.json file
located at /cfg/sysrepo) and its associated system version
(/cfg/sysrepo/version), and if any changes need to happen, they are
automatically applied.

This commit introduces first migration.
This initial content makes sure that there's something (like a default
channel plan, or some mandatory YANG data nodes) when booting from
factory defaults (or from a pre-versioning SW release). Since this is a
one-shot operation, the operator is free to overwrite the data (e.g.,
rewrite the channel plan), and the system will happily accept the new data
as long as they pass the YANG validation. This is different from the
previous behavior of the SW stack which would apply the defaults during
each boot, even when the configuration was restored.

We also introduce tests for these migrations scripts. They are located
under tests/czechlight-cfg-fs directory and there is a pytest runner.
Each test case is a single directory containing current startup DS
content (as JSON file), expected content after running migrations,
and three control files: One for current startup DS version (so we know
which migrations to run), one for cmdline (so both scripts
czechlight-install-yang and czechlight-migrate can distinguish between
czechlight box types in code), and xpath file used only if we want to
check for a part of the sysrepo DS content.

The tests simulate the workflow that is done when the system boots.
I.e., they install YANG models, restore startup DS backup into sysrepo
and then they run the migrations if necessary.

Change-Id: I96191630fd6b3a1ffbc5ba9f62c4a6c14ab5ed92
diff --git a/ci/build.sh b/ci/build.sh
index d7a6ada..14e73bb 100755
--- a/ci/build.sh
+++ b/ci/build.sh
@@ -87,6 +87,8 @@
 make -j${CI_PARALLEL_JOBS} --output-sync=target rootfs-czechlight-rauc
 mv images/update.raucb ~/zuul-output/artifacts/
 
+PATH="$PATH:$(pwd)/host/bin/" pytest -vv ${ZUUL_PROJECT_SRC_DIR}/tests/czechlight-cfg-fs/migrations.py
+
 if [[ "${ZUUL_JOB_NAME}" =~ clearfog ]]; then
     if [[ ${TRIGGERED_VIA_DEP} != 1 ]]; then
         # store a cached tarball as an artifact