diff --git a/builders/lando-v4.js b/builders/lando-v4.js index 6d86d376b..71cd2e328 100644 --- a/builders/lando-v4.js +++ b/builders/lando-v4.js @@ -281,6 +281,7 @@ module.exports = { ...require('../utils/normalize-storage')(config.storage, this), ...require('../utils/normalize-storage')(config['persistent-storage'], this), ]; + this.volumes = config.volumes; // top level stuff @@ -452,20 +453,22 @@ module.exports = { // create storage if needed // @TODO: should this be in try block below? if (this.storage.filter(volume => volume.type === 'volume').length > 0) { - const bengine = this.getBengine(); // get existing volumes - const estorage = (await this.getStorageVolumes()).map(volume => volume.source); + const estorage = (await this.getStorageVolumes()).map(volume => volume.id); - // find any volumes we might need to create + // find any service level volumes we might need to create + // @TODO: note that app/project/global storage is created at the app level and not here const cstorage = this.storage .filter(volume => volume.type === 'volume') - .filter(volume => !estorage.includes(volume.source)) + .filter(volume => !estorage.includes(volume.id)) + .filter(volume => volume.scope === 'service') .filter(volume => volume?.labels?.['dev.lando.storage-volume'] === 'TRUE'); await Promise.all(cstorage.map(async volume => { + const bengine = this.getBengine(); try { await bengine.createVolume({Name: volume.source, Labels: volume.labels}); - this.debug('created %o storage volume %o with metadata %o', volume.scope, volume.source, volume.labels); + this.debug('created service storage volume %o with metadata %o', volume.id, volume.labels); } catch (error) { throw error; } diff --git a/examples/storage/README.md b/examples/storage/README.md index e152e0a37..daed23c59 100644 --- a/examples/storage/README.md +++ b/examples/storage/README.md @@ -40,7 +40,7 @@ docker volume inspect lando-everywhere | grep "dev.lando.storage-scope" | grep g docker volume inspect lando-everywhere | grep "dev.lando.storage-project" || echo "$?" | grep 1 docker volume inspect lando-everywhere | grep "dev.lando.storage-service" || echo "$?" | grep 1 docker volume inspect landostorage-stuff | grep "dev.lando.storage-volume" | grep TRUE -docker volume inspect landostorage-stuff | grep "dev.lando.storage-scope" | grep -E "app|project" || docker volume inspect landostorage-stuff | grep "dev.lando.storage-scope" +docker volume inspect landostorage-stuff | grep "dev.lando.storage-scope" | grep app docker volume inspect landostorage-stuff | grep "dev.lando.storage-project" | grep landostorage docker volume inspect landostorage-stuff | grep "dev.lando.storage-service" | grep db docker volume inspect landostorage-alpine-some-cache-directory | grep "dev.lando.storage-volume" | grep TRUE diff --git a/hooks/app-run-v4-build-app.js b/hooks/app-run-v4-build-app.js index 3f6072e6a..d8de425d2 100644 --- a/hooks/app-run-v4-build-app.js +++ b/hooks/app-run-v4-build-app.js @@ -17,9 +17,42 @@ module.exports = async app => { .filter(service => service?.info?.state?.APP !== 'BUILT') .value(); - app.log.debug('going to build v4 apps', services.map(service => service.id)); + // start by getting existing storage + const estorage = _(await Promise.all(services.map(async service => await service.getStorageVolumes()))) + .flatten() + .filter(volume => volume !== 'service') + .uniqBy('id') + .map(volume => volume.id) + .value(); + app.log.debug('found existing non-service scoped storage volumes %o', estorage); + + // and then new storage that needs to be created + const cstorage = _(services) + .map(service => service.storage) + .flatten() + .filter(volume => volume.type === 'volume') + .filter(volume => !estorage.includes(volume.id)) + .filter(volume => volume.scope !== 'service') + .filter(volume => volume?.labels?.['dev.lando.storage-volume'] === 'TRUE') + .groupBy('target') + .map(group => group[0]) + .value(); + app.log.debug('missing storage volumes %o', cstorage.map(volume => volume.source)); + + // create any missing volumes + await Promise.all(cstorage.map(async volume => { + // if this iterates is it gauranteed that the below will always work? + const bengine = services[0].getBengine(); + try { + await bengine.createVolume({Name: volume.source, Labels: volume.labels}); + app.log.debug('created %o storage volume %o with metadata %o', volume.scope, volume.source, volume.labels); + } catch (error) { + throw error; + } + })); - // and then run them in parallel + // run all build services methods + app.log.debug('going to build v4 services', services.map(service => service.id)); await Promise.all(services.map(async service => { try { await service.buildApp();