snapshot: Explicitly export Pathbuilders
This commit updates the 'wdcli snapshot' command to also export pathbuilders from the system.
This commit is contained in:
parent
477152814a
commit
c4de1f2a06
5 changed files with 125 additions and 6 deletions
|
|
@ -288,15 +288,16 @@ sudo /var/www/deploy/wdcli snapshot SLUG
|
||||||
sudo /var/www/deploy/wdcli snapshot SLUG /path/to/snapshot.tar.gz
|
sudo /var/www/deploy/wdcli snapshot SLUG /path/to/snapshot.tar.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
The backup proceeeds as follows:
|
The snapshot proceeeds as follows:
|
||||||
1. make a copy of the instance configuration
|
1. make a copy of the instance configuration
|
||||||
2. shutdown the running instance
|
2. shutdown the running instance
|
||||||
3. make a dump of the triplestore and mysql databases
|
3. make a dump of the triplestore and mysql databases
|
||||||
4. make a copy of the file system
|
4. make a copy of the file system
|
||||||
5. start the instance again
|
5. export all pathbuilders
|
||||||
6. package the data into the final `.tar.gz` file
|
6. start the instance again
|
||||||
|
7. package the data into the final `.tar.gz` file
|
||||||
|
|
||||||
When uptime is critical, it is possible to skip sets 2 and 5 and leave the instance running.
|
When uptime is critical, it is possible to skip shutting down a running instance.
|
||||||
This might result in inconsistent backup data.
|
This might result in inconsistent backup data.
|
||||||
To do so, run the script with the `--keepalive` flag:
|
To do so, run the script with the `--keepalive` flag:
|
||||||
|
|
||||||
|
|
|
||||||
2
TODO.md
2
TODO.md
|
|
@ -9,8 +9,6 @@
|
||||||
- Move `provision_entrypoint.sh` into go
|
- Move `provision_entrypoint.sh` into go
|
||||||
- Enhance Snapshots
|
- Enhance Snapshots
|
||||||
- Export the Docker Images
|
- Export the Docker Images
|
||||||
- Export the XML from the Pathbuilder
|
|
||||||
- Snapshot the docker images being used also!
|
|
||||||
- Avoid running `docker compose` executable and shift it to a library
|
- Avoid running `docker compose` executable and shift it to a library
|
||||||
- Cleanup code: Have consistent error handling
|
- Cleanup code: Have consistent error handling
|
||||||
- Add a metadata / statistics server
|
- Add a metadata / statistics server
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script will list all the URIs that this system is aware of.
|
||||||
|
* This works by listing all the default graph uris of all the adapters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Drupal\wisski_pathbuilder\Entity\WisskiPathEntity;
|
||||||
|
|
||||||
|
// load all the pathbuilders
|
||||||
|
$pbs = \Drupal::entityTypeManager()->getStorage('wisski_pathbuilder')->loadMultiple();
|
||||||
|
|
||||||
|
// map over the pathbuilders
|
||||||
|
$xmls = array_map(function($pb) {
|
||||||
|
$xml = new \SimpleXMLElement("<pathbuilderinterface></pathbuilderinterface>");
|
||||||
|
|
||||||
|
$paths = $pb->getAllPaths();
|
||||||
|
foreach ($paths as $key => $path) {
|
||||||
|
$id = $path->getID();
|
||||||
|
|
||||||
|
$path = $pb->getPbPath($id);
|
||||||
|
|
||||||
|
$pathChild = $xml->addChild("path");
|
||||||
|
$pathObject = WisskiPathEntity::load($id);
|
||||||
|
|
||||||
|
foreach ($path as $subkey => $value) {
|
||||||
|
|
||||||
|
if (in_array($subkey, ['relativepath'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($subkey == "parent") {
|
||||||
|
$subkey = "group_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
$pathChild->addChild($subkey, htmlspecialchars($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
$pathArray = $pathChild->addChild('path_array');
|
||||||
|
foreach ($pathObject->getPathArray() as $subkey => $value) {
|
||||||
|
$pathArray->addChild($subkey % 2 == 0 ? 'x' : 'y', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pathChild->addChild('datatype_property', htmlspecialchars($pathObject->getDatatypeProperty()));
|
||||||
|
$pathChild->addChild('short_name', htmlspecialchars($pathObject->getShortName()));
|
||||||
|
$pathChild->addChild('disamb', htmlspecialchars($pathObject->getDisamb()));
|
||||||
|
$pathChild->addChild('description', htmlspecialchars($pathObject->getDescription()));
|
||||||
|
$pathChild->addChild('uuid', htmlspecialchars($pathObject->uuid()));
|
||||||
|
if ($pathObject->getType() == "Group" || $pathObject->getType() == "Smartgroup") {
|
||||||
|
$pathChild->addChild('is_group', "1");
|
||||||
|
} else {
|
||||||
|
$pathChild->addChild('is_group', "0");
|
||||||
|
}
|
||||||
|
$pathChild->addChild('name', htmlspecialchars($pathObject->getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// turn it into XML
|
||||||
|
$dom = dom_import_simplexml($xml)->ownerDocument;
|
||||||
|
$dom->formatOutput = TRUE;
|
||||||
|
return $dom->saveXML();
|
||||||
|
}, $pbs);
|
||||||
|
|
||||||
|
echo json_encode($xmls);
|
||||||
38
env/instances.go
vendored
38
env/instances.go
vendored
|
|
@ -1,6 +1,8 @@
|
||||||
package env
|
package env
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
@ -16,6 +18,8 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tkw1536/goprogram/exit"
|
"github.com/tkw1536/goprogram/exit"
|
||||||
"github.com/tkw1536/goprogram/stream"
|
"github.com/tkw1536/goprogram/stream"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
@ -366,3 +370,37 @@ func (instance *Instance) PrefixConfig() (config string, err error) {
|
||||||
// and done!
|
// and done!
|
||||||
return builder.String(), nil
|
return builder.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errPathbuildersExecFailed = errors.New("ExportPathbuilders: Failed to call export_pathbuilder")
|
||||||
|
|
||||||
|
// ExportPathbuilders writes pathbuilders into the directory dest
|
||||||
|
func (instance *Instance) ExportPathbuilders(dest string) error {
|
||||||
|
// export all the pathbuilders into the buffer
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
wu := stream.NewIOStream(&buffer, nil, nil, 0)
|
||||||
|
code, err := instance.Stack().Exec(wu, "barrel", "/bin/bash", "/user_shell.sh", "-c", "drush php:script /wisskiutils/export_pathbuilder.php")
|
||||||
|
if err != nil || code != 0 {
|
||||||
|
return errPathbuildersExecFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode them as a json array
|
||||||
|
var pathbuilders map[string]string
|
||||||
|
if err := json.NewDecoder(&buffer).Decode(&pathbuilders); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort the names of the pathbuilders
|
||||||
|
names := maps.Keys(pathbuilders)
|
||||||
|
slices.Sort(names)
|
||||||
|
|
||||||
|
// write each into a file!
|
||||||
|
for _, name := range names {
|
||||||
|
pbxml := []byte(pathbuilders[name])
|
||||||
|
name := filepath.Join(dest, fmt.Sprintf("%s.xml", name))
|
||||||
|
if err := os.WriteFile(name, pbxml, fs.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
19
env/snapshot.go
vendored
19
env/snapshot.go
vendored
|
|
@ -86,6 +86,7 @@ type Snapshot struct {
|
||||||
ErrStop error
|
ErrStop error
|
||||||
|
|
||||||
ErrBookkeep error
|
ErrBookkeep error
|
||||||
|
ErrPathbuilder error
|
||||||
ErrFilesystem error
|
ErrFilesystem error
|
||||||
ErrTriplestore error
|
ErrTriplestore error
|
||||||
ErrSSQL error
|
ErrSSQL error
|
||||||
|
|
@ -145,6 +146,24 @@ func (snapshot *Snapshot) create(io stream.IOStream, instance Instance) {
|
||||||
_, snapshot.ErrBookkeep = fmt.Fprintf(info, "%#v\n", instance.Instance)
|
_, snapshot.ErrBookkeep = fmt.Fprintf(info, "%#v\n", instance.Instance)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
// write pathbuilders
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
pbPath := filepath.Join(snapshot.Description.Dest, "pathbuilders")
|
||||||
|
messages <- pbPath
|
||||||
|
|
||||||
|
// create the directory!
|
||||||
|
if err := os.Mkdir(pbPath, fs.ModeDir); err != nil {
|
||||||
|
snapshot.ErrPathbuilder = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// put in all the pathbuilders
|
||||||
|
snapshot.ErrPathbuilder = instance.ExportPathbuilders(pbPath)
|
||||||
|
}()
|
||||||
|
|
||||||
// backup the filesystem
|
// backup the filesystem
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue