summaryrefslogtreecommitdiff
path: root/schema/parse.py
diff options
context:
space:
mode:
Diffstat (limited to 'schema/parse.py')
-rw-r--r--schema/parse.py210
1 files changed, 210 insertions, 0 deletions
diff --git a/schema/parse.py b/schema/parse.py
new file mode 100644
index 00000000..a118e70b
--- /dev/null
+++ b/schema/parse.py
@@ -0,0 +1,210 @@
+# Load Baserock Definitions serialisation format V5 into a SurfRDF 'store'.
+
+# https://github.com/cosminbasca/surfrdf
+
+
+import rdflib
+import surf
+import yaml
+
+import os
+import warnings
+
+
+surf.ns.register(baserock='http://baserock.org/definitions/example-schema#')
+
+
+def load_all_morphologies(session, store):
+ Chunk = session.get_class(surf.ns.BASEROCK.Chunk)
+ ChunkReference = session.get_class(surf.ns.BASEROCK.ChunkReference)
+ Stratum = session.get_class(surf.ns.BASEROCK.Stratum)
+ StratumArtifact = session.get_class(surf.ns.BASEROCK.StratumArtifact)
+ System = session.get_class(surf.ns.BASEROCK.System)
+ SystemDeployment = session.get_class(surf.ns.BASEROCK.SystemDeployment)
+ Cluster = session.get_class(surf.ns.BASEROCK.Cluster)
+
+ def load_morph(path):
+ try:
+ with open(path) as f:
+ text = f.read()
+ contents = yaml.safe_load(text)
+ morph_type = contents['kind']
+ assert 'name' in contents
+ assert contents['kind'] in ['cluster', 'system', 'stratum', 'chunk']
+ except Exception as e:
+ warnings.warn("Problem loading %s: %s" % (path, e))
+
+ # FIXME:
+ base_uri = 'http://example.com/'
+
+ entity = None
+
+ # Note the 'surf' library doesn't seem to do any kind of validity checking
+ # so you can insert whatever random data you feel like, if you want.
+
+ if contents['kind'] == 'chunk':
+ chunk_uri = base_uri + 'chunks/' + contents['name']
+ entity = chunk = Chunk(chunk_uri)
+
+ # FIXME: I think order is lost here !!!!!
+ if 'pre-configure-commands' in contents:
+ chunk.baserock_preConfigureCommands = contents['pre-configure-commands']
+ if 'configure-commands' in contents:
+ chunk.baserock_configureCommands = contents['configure-commands']
+ if 'post-configure-commands' in contents:
+ chunk.baserock_postConfigureCommands = contents['post-configure-commands']
+ if 'pre-build-commands' in contents:
+ chunk.baserock_preBuildCommands = contents['pre-build-commands']
+ if 'build-commands' in contents:
+ chunk.baserock_buildCommands = contents['build-commands']
+ if 'post-build-commands' in contents:
+ chunk.baserock_postBuildCommands = contents['post-build-commands']
+ if 'pre-install-commands' in contents:
+ chunk.baserock_preInstallCommands = contents['pre-install-commands']
+ if 'install-commands' in contents:
+ chunk.baserock_installCommands = contents['install-commands']
+ if 'post-install-commands' in contents:
+ chunk.baserock_postInstallCommands = contents['post-install-commands']
+
+ elif contents['kind'] == 'stratum':
+ stratum_uri = base_uri + 'strata/' + contents['name']
+ entity = stratum = Stratum(stratum_uri)
+
+ stratum_build_deps = []
+ for entry in contents.get('build-depends', []):
+ build_dep_uri = base_uri + 'strata/' + entry['morph']
+ stratum_build_deps.append(rdflib.URIRef(build_dep_uri))
+ stratum.baserock_hasBuildDependency = stratum_build_deps
+
+ artifacts = []
+ for entry in contents.get('products', []):
+ artifact_uri = stratum_uri + '/products/' + entry['artifact']
+ artifact = StratumArtifact(artifact_uri)
+ # FIXME: order probably lost here
+ if 'includes' in entry:
+ artifact.baserock_includes = entry['includes']
+ artifacts.append(artifact)
+ stratum.baserock_produces = artifacts
+
+ chunk_refs = []
+ for entry in contents.get('chunks', []):
+ chunk_ref_uri = stratum_uri + '/chunk-refs/' + entry['name']
+ chunk_ref = ChunkReference(chunk_ref_uri)
+
+ # FIXME: this ignores the 'morph' field, and assumes 'name' is
+ # usable as-is.
+ chunk_uri = base_uri + 'chunks/' + entry['name']
+ chunk_ref.baserock_refersToChunk = rdflib.URIRef(chunk_uri)
+
+ chunk_ref.baserock_repo = entry['repo']
+ chunk_ref.baserock_ref = entry['ref']
+ if 'unpetrify-ref' in entry:
+ chunk_ref.baserock_unpetrifyRef = entry['unpetrify-ref']
+ chunk_ref.baserock_buildMode = entry.get('build-mode', 'normal')
+ chunk_ref.baserock_prefix = entry.get('prefix', '/usr')
+
+ chunk_ref_build_deps = []
+ for entry_dep in entry.get('build-depends', []):
+ build_dep_uri = stratum_uri + '/chunk-refs/' + entry_dep
+ chunk_ref_build_deps.append(build_dep_uri)
+ chunk_ref.baserock_hasChunkBuildDependency = chunk_ref_build_deps
+
+ chunk_refs.append(chunk_ref)
+
+ stratum.baserock_containsChunkReference = chunk_refs
+
+ elif contents['kind'] == 'system':
+ system_uri = base_uri + 'systems/' + contents['name']
+ entity = system = System(system_uri)
+
+ system.baserock_arch = contents['arch']
+
+ stratum_artifacts = []
+ for entry in contents.get('strata', []):
+ # FIXME: need to include all strata if 'artifacts' isn't specified,
+ # which is difficult becausee they might not all be loaded yet ...
+ # so for now I cheat and just assume -runtime and -devel. If there
+ # are extra artifacts for the stratum they won't be incuded by
+ # default. I'm not sure if this is how Morph behaves or not.
+ artifacts = entry.get('artifacts')
+ if artifacts is None:
+ artifacts = ['%s-runtime' % entry['name'],
+ '%s-devel' % entry['name']]
+ for artifact in artifacts:
+ artifact_uri = (base_uri + '/strata/' + entry['name'] +
+ '/products/' + artifact)
+ stratum_artifacts.append(artifact_uri)
+ system.baserock_containsStratumArtifact = stratum_artifacts
+
+ system.baserock_hasConfigurationExtension = \
+ contents.get('configuration-extensions', [])
+
+ elif contents['kind'] == 'cluster':
+ cluster_uri = base_uri + 'clusters/' + contents['name']
+ entity = cluster = Cluster(cluster_uri)
+
+ deployments = []
+ for entry in contents.get('systems', []):
+ # FIXME: can't get the URI from the 'morph' entry... need to load
+ # the actual .morph file and get the name from there.
+ system_uri = 'http://FIXME'
+
+ # FIXME: ignores deploy-defaults at present
+ for label, details in entry['deploy'].items():
+ deployment_uri = cluster_uri + '/' + label
+ deployment = SystemDeployment(deployment_uri)
+
+ deployment.baserock_deploysSystem = rdflib.URIRef(system_uri)
+ deployment.baserock_hasLabel = label
+
+ deployment.baserock_hasType = details['type']
+ deployment.baserock_hasLocation = details['location']
+
+ settings = []
+ for key, value in details.items():
+ if key in ['type', 'location']:
+ continue
+ # FIXME: RDF must have a way of representing arbitrary
+ # key/values better than using a string with an = sign...
+ settings.append('%s=%s' % (key,value))
+ deployment.baserock_hasConfigurationSetting = settings
+ deployments.append(deployment)
+
+ cluster.baserock_deploysSystem = deployments
+
+ if 'description' in contents:
+ entity.baserock_description = contents['description']
+
+ # FIXME: is this needed? why?
+ entity.set_dirty(True)
+ # FIXME: comments from the .yaml file are lost ... as a quick solution,
+ # you could manually find every line from the YAML that starts with a '#'
+ # and dump that into a property.
+
+ print 'Parsing .morph files...'
+ for dirname, dirnames, filenames in os.walk('..'):
+ if '.git' in dirnames:
+ dirnames.remove('.git')
+ for filename in sorted(filenames):
+ if filename.endswith('.morph'):
+ load_morph(os.path.join(dirname, filename))
+
+ print 'Committing to database...'
+ try:
+ session.commit()
+ except Exception as e:
+ if DATABASE=='virtuoso' and \
+ 'Virtuoso 42000 Error SR186: No permission to execute procedure DB' in e.message:
+ print("Permission denied trying to update the database via the "
+ "SPARQL endpoint. By default this endpoint is read-only. "
+ "To enable write access, run the `isql` or `isql-vt` "
+ "commandline interface and run the following statement:\n\n"
+ " grant SPARQL_UPDATE to \"SPARQL\";\n\n"
+ "WARNING! Only do this if you're using a local test instance "
+ "of Virtuoso. You need to set up a real authenticated user "
+ "account if using an instance of Virtuoso that has "
+ "important data on it.")
+ else:
+ raise
+
+ store.save()