Merge branch 'tmessi-migration-editions'
This commit is contained in:
153 files changed
+3853
-11411
No files matched your search
Generated
+88
-88
@@ -30,49 +30,49 @@ jobs:
|
||||
command: mkdir -p .buildcache && echo "*" > .buildcache/.gitignore
|
||||
name: Ignore .buildcache
|
||||
- restore_cache:
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: make package-meta-all
|
||||
@@ -84,20 +84,20 @@ jobs:
|
||||
command: ls -lahR .buildcache
|
||||
name: List Build Cache
|
||||
- run:
|
||||
command: cp packages*.lock/pkgs.yml lockfile-645fb387fb0a87de.yml
|
||||
command: cp packages*.lock/pkgs.yml lockfile-84a71f97438578ee.yml
|
||||
name: Update Lockfile Name
|
||||
- run:
|
||||
command: tar -czf packages-645fb387fb0a87de.tar.gz .buildcache/packages lockfile-645fb387fb0a87de.yml
|
||||
command: tar -czf packages-84a71f97438578ee.tar.gz .buildcache/packages lockfile-84a71f97438578ee.yml
|
||||
name: Create Raw Package Tarball
|
||||
- run:
|
||||
command: tar -czf meta-645fb387fb0a87de.tar.gz .buildcache/packages/store/*.json lockfile-645fb387fb0a87de.yml
|
||||
command: tar -czf meta-84a71f97438578ee.tar.gz .buildcache/packages/store/*.json lockfile-84a71f97438578ee.yml
|
||||
name: Create Metadata Tarball
|
||||
- store_artifacts:
|
||||
path: lockfile-645fb387fb0a87de.yml
|
||||
path: lockfile-84a71f97438578ee.yml
|
||||
- store_artifacts:
|
||||
path: packages-645fb387fb0a87de.tar.gz
|
||||
path: packages-84a71f97438578ee.tar.gz
|
||||
- store_artifacts:
|
||||
path: meta-645fb387fb0a87de.tar.gz
|
||||
path: meta-84a71f97438578ee.tar.gz
|
||||
- store_artifacts:
|
||||
path: .buildcache/packages
|
||||
environment:
|
||||
@@ -112,7 +112,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 2bb9488232c945d6800cc3a4a461d9b17503bccc
|
||||
- PACKAGE_SPEC_ID: 9801fb26ed9eb42980684234791a85a8d16c2713
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -172,7 +172,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -184,7 +184,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 44f600485ac3823fa4e0dbba45763d932187225a
|
||||
- PACKAGE_SPEC_ID: c380c1e5206b2d02d9603a8cc068933436e05eb0
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -198,7 +198,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -214,7 +214,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -244,7 +244,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -274,14 +274,14 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
- base_2017_{{checksum ".buildcache/cache-keys/base-2017dceda969e0eab6fd00cab602c9a05538de9c"}}
|
||||
name: 'Restore Layer Cache: copy-source'
|
||||
- run:
|
||||
command: LAYER_SPEC_ID=03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7 make -C packages*.lock load-builder-cache
|
||||
command: LAYER_SPEC_ID=03-copy-source-e59a64ba925a852a09535a8d252147336d635eff make -C packages*.lock load-builder-cache
|
||||
name: Load whatever builder cache we have (if any) into the Docker daemon
|
||||
- run:
|
||||
command: |2-
|
||||
@@ -345,7 +345,7 @@ jobs:
|
||||
echo " attempts to directly clone private repositories."
|
||||
fi
|
||||
|
||||
make -f packages*.lock/layer.mk 03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7-image
|
||||
make -f packages*.lock/layer.mk 03-copy-source-e59a64ba925a852a09535a8d252147336d635eff-image
|
||||
name: Build copy-source layer
|
||||
- run:
|
||||
command: |2-
|
||||
@@ -361,13 +361,13 @@ jobs:
|
||||
echo " attempts to directly clone private repositories."
|
||||
fi
|
||||
|
||||
make -f packages*.lock/layer.mk 03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7-save
|
||||
make -f packages*.lock/layer.mk 03-copy-source-e59a64ba925a852a09535a8d252147336d635eff-save
|
||||
name: Build copy-source layer
|
||||
- save_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
name: 'Save Layer Cache: copy-source'
|
||||
paths:
|
||||
- .buildcache/archives/03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7.tar.gz
|
||||
- .buildcache/archives/03-copy-source-e59a64ba925a852a09535a8d252147336d635eff.tar.gz
|
||||
environment:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
@@ -380,7 +380,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 7f1216479517d6c6122fd8928ff44c046eb3a377
|
||||
- PACKAGE_SPEC_ID: d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -394,7 +394,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -410,7 +410,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -440,7 +440,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -452,7 +452,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: ab3b6922ce2bd0fab200dddd6127544427b89fef
|
||||
- PACKAGE_SPEC_ID: dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -466,7 +466,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -482,7 +482,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -512,7 +512,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -535,7 +535,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a
|
||||
- PACKAGE_SPEC_ID: 701ab62817cc79f8ec83299cefac126cb3c74d47
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -549,7 +549,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -565,7 +565,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -595,7 +595,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -607,7 +607,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: e9f9d34c2c14f59f68c31469b7bfa994074a48c2
|
||||
- PACKAGE_SPEC_ID: c6687b4dfea47101b46520e0809c4e4135a9a3b8
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -621,7 +621,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -637,7 +637,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -667,7 +667,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -679,7 +679,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 3e2a1075872eae7608bf8be4b74f7291ca88d5b5
|
||||
- PACKAGE_SPEC_ID: 3d40792896ab78cd0e160df4bbd1c757c63cf985
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -693,7 +693,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -709,7 +709,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -739,7 +739,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -751,7 +751,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: b0201f2d2d1b04f519e0d091fbe23997252c5f70
|
||||
- PACKAGE_SPEC_ID: 053de88ba7c9c7d3d7021774a040b4dba0edb1d3
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -765,7 +765,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -781,7 +781,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -811,7 +811,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -823,7 +823,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 03d32b4b7349ceac506ca889be4772fe8239ecd8
|
||||
- PACKAGE_SPEC_ID: 524f6510ca269c805e992fa740ae8cd26db1b091
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -837,7 +837,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -853,7 +853,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -883,7 +883,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -906,7 +906,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 19efae459acdaea98d804c26c554640ab3544553
|
||||
- PACKAGE_SPEC_ID: 6d1801298f017e462e056af69b69e5b2f5fd2143
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -920,7 +920,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -936,7 +936,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -966,7 +966,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1128,7 +1128,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8
|
||||
- PACKAGE_SPEC_ID: 0b0af5839c026648f6a9bee77d6769df9b76fd6c
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -1142,7 +1142,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1158,7 +1158,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1188,7 +1188,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1200,7 +1200,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 51ea70d1d613481fac829f239f1f081c5ad6c88b
|
||||
- PACKAGE_SPEC_ID: 34a4409cf043f4e9aedbb4ae8e68db90fa0552a0
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -1214,7 +1214,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1230,7 +1230,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1260,7 +1260,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1272,7 +1272,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 7fae91402a49def23c2453fe147c262f1377eac3
|
||||
- PACKAGE_SPEC_ID: 15db6440776ae92411d314100f394e7d59eb54dc
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -1286,7 +1286,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1302,7 +1302,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1332,7 +1332,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1344,7 +1344,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: 822b1aa9954becb7a9cb480784ff9f99783a8d23
|
||||
- PACKAGE_SPEC_ID: fb9d5eb085b094774ff0f514490c9b8a5da28e24
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -1358,7 +1358,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1374,7 +1374,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1404,7 +1404,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1416,7 +1416,7 @@ jobs:
|
||||
- AUTO_INSTALL_TOOLS: 'YES'
|
||||
- BUILDKIT_PROGRESS: plain
|
||||
- PRODUCT_REVISION: ''
|
||||
- PACKAGE_SPEC_ID: d10bc84044e1ad705f48cd51591b05ee5e1e7dd5
|
||||
- PACKAGE_SPEC_ID: 1df2a38d32be613f8179c22ffd0bf03c68f1a16d
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: false
|
||||
@@ -1430,7 +1430,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1446,7 +1446,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1476,7 +1476,7 @@ jobs:
|
||||
command: ls -lahR .buildcache/packages
|
||||
name: List packages
|
||||
- save_cache:
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Save package cache
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
@@ -1492,7 +1492,7 @@ jobs:
|
||||
make test-sql POSTGRES_DOCKER_IMAGE_BASE=docker.mirror.hashicorp.services/postgres PG_DOCKER_TAG=latest
|
||||
name: Run SQL PgTap Tests
|
||||
workflows:
|
||||
build-645fb387fb0a87de:
|
||||
build-84a71f97438578ee:
|
||||
jobs:
|
||||
- build-common-layers
|
||||
- darwin_amd64_package:
|
||||
|
||||
@@ -30,14 +30,14 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
- base_2017_{{checksum ".buildcache/cache-keys/base-2017dceda969e0eab6fd00cab602c9a05538de9c"}}
|
||||
name: 'Restore Layer Cache: copy-source'
|
||||
- run:
|
||||
command: LAYER_SPEC_ID=03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7 make -C packages*.lock load-builder-cache
|
||||
command: LAYER_SPEC_ID=03-copy-source-e59a64ba925a852a09535a8d252147336d635eff make -C packages*.lock load-builder-cache
|
||||
name: Load whatever builder cache we have (if any) into the Docker daemon
|
||||
- run:
|
||||
command: |2-
|
||||
@@ -101,7 +101,7 @@ jobs:
|
||||
echo " attempts to directly clone private repositories."
|
||||
fi
|
||||
|
||||
make -f packages*.lock/layer.mk 03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7-image
|
||||
make -f packages*.lock/layer.mk 03-copy-source-e59a64ba925a852a09535a8d252147336d635eff-image
|
||||
name: Build copy-source layer
|
||||
- run:
|
||||
command: |2-
|
||||
@@ -117,12 +117,12 @@ jobs:
|
||||
echo " attempts to directly clone private repositories."
|
||||
fi
|
||||
|
||||
make -f packages*.lock/layer.mk 03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7-save
|
||||
make -f packages*.lock/layer.mk 03-copy-source-e59a64ba925a852a09535a8d252147336d635eff-save
|
||||
name: Build copy-source layer
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/archives/03-copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7.tar.gz
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
- .buildcache/archives/03-copy-source-e59a64ba925a852a09535a8d252147336d635eff.tar.gz
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
name: 'Save Layer Cache: copy-source'
|
||||
bundle-releases:
|
||||
executor: builder
|
||||
@@ -136,49 +136,49 @@ jobs:
|
||||
command: mkdir -p .buildcache && echo "*" > .buildcache/.gitignore
|
||||
name: Ignore .buildcache
|
||||
- restore_cache:
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Restore package cache
|
||||
- restore_cache:
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: make package-meta-all
|
||||
@@ -190,20 +190,20 @@ jobs:
|
||||
command: ls -lahR .buildcache
|
||||
name: List Build Cache
|
||||
- run:
|
||||
command: cp packages*.lock/pkgs.yml lockfile-645fb387fb0a87de.yml
|
||||
command: cp packages*.lock/pkgs.yml lockfile-84a71f97438578ee.yml
|
||||
name: Update Lockfile Name
|
||||
- run:
|
||||
command: tar -czf packages-645fb387fb0a87de.tar.gz .buildcache/packages lockfile-645fb387fb0a87de.yml
|
||||
command: tar -czf packages-84a71f97438578ee.tar.gz .buildcache/packages lockfile-84a71f97438578ee.yml
|
||||
name: Create Raw Package Tarball
|
||||
- run:
|
||||
command: tar -czf meta-645fb387fb0a87de.tar.gz .buildcache/packages/store/*.json lockfile-645fb387fb0a87de.yml
|
||||
command: tar -czf meta-84a71f97438578ee.tar.gz .buildcache/packages/store/*.json lockfile-84a71f97438578ee.yml
|
||||
name: Create Metadata Tarball
|
||||
- store_artifacts:
|
||||
path: lockfile-645fb387fb0a87de.yml
|
||||
path: lockfile-84a71f97438578ee.yml
|
||||
- store_artifacts:
|
||||
path: packages-645fb387fb0a87de.tar.gz
|
||||
path: packages-84a71f97438578ee.tar.gz
|
||||
- store_artifacts:
|
||||
path: meta-645fb387fb0a87de.tar.gz
|
||||
path: meta-84a71f97438578ee.tar.gz
|
||||
- store_artifacts:
|
||||
path: .buildcache/packages
|
||||
darwin_amd64_package:
|
||||
@@ -221,7 +221,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -237,7 +237,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -269,10 +269,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-2bb9488232c945d6800cc3a4a461d9b17503bccc-{{checksum ".buildcache/cache-keys/package-2bb9488232c945d6800cc3a4a461d9b17503bccc"}}
|
||||
key: package-9801fb26ed9eb42980684234791a85a8d16c2713-{{checksum ".buildcache/cache-keys/package-9801fb26ed9eb42980684234791a85a8d16c2713"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 2bb9488232c945d6800cc3a4a461d9b17503bccc
|
||||
PACKAGE_SPEC_ID: 9801fb26ed9eb42980684234791a85a8d16c2713
|
||||
freebsd_386_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -288,7 +288,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -304,7 +304,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -336,10 +336,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2-{{checksum ".buildcache/cache-keys/package-e9f9d34c2c14f59f68c31469b7bfa994074a48c2"}}
|
||||
key: package-c6687b4dfea47101b46520e0809c4e4135a9a3b8-{{checksum ".buildcache/cache-keys/package-c6687b4dfea47101b46520e0809c4e4135a9a3b8"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: e9f9d34c2c14f59f68c31469b7bfa994074a48c2
|
||||
PACKAGE_SPEC_ID: c6687b4dfea47101b46520e0809c4e4135a9a3b8
|
||||
freebsd_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -355,7 +355,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -371,7 +371,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -403,10 +403,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5-{{checksum ".buildcache/cache-keys/package-3e2a1075872eae7608bf8be4b74f7291ca88d5b5"}}
|
||||
key: package-3d40792896ab78cd0e160df4bbd1c757c63cf985-{{checksum ".buildcache/cache-keys/package-3d40792896ab78cd0e160df4bbd1c757c63cf985"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 3e2a1075872eae7608bf8be4b74f7291ca88d5b5
|
||||
PACKAGE_SPEC_ID: 3d40792896ab78cd0e160df4bbd1c757c63cf985
|
||||
freebsd_arm_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -422,7 +422,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -438,7 +438,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -470,10 +470,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-822b1aa9954becb7a9cb480784ff9f99783a8d23-{{checksum ".buildcache/cache-keys/package-822b1aa9954becb7a9cb480784ff9f99783a8d23"}}
|
||||
key: package-fb9d5eb085b094774ff0f514490c9b8a5da28e24-{{checksum ".buildcache/cache-keys/package-fb9d5eb085b094774ff0f514490c9b8a5da28e24"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 822b1aa9954becb7a9cb480784ff9f99783a8d23
|
||||
PACKAGE_SPEC_ID: fb9d5eb085b094774ff0f514490c9b8a5da28e24
|
||||
linux_386_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -489,7 +489,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -505,7 +505,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -537,10 +537,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a-{{checksum ".buildcache/cache-keys/package-7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a"}}
|
||||
key: package-701ab62817cc79f8ec83299cefac126cb3c74d47-{{checksum ".buildcache/cache-keys/package-701ab62817cc79f8ec83299cefac126cb3c74d47"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 7fd6bd8ba41907a8ad8d09a9ed3c43fb94801f2a
|
||||
PACKAGE_SPEC_ID: 701ab62817cc79f8ec83299cefac126cb3c74d47
|
||||
linux_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -556,7 +556,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -572,7 +572,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -604,10 +604,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-03d32b4b7349ceac506ca889be4772fe8239ecd8-{{checksum ".buildcache/cache-keys/package-03d32b4b7349ceac506ca889be4772fe8239ecd8"}}
|
||||
key: package-524f6510ca269c805e992fa740ae8cd26db1b091-{{checksum ".buildcache/cache-keys/package-524f6510ca269c805e992fa740ae8cd26db1b091"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 03d32b4b7349ceac506ca889be4772fe8239ecd8
|
||||
PACKAGE_SPEC_ID: 524f6510ca269c805e992fa740ae8cd26db1b091
|
||||
linux_arm_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -623,7 +623,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -639,7 +639,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -671,10 +671,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-ab3b6922ce2bd0fab200dddd6127544427b89fef-{{checksum ".buildcache/cache-keys/package-ab3b6922ce2bd0fab200dddd6127544427b89fef"}}
|
||||
key: package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175-{{checksum ".buildcache/cache-keys/package-dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: ab3b6922ce2bd0fab200dddd6127544427b89fef
|
||||
PACKAGE_SPEC_ID: dc756c7b14fbf4ade5d1b63f03d2ca186f5eb175
|
||||
linux_arm64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -690,7 +690,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -706,7 +706,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -738,10 +738,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-7f1216479517d6c6122fd8928ff44c046eb3a377-{{checksum ".buildcache/cache-keys/package-7f1216479517d6c6122fd8928ff44c046eb3a377"}}
|
||||
key: package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2-{{checksum ".buildcache/cache-keys/package-d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 7f1216479517d6c6122fd8928ff44c046eb3a377
|
||||
PACKAGE_SPEC_ID: d0d49ef910d2c6f6556cd3e86b36936b0d7c2ac2
|
||||
netbsd_386_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -757,7 +757,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -773,7 +773,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -805,10 +805,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-7fae91402a49def23c2453fe147c262f1377eac3-{{checksum ".buildcache/cache-keys/package-7fae91402a49def23c2453fe147c262f1377eac3"}}
|
||||
key: package-15db6440776ae92411d314100f394e7d59eb54dc-{{checksum ".buildcache/cache-keys/package-15db6440776ae92411d314100f394e7d59eb54dc"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 7fae91402a49def23c2453fe147c262f1377eac3
|
||||
PACKAGE_SPEC_ID: 15db6440776ae92411d314100f394e7d59eb54dc
|
||||
netbsd_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -824,7 +824,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -840,7 +840,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -872,10 +872,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8-{{checksum ".buildcache/cache-keys/package-c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8"}}
|
||||
key: package-0b0af5839c026648f6a9bee77d6769df9b76fd6c-{{checksum ".buildcache/cache-keys/package-0b0af5839c026648f6a9bee77d6769df9b76fd6c"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: c9b8b9c5b6a1ab2f53599efe3792f7ebbd43a6b8
|
||||
PACKAGE_SPEC_ID: 0b0af5839c026648f6a9bee77d6769df9b76fd6c
|
||||
openbsd_386_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -891,7 +891,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -907,7 +907,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -939,10 +939,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-b0201f2d2d1b04f519e0d091fbe23997252c5f70-{{checksum ".buildcache/cache-keys/package-b0201f2d2d1b04f519e0d091fbe23997252c5f70"}}
|
||||
key: package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3-{{checksum ".buildcache/cache-keys/package-053de88ba7c9c7d3d7021774a040b4dba0edb1d3"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: b0201f2d2d1b04f519e0d091fbe23997252c5f70
|
||||
PACKAGE_SPEC_ID: 053de88ba7c9c7d3d7021774a040b4dba0edb1d3
|
||||
openbsd_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -958,7 +958,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -974,7 +974,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1006,10 +1006,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-51ea70d1d613481fac829f239f1f081c5ad6c88b-{{checksum ".buildcache/cache-keys/package-51ea70d1d613481fac829f239f1f081c5ad6c88b"}}
|
||||
key: package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0-{{checksum ".buildcache/cache-keys/package-34a4409cf043f4e9aedbb4ae8e68db90fa0552a0"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 51ea70d1d613481fac829f239f1f081c5ad6c88b
|
||||
PACKAGE_SPEC_ID: 34a4409cf043f4e9aedbb4ae8e68db90fa0552a0
|
||||
solaris_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -1025,7 +1025,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1041,7 +1041,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1073,10 +1073,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-19efae459acdaea98d804c26c554640ab3544553-{{checksum ".buildcache/cache-keys/package-19efae459acdaea98d804c26c554640ab3544553"}}
|
||||
key: package-6d1801298f017e462e056af69b69e5b2f5fd2143-{{checksum ".buildcache/cache-keys/package-6d1801298f017e462e056af69b69e5b2f5fd2143"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 19efae459acdaea98d804c26c554640ab3544553
|
||||
PACKAGE_SPEC_ID: 6d1801298f017e462e056af69b69e5b2f5fd2143
|
||||
windows_386_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -1092,7 +1092,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1108,7 +1108,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1140,10 +1140,10 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-44f600485ac3823fa4e0dbba45763d932187225a-{{checksum ".buildcache/cache-keys/package-44f600485ac3823fa4e0dbba45763d932187225a"}}
|
||||
key: package-c380c1e5206b2d02d9603a8cc068933436e05eb0-{{checksum ".buildcache/cache-keys/package-c380c1e5206b2d02d9603a8cc068933436e05eb0"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: 44f600485ac3823fa4e0dbba45763d932187225a
|
||||
PACKAGE_SPEC_ID: c380c1e5206b2d02d9603a8cc068933436e05eb0
|
||||
windows_amd64_package:
|
||||
executor: builder
|
||||
steps:
|
||||
@@ -1159,7 +1159,7 @@ jobs:
|
||||
command: make -C packages*.lock write-package-cache-key
|
||||
name: Write package cache key
|
||||
- restore_cache:
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Restore package cache
|
||||
- run:
|
||||
command: |2
|
||||
@@ -1175,7 +1175,7 @@ jobs:
|
||||
command: make -C packages*.lock write-builder-cache-keys
|
||||
name: Write builder layer cache keys
|
||||
- restore_cache:
|
||||
key: copy-source_5f13_{{checksum ".buildcache/cache-keys/copy-source-5f13b2247825f6b1ba38bb75dd62a7a15469efe7"}}
|
||||
key: copy-source_e59a_{{checksum ".buildcache/cache-keys/copy-source-e59a64ba925a852a09535a8d252147336d635eff"}}
|
||||
keys:
|
||||
- go-modules_0542_{{checksum ".buildcache/cache-keys/go-modules-0542ebe70aa49ea525c7cd85313d5ba08f90441e"}}
|
||||
- ui_f43e_{{checksum ".buildcache/cache-keys/ui-f43e20c1d27527cddb9fa2f5a08420e5058396f1"}}
|
||||
@@ -1207,12 +1207,12 @@ jobs:
|
||||
- save_cache:
|
||||
paths:
|
||||
- .buildcache/packages/store
|
||||
key: package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5-{{checksum ".buildcache/cache-keys/package-d10bc84044e1ad705f48cd51591b05ee5e1e7dd5"}}
|
||||
key: package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d-{{checksum ".buildcache/cache-keys/package-1df2a38d32be613f8179c22ffd0bf03c68f1a16d"}}
|
||||
name: Save package cache
|
||||
environment:
|
||||
PACKAGE_SPEC_ID: d10bc84044e1ad705f48cd51591b05ee5e1e7dd5
|
||||
PACKAGE_SPEC_ID: 1df2a38d32be613f8179c22ffd0bf03c68f1a16d
|
||||
workflows:
|
||||
build-645fb387fb0a87de:
|
||||
build-84a71f97438578ee:
|
||||
jobs:
|
||||
- build-common-layers: {}
|
||||
- darwin_amd64_package:
|
||||
|
||||
@@ -77,10 +77,7 @@ endif
|
||||
perms-table:
|
||||
@go run internal/website/permstable/permstable.go
|
||||
|
||||
gen: cleangen proto api cli migrations perms-table fmt
|
||||
|
||||
migrations:
|
||||
$(MAKE) --environment-overrides -C internal/db/schema/migrations/generate migrations
|
||||
gen: cleangen proto api cli perms-table fmt
|
||||
|
||||
### oplog requires protoc-gen-go v1.20.0 or later
|
||||
# GO111MODULE=on go get -u github.com/golang/protobuf/protoc-gen-go@v1.40
|
||||
@@ -221,7 +218,7 @@ docker-publish:
|
||||
docker push $(IMAGE_TAG)
|
||||
docker push hashicorp/boundary:latest
|
||||
|
||||
.PHONY: api cli tools gen migrations proto website ci-config ci-verify set-ui-version docker docker-build docker-build-dev docker-publish test-database-up test-database-down
|
||||
.PHONY: api cli tools gen proto website ci-config ci-verify set-ui-version docker docker-build docker-build-dev docker-publish test-database-up test-database-down
|
||||
|
||||
.NOTPARALLEL:
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func (b *Server) CreateDevDatabase(ctx context.Context, opt ...Option) error {
|
||||
}
|
||||
|
||||
// Let migrate store manage the dirty bit since dev DBs should be ephemeral anyways.
|
||||
_, err := schema.MigrateStore(ctx, dialect, url)
|
||||
_, err := schema.MigrateStore(ctx, schema.Dialect(dialect), url)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("unable to initialize dev database with dialect %s: %w", dialect, err)
|
||||
if c != nil {
|
||||
@@ -78,7 +78,7 @@ func (b *Server) CreateDevDatabase(ctx context.Context, opt ...Option) error {
|
||||
b.DatabaseUrl = url
|
||||
default:
|
||||
// Let migrate store manage the dirty bit since dev DBs should be ephemeral anyways.
|
||||
if _, err := schema.MigrateStore(ctx, dialect, b.DatabaseUrl); err != nil {
|
||||
if _, err := schema.MigrateStore(ctx, schema.Dialect(dialect), b.DatabaseUrl); err != nil {
|
||||
err = fmt.Errorf("error initializing store: %w", err)
|
||||
if c != nil {
|
||||
err = multierror.Append(err, c())
|
||||
|
||||
@@ -29,7 +29,7 @@ func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initiali
|
||||
ui.Error(fmt.Sprintf("Unable to connect to the database at %q", u))
|
||||
return noop, 2
|
||||
}
|
||||
man, err := schema.NewManager(ctx, dialect, dBase)
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase)
|
||||
if err != nil {
|
||||
if errors.Match(errors.T(errors.MigrationLock), err) {
|
||||
ui.Error("Unable to capture a lock on the database.")
|
||||
@@ -53,26 +53,22 @@ func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initiali
|
||||
ui.Error(fmt.Errorf("Error getting database state: %w", err).Error())
|
||||
return unlock, 2
|
||||
}
|
||||
if initialized && !st.InitializationStarted {
|
||||
if initialized && !st.Initialized {
|
||||
ui.Output(base.WrapAtLength("Database has not been initialized. Please use 'boundary database init' to initialize the boundary database."))
|
||||
return unlock, -1
|
||||
}
|
||||
if !initialized && st.InitializationStarted {
|
||||
if !initialized && st.Initialized {
|
||||
ui.Output(base.WrapAtLength("Database has already been initialized. Please use 'boundary database migrate' for any upgrade needs."))
|
||||
return unlock, -1
|
||||
}
|
||||
if st.Dirty {
|
||||
ui.Error(base.WrapAtLength("Database is in a bad state. Please revert back to the last known good state."))
|
||||
return unlock, 2
|
||||
}
|
||||
if err := man.RollForward(ctx); err != nil {
|
||||
if err := man.ApplyMigrations(ctx); err != nil {
|
||||
ui.Error(fmt.Errorf("Error running database migrations: %w", err).Error())
|
||||
return unlock, 2
|
||||
}
|
||||
if base.Format(ui) == "table" {
|
||||
ui.Info("Migrations successfully run.")
|
||||
}
|
||||
migrationLogs, err := schema.GetMigrationLog(ctx, dBase)
|
||||
migrationLogs, err := man.GetMigrationLog(ctx)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Errorf("Error retrieving database migration logs: %w", err).Error())
|
||||
return unlock, 2
|
||||
|
||||
@@ -53,13 +53,11 @@ func TestMigrateDatabase(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
earlyMigrationVersion := 2000
|
||||
oState := schema.TestCloneMigrationStates(t)
|
||||
nState := schema.TestCreatePartialMigrationState(oState["postgres"], earlyMigrationVersion)
|
||||
oState["postgres"] = nState
|
||||
|
||||
man, err := schema.NewManager(ctx, dialect, dBase, schema.WithMigrationStates(oState))
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase, schema.WithEditions(
|
||||
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": earlyMigrationVersion}),
|
||||
))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, man.RollForward(ctx))
|
||||
require.NoError(t, man.ApplyMigrations(ctx))
|
||||
return u
|
||||
},
|
||||
expectedCode: 0,
|
||||
@@ -79,13 +77,11 @@ func TestMigrateDatabase(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
earlyMigrationVersion := 2000
|
||||
oState := schema.TestCloneMigrationStates(t)
|
||||
nState := schema.TestCreatePartialMigrationState(oState["postgres"], earlyMigrationVersion)
|
||||
oState["postgres"] = nState
|
||||
|
||||
man, err := schema.NewManager(ctx, dialect, dBase, schema.WithMigrationStates(oState))
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase, schema.WithEditions(
|
||||
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": earlyMigrationVersion}),
|
||||
))
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, man.RollForward(ctx))
|
||||
require.NoError(t, man.ApplyMigrations(ctx))
|
||||
return u
|
||||
},
|
||||
expectedCode: -1,
|
||||
@@ -157,7 +153,7 @@ func TestMigrateDatabase(t *testing.T) {
|
||||
dBase, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
man, err := schema.NewManager(ctx, dialect, dBase)
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase)
|
||||
require.NoError(t, err)
|
||||
// This is an advisory lock on the DB which is released when the DB session ends.
|
||||
err = man.ExclusiveLock(ctx)
|
||||
@@ -180,7 +176,7 @@ func TestMigrateDatabase(t *testing.T) {
|
||||
dBase, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
man, err := schema.NewManager(ctx, dialect, dBase)
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase)
|
||||
require.NoError(t, err)
|
||||
// This is an advisory lock on the DB which is released when the DB session ends.
|
||||
err = man.ExclusiveLock(ctx)
|
||||
@@ -220,9 +216,9 @@ func TestVerifyOplogIsEmpty(t *testing.T) {
|
||||
dBase, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
man, err := schema.NewManager(ctx, dialect, dBase)
|
||||
man, err := schema.NewManager(ctx, schema.Dialect(dialect), dBase)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, man.RollForward(ctx))
|
||||
require.NoError(t, man.ApplyMigrations(ctx))
|
||||
|
||||
cmd := InitCommand{Command: base.NewCommand(cli.NewMockUi())}
|
||||
cmd.srv = base.NewServer(&base.Command{UI: cmd.UI})
|
||||
|
||||
@@ -425,24 +425,22 @@ func (c *Command) Run(args []string) int {
|
||||
c.UI.Error(fmt.Errorf("Error checking schema state: %w", err).Error())
|
||||
return base.CommandCliError
|
||||
}
|
||||
if !ckState.InitializationStarted {
|
||||
if !ckState.Initialized {
|
||||
c.UI.Error(base.WrapAtLength("The database has not been initialized. Please run 'boundary database init'."))
|
||||
return base.CommandCliError
|
||||
}
|
||||
if ckState.Dirty {
|
||||
c.UI.Error(base.WrapAtLength("Database is in a bad state. Please revert the database into the last known good state."))
|
||||
return base.CommandCliError
|
||||
}
|
||||
if ckState.BinarySchemaVersion > ckState.DatabaseSchemaVersion {
|
||||
if !ckState.MigrationsApplied() {
|
||||
for _, e := range ckState.Editions {
|
||||
if e.DatabaseSchemaState == schema.Ahead {
|
||||
c.UI.Error(base.WrapAtLength(fmt.Sprintf("Newer schema version (%s %d) "+
|
||||
"than this binary expects. Please use a newer version of the boundary "+
|
||||
"binary.", e.Name, e.DatabaseSchemaVersion)))
|
||||
return base.CommandCliError
|
||||
}
|
||||
}
|
||||
c.UI.Error(base.WrapAtLength("Database schema must be updated to use this version. Run 'boundary database migrate' to update the database. NOTE: Boundary does not currently support live migration; ensure all controllers are shut down before running the migration command."))
|
||||
return base.CommandCliError
|
||||
}
|
||||
if ckState.BinarySchemaVersion < ckState.DatabaseSchemaVersion {
|
||||
c.UI.Error(base.WrapAtLength(fmt.Sprintf("Newer schema version (%d) "+
|
||||
"than this binary expects. Please use a newer version of the boundary "+
|
||||
"binary.", ckState.DatabaseSchemaVersion)))
|
||||
return base.CommandCliError
|
||||
}
|
||||
if err := c.verifyKmsSetup(); err != nil {
|
||||
c.UI.Error(base.WrapAtLength("Database is in a bad state. Please revert the database into the last known good state."))
|
||||
return base.CommandCliError
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
// import for init side-effects to include migrations
|
||||
_ "github.com/hashicorp/boundary/internal/db/schema/migrations/oss"
|
||||
)
|
||||
@@ -0,0 +1,22 @@
|
||||
// Package schema is used to apply sql migrations to modify the state of a
|
||||
// database instance. It also provides functionality to report on the state of
|
||||
// a database instance and how it compares with the migration editions in the
|
||||
// running binary.
|
||||
//
|
||||
// This package requires that the migration editions are first registered,
|
||||
// prior to creating a schema.Manager. This is generally done in an init
|
||||
// function of another package, i.e.:
|
||||
//
|
||||
// //go:embed postgres
|
||||
// var postgres embed.FS
|
||||
//
|
||||
// func init() {
|
||||
// schema.RegisterEdition("oss", schema.Postgres, postgres, 0)
|
||||
// }
|
||||
//
|
||||
// Then a manager can be created and used to apply the migrations:
|
||||
//
|
||||
// m := schema.NewManager(ctx, schema.Postgres, db)
|
||||
// m.ApplyMigrations()
|
||||
//
|
||||
package schema
|
||||
@@ -0,0 +1,68 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
)
|
||||
|
||||
// Dialect is same as edition.Dialect
|
||||
type Dialect = edition.Dialect
|
||||
|
||||
// Supported dialects.
|
||||
const (
|
||||
Postgres Dialect = "postgres"
|
||||
)
|
||||
|
||||
var supportedDialects = map[Dialect]struct{}{
|
||||
Postgres: struct{}{},
|
||||
}
|
||||
|
||||
// type dialects map[Dialect]edition.Editions
|
||||
|
||||
type dialects struct {
|
||||
sync.Mutex
|
||||
|
||||
m map[Dialect]edition.Editions
|
||||
}
|
||||
|
||||
var editions = dialects{
|
||||
m: make(map[Dialect]edition.Editions),
|
||||
}
|
||||
|
||||
// RegisterEdition registers an edition for use by the Manager. It will panic if:
|
||||
// - An unsupported dialect is provided.
|
||||
// - The same (dialect, name) is registered.
|
||||
// - The same (dialect, priority) is registered.
|
||||
func RegisterEdition(name string, dialect Dialect, fs embed.FS, priority int) {
|
||||
editions.Lock()
|
||||
defer editions.Unlock()
|
||||
|
||||
if _, ok := supportedDialects[dialect]; !ok {
|
||||
panic(fmt.Sprintf("unsupported dialect: %s", dialect))
|
||||
}
|
||||
var e edition.Editions
|
||||
var ok bool
|
||||
|
||||
e, ok = editions.m[dialect]
|
||||
if !ok {
|
||||
e = make(edition.Editions, 0)
|
||||
}
|
||||
|
||||
for _, ee := range e {
|
||||
if ee.Name == name {
|
||||
panic(fmt.Sprintf("edition %s with dialect %s already registered", name, dialect))
|
||||
}
|
||||
|
||||
if ee.Priority == priority {
|
||||
panic(fmt.Sprintf("edition %s with dialect %s and priority %d has same priority as edition %s", name, dialect, priority, ee.Name))
|
||||
}
|
||||
}
|
||||
|
||||
e = append(e, edition.New(name, dialect, fs, priority))
|
||||
e.Sort()
|
||||
|
||||
editions.m[dialect] = e
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type testEdition struct {
|
||||
name string
|
||||
dialect schema.Dialect
|
||||
fs embed.FS
|
||||
priority int
|
||||
}
|
||||
|
||||
var (
|
||||
//go:embed testdata/one
|
||||
one embed.FS
|
||||
|
||||
//go:embed testdata/two
|
||||
two embed.FS
|
||||
|
||||
//go:embed testdata/three
|
||||
three embed.FS
|
||||
)
|
||||
|
||||
func TestRegisterEditionPanics(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
editions []testEdition
|
||||
}{
|
||||
{
|
||||
"unsupportedDialect",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Dialect("mongodb"),
|
||||
one,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"duplicateName",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"duplicatePriority",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"two",
|
||||
schema.Postgres,
|
||||
two,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Panics(t, func() {
|
||||
for _, e := range tt.editions {
|
||||
schema.RegisterEdition(e.name, e.dialect, e.fs, e.priority)
|
||||
}
|
||||
}, tt.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterEdition(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
editions []testEdition
|
||||
}{
|
||||
{
|
||||
"singleEdition",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditions",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"two",
|
||||
schema.Postgres,
|
||||
one,
|
||||
1,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"threeEditions",
|
||||
[]testEdition{
|
||||
{
|
||||
"one",
|
||||
schema.Postgres,
|
||||
one,
|
||||
0,
|
||||
},
|
||||
{
|
||||
"two",
|
||||
schema.Postgres,
|
||||
one,
|
||||
1,
|
||||
},
|
||||
{
|
||||
"three",
|
||||
schema.Postgres,
|
||||
one,
|
||||
3,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.NotPanics(t, func() {
|
||||
schema.TestClearEditions(t)
|
||||
for _, e := range tt.editions {
|
||||
schema.RegisterEdition(e.name, e.dialect, e.fs, e.priority)
|
||||
}
|
||||
}, tt.name)
|
||||
})
|
||||
}
|
||||
schema.TestClearEditions(t)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
)
|
||||
|
||||
const NilVersion = nilVersion
|
||||
|
||||
// TestClearEditions is a test helper to reset the editions map.
|
||||
func TestClearEditions(t *testing.T) {
|
||||
t.Helper()
|
||||
editions.Lock()
|
||||
defer editions.Unlock()
|
||||
|
||||
editions.m = make(map[edition.Dialect]edition.Editions)
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// Package edition provides internal structs for the schema package for
|
||||
// defining and organizing database migration editions.
|
||||
package edition
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Dialect is a specific SQL language variant. This generally is the same as
|
||||
// a specific SQL server implementation.
|
||||
type Dialect string
|
||||
|
||||
func (d Dialect) String() string {
|
||||
return string(d)
|
||||
}
|
||||
|
||||
// Edition is a collection of sql statements along with a version number.
|
||||
// It is used to apply changes to the database instance.
|
||||
type Edition struct {
|
||||
// The identifier of an edition. The Name and Dialect pair should be unique.
|
||||
Name string
|
||||
// The specific SQL language variant that the Migrtions are for. The Name
|
||||
// and Dialect pair should be unique.
|
||||
Dialect Dialect
|
||||
|
||||
// The latest version of the schema for this edition that this binary supports.
|
||||
LatestVersion int
|
||||
|
||||
// The set of migrations that should be applied to a database to reach the latest version.
|
||||
// This is a map of schema versions to sql.
|
||||
Migrations map[int][]byte
|
||||
|
||||
// Priority is used to determine the order that multiple Editions should be applied.
|
||||
Priority int
|
||||
}
|
||||
|
||||
// Editions is a collection of Edition
|
||||
type Editions []Edition
|
||||
|
||||
// Sort orders the Editions by priority.
|
||||
func (e Editions) Sort() {
|
||||
sort.SliceStable(e, func(i, j int) bool {
|
||||
return e[i].Priority < e[j].Priority
|
||||
})
|
||||
}
|
||||
|
||||
// New creates an Edition with the provided parameters. The embed.FS m will be
|
||||
// walked to extract the sql statements. The priority is used to determine
|
||||
// when this Edition's migrations are applied relative to other Editions. A
|
||||
// lower number indicates a higher priority. New will panic if the structure
|
||||
// of the embed.FS is not correct. The files must be structured as follows:
|
||||
//
|
||||
// <majorVersion>/
|
||||
// <minorVersion>_<description>.up.sql
|
||||
//
|
||||
// Where majorVersion and minorVersion are integers. There can be any number of
|
||||
// leading directories prior to the major versions. For example a directory
|
||||
// structure like the following is correct:
|
||||
//
|
||||
// migrations/oss/postgres/
|
||||
// 0/
|
||||
// 01_initial.up.sql
|
||||
// 1/
|
||||
// 01_add_columns.up.sql
|
||||
// 02_rename_table.up.sql
|
||||
// 2/
|
||||
// 01_add_new_table.up.sql
|
||||
// 02_refactor_views.up.sql
|
||||
func New(name string, dialect Dialect, m embed.FS, priority int) Edition {
|
||||
var largestSchemaVersion int
|
||||
migrations := make(map[int][]byte)
|
||||
|
||||
fs.WalkDir(m, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to process migration files: %s", err))
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(path, ".up.sql") {
|
||||
return nil
|
||||
}
|
||||
|
||||
dir, file := filepath.Split(path)
|
||||
verMajorDir := filepath.Base(dir)
|
||||
|
||||
verMajor, err := strconv.Atoi(verMajorDir)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("migration file does not have valid major version directory: %s", path))
|
||||
}
|
||||
|
||||
verMinor, err := strconv.Atoi(strings.SplitN(file, "_", 2)[0])
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("migration file does not have valid minor version prefix: %s", path))
|
||||
}
|
||||
|
||||
fullV := (verMajor * 1000) + verMinor
|
||||
if fullV > largestSchemaVersion {
|
||||
largestSchemaVersion = fullV
|
||||
}
|
||||
|
||||
cbts, err := m.ReadFile(path)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("unable to read migration file: %s", path))
|
||||
}
|
||||
|
||||
contents := strings.TrimSpace(string(cbts))
|
||||
if strings.ToLower(contents[:len("begin;")]) == "begin;" {
|
||||
contents = contents[len("begin;"):]
|
||||
}
|
||||
if strings.ToLower(contents[len(contents)-len("commit;"):]) == "commit;" {
|
||||
contents = contents[:len(contents)-len("commit;")]
|
||||
}
|
||||
contents = strings.TrimSpace(contents)
|
||||
|
||||
migrations[fullV] = []byte(contents)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
return Edition{
|
||||
Name: name,
|
||||
Dialect: dialect,
|
||||
LatestVersion: largestSchemaVersion,
|
||||
Migrations: migrations,
|
||||
Priority: priority,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package edition_test
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// valid embed.FS
|
||||
var (
|
||||
//go:embed testdata/one
|
||||
one embed.FS
|
||||
//go:embed testdata/two
|
||||
two embed.FS
|
||||
//go:embed testdata/three
|
||||
three embed.FS
|
||||
)
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
priority int
|
||||
fs embed.FS
|
||||
expectedVersion int
|
||||
expectedMigrationCount int
|
||||
}{
|
||||
{
|
||||
"one",
|
||||
0,
|
||||
one,
|
||||
1,
|
||||
1,
|
||||
},
|
||||
{
|
||||
"two",
|
||||
1,
|
||||
two,
|
||||
2,
|
||||
2,
|
||||
},
|
||||
{
|
||||
"three",
|
||||
3,
|
||||
three,
|
||||
1001,
|
||||
2,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
e := edition.New(tt.name, edition.Dialect("postgres"), tt.fs, tt.priority)
|
||||
assert.Equal(t, e.Name, tt.name, "Name")
|
||||
assert.Equal(t, e.Dialect, edition.Dialect("postgres"), "Dialect")
|
||||
assert.Equal(t, e.LatestVersion, tt.expectedVersion, "Version")
|
||||
assert.Equal(t, e.Priority, tt.priority, "Priority")
|
||||
assert.Equal(t, len(e.Migrations), tt.expectedMigrationCount, "Number of migrations")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// invalid embed.FS
|
||||
var (
|
||||
//go:embed testdata/invalid/major-version-not-int
|
||||
majorVersionNotInt embed.FS
|
||||
//go:embed testdata/invalid/minor-version-invalid-separator
|
||||
minorVersionInvalidSeparator embed.FS
|
||||
//go:embed testdata/invalid/minor-version-not-int
|
||||
minorVersionNotInt embed.FS
|
||||
//go:embed testdata/invalid/no-minor-version
|
||||
noMinorVersion embed.FS
|
||||
//go:embed testdata/invalid/no-major-version
|
||||
noMajorVersion embed.FS
|
||||
)
|
||||
|
||||
func TestNewPanics(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fs embed.FS
|
||||
}{
|
||||
{
|
||||
"majorVersionNotInt",
|
||||
majorVersionNotInt,
|
||||
},
|
||||
{
|
||||
"minorVersionInvalidSeparator",
|
||||
minorVersionInvalidSeparator,
|
||||
},
|
||||
{
|
||||
"minorVersionNotInt",
|
||||
minorVersionNotInt,
|
||||
},
|
||||
{
|
||||
"noMinorVersion",
|
||||
noMinorVersion,
|
||||
},
|
||||
{
|
||||
"noMajorVersion",
|
||||
noMajorVersion,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Panics(t, func() {
|
||||
edition.New(tt.name, edition.Dialect("postgres"), tt.fs, 0)
|
||||
}, tt.name)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSort(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
editions edition.Editions
|
||||
sorted edition.Editions
|
||||
}{
|
||||
{
|
||||
"unsortedConsecutive",
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "two",
|
||||
Priority: 2,
|
||||
},
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"unsorted",
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "three",
|
||||
Priority: 3,
|
||||
},
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"equalPriority",
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "three-also",
|
||||
Priority: 3,
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
Priority: 3,
|
||||
},
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
},
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Name: "three-also",
|
||||
Priority: 3,
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
Priority: 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"alreadySorted",
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "zero",
|
||||
Priority: 0,
|
||||
},
|
||||
{
|
||||
Name: "one",
|
||||
Priority: 1,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
Priority: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tt.editions.Sort()
|
||||
assert.Equal(t, tt.editions, tt.sorted)
|
||||
})
|
||||
}
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table one (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table three (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
@@ -0,0 +1,3 @@
|
||||
begin;
|
||||
alter table tree add column name text;
|
||||
commit;
|
||||
@@ -0,0 +1,5 @@
|
||||
begin;
|
||||
create table two (
|
||||
id bigint primary key
|
||||
);
|
||||
commit;
|
||||
@@ -0,0 +1,3 @@
|
||||
begin;
|
||||
alter table two add column name text;
|
||||
commit;
|
||||
@@ -0,0 +1,3 @@
|
||||
// Package log provides internal structs and options for the schema package for
|
||||
// tracking logs generated when applying migrations.
|
||||
package log
|
||||
@@ -0,0 +1,12 @@
|
||||
package log
|
||||
|
||||
import "time"
|
||||
|
||||
// Entry represents a log entry generated during migrations.
|
||||
type Entry struct {
|
||||
Id int
|
||||
MigrationEdition string
|
||||
MigrationVersion int
|
||||
CreateTime time.Time
|
||||
Entry string
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package log
|
||||
|
||||
// GetOpts - iterate the inbound Options and return a struct.
|
||||
func GetOpts(opt ...Option) Options {
|
||||
opts := getDefaultOptions()
|
||||
for _, o := range opt {
|
||||
o(&opts)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// Option - how Options are passed as arguments.
|
||||
type Option func(*Options)
|
||||
|
||||
// Options = how options are represented
|
||||
type Options struct {
|
||||
WithDeleteLog bool
|
||||
}
|
||||
|
||||
func getDefaultOptions() Options {
|
||||
return Options{}
|
||||
}
|
||||
|
||||
// WithDeleteLog provides an option to specify the deletion of log entries.
|
||||
func WithDeleteLog(del bool) Option {
|
||||
return func(o *Options) {
|
||||
o.WithDeleteLog = del
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// Package postgres provides an implementation of the schema.driver interface
|
||||
// for a PostgreSQL database.
|
||||
package postgres
|
||||
@@ -0,0 +1,111 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEnsureVersion(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
|
||||
err := p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEnsureVersion_NoTxn(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
err := p.EnsureVersionTable(ctx)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
func TestEnsureVersion_UpdateForEditionSupport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, db, _ := setup(ctx, t)
|
||||
|
||||
_, err := db.ExecContext(ctx, `
|
||||
create table boundary_schema_version (
|
||||
version bigint primary key,
|
||||
dirty boolean not null
|
||||
);`)
|
||||
require.NoError(t, err)
|
||||
_, err = db.ExecContext(ctx, `
|
||||
insert into boundary_schema_version
|
||||
(version, dirty)
|
||||
values
|
||||
(1001, false);`)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
var edition string
|
||||
var version int
|
||||
|
||||
err = db.QueryRowContext(
|
||||
ctx,
|
||||
`select edition, version from boundary_schema_version`,
|
||||
).Scan(&edition, &version)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, edition, "oss")
|
||||
assert.Equal(t, version, 1001)
|
||||
}
|
||||
|
||||
func TestEnsureVersion_RenameOldSchemaTable(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, db, _ := setup(ctx, t)
|
||||
|
||||
_, err := db.ExecContext(ctx, `
|
||||
create table schema_migrations (
|
||||
version bigint primary key,
|
||||
dirty boolean not null
|
||||
);`)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
_, err = db.ExecContext(ctx, `
|
||||
insert into schema_migrations
|
||||
(version, dirty)
|
||||
values
|
||||
(1001, false);`)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
var edition string
|
||||
var version int
|
||||
|
||||
err = db.QueryRowContext(
|
||||
ctx,
|
||||
`select edition, version from boundary_schema_version`,
|
||||
).Scan(&edition, &version)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, edition, "oss")
|
||||
assert.Equal(t, version, 1001)
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Original Work
|
||||
// Copyright (c) 2016 Matthias Kadenbach
|
||||
// https://github.com/mattes/migrate
|
||||
//
|
||||
// Modified Work
|
||||
// Copyright (c) 2018 Dale Hui
|
||||
// https://github.com/golang-migrate/migrate
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgres
|
||||
|
||||
import "strings"
|
||||
|
||||
const newLine = '\n'
|
||||
|
||||
func runesCount(input []rune, target rune) int {
|
||||
var count int
|
||||
for _, r := range input {
|
||||
if r == target {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func runesLastIndex(input []rune, target rune) int {
|
||||
for i := len(input) - 1; i >= 0; i-- {
|
||||
if input[i] == target {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func computeLineFromPos(s string, pos int) (line uint, col uint, ok bool) {
|
||||
// replace crlf with lf
|
||||
s = strings.Replace(s, "\r\n", "\n", -1)
|
||||
// pg docs: pos uses index 1 for the first character, and positions are measured in characters not bytes
|
||||
runes := []rune(s)
|
||||
if pos > len(runes) {
|
||||
return 0, 0, false
|
||||
}
|
||||
sel := runes[:pos]
|
||||
line = uint(runesCount(sel, newLine) + 1)
|
||||
col = uint(pos - 1 - runesLastIndex(sel, newLine))
|
||||
return line, col, true
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Original Work
|
||||
// Copyright (c) 2016 Matthias Kadenbach
|
||||
// https://github.com/mattes/migrate
|
||||
//
|
||||
// Modified Work
|
||||
// Copyright (c) 2018 Dale Hui
|
||||
// https://github.com/golang-migrate/migrate
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_computeLineFromPos(t *testing.T) {
|
||||
testcases := []struct {
|
||||
pos int
|
||||
wantLine uint
|
||||
wantCol uint
|
||||
input string
|
||||
wantOk bool
|
||||
}{
|
||||
{
|
||||
15, 2, 6, "SELECT *\nFROM foo", true, // foo table does not exists
|
||||
},
|
||||
{
|
||||
16, 3, 6, "SELECT *\n\nFROM foo", true, // foo table does not exists, empty line
|
||||
},
|
||||
{
|
||||
25, 3, 7, "SELECT *\nFROM foo\nWHERE x", true, // x column error
|
||||
},
|
||||
{
|
||||
27, 5, 7, "SELECT *\n\nFROM foo\n\nWHERE x", true, // x column error, empty lines
|
||||
},
|
||||
{
|
||||
10, 2, 1, "SELECT *\nFROMM foo", true, // FROMM typo
|
||||
},
|
||||
{
|
||||
11, 3, 1, "SELECT *\n\nFROMM foo", true, // FROMM typo, empty line
|
||||
},
|
||||
{
|
||||
17, 2, 8, "SELECT *\nFROM foo", true, // last character
|
||||
},
|
||||
{
|
||||
18, 0, 0, "SELECT *\nFROM foo", false, // invalid position
|
||||
},
|
||||
}
|
||||
for i, tc := range testcases {
|
||||
t.Run("tc"+strconv.Itoa(i), func(t *testing.T) {
|
||||
run := func(crlf bool, nonASCII bool) {
|
||||
var name string
|
||||
if crlf {
|
||||
name = "crlf"
|
||||
} else {
|
||||
name = "lf"
|
||||
}
|
||||
if nonASCII {
|
||||
name += "-nonascii"
|
||||
} else {
|
||||
name += "-ascii"
|
||||
}
|
||||
t.Run(name, func(t *testing.T) {
|
||||
input := tc.input
|
||||
if crlf {
|
||||
input = strings.Replace(input, "\n", "\r\n", -1)
|
||||
}
|
||||
if nonASCII {
|
||||
input = strings.Replace(input, "FROM", "FRÖM", -1)
|
||||
}
|
||||
gotLine, gotCol, gotOK := computeLineFromPos(input, tc.pos)
|
||||
|
||||
if tc.wantOk {
|
||||
t.Logf("pos %d, want %d:%d, %#v", tc.pos, tc.wantLine, tc.wantCol, input)
|
||||
}
|
||||
|
||||
if gotOK != tc.wantOk {
|
||||
t.Fatalf("expected ok %v but got %v", tc.wantOk, gotOK)
|
||||
}
|
||||
if gotLine != tc.wantLine {
|
||||
t.Fatalf("expected line %d but got %d", tc.wantLine, gotLine)
|
||||
}
|
||||
if gotCol != tc.wantCol {
|
||||
t.Fatalf("expected col %d but got %d", tc.wantCol, gotCol)
|
||||
}
|
||||
})
|
||||
}
|
||||
run(false, false)
|
||||
run(true, false)
|
||||
run(false, true)
|
||||
run(true, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/common"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/postgres"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Tests that TrySharedLock:
|
||||
// - can get a lock as the only connection
|
||||
// - a second connection can also get the shared lock
|
||||
// - a second connection cannot get an exclusive lock
|
||||
func TestTrySharedLock(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
p, _, u := setup(ctx, t)
|
||||
|
||||
err := p.TrySharedLock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
p2, err := postgres.New(ctx, d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TrySharedLock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// Test that TryLock gets an exclusive lock and:
|
||||
// - a separate connection cannot get the lock via TryLock
|
||||
// - a separate connection cannot get the lock via TrySharedLock
|
||||
// - a separate connection cannot get the lock via Lock
|
||||
func TestTryLock(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
p, _, u := setup(ctx, t)
|
||||
|
||||
err := p.TryLock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
p2, err := postgres.New(ctx, d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TrySharedLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
err = p2.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
ctx2, _ := context.WithTimeout(ctx, time.Millisecond)
|
||||
err = p2.Lock(ctx2)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// Test that Lock gets an exclusive lock and:
|
||||
// - a separate connection cannot get the lock via TryLock
|
||||
// - a separate connection cannot get the lock via TrySharedLock
|
||||
// - a separate connection cannot get the lock via Lock
|
||||
func TestLock(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
p, _, u := setup(ctx, t)
|
||||
|
||||
err := p.Lock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
p2, err := postgres.New(ctx, d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TrySharedLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
err = p2.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
ctx2, _ := context.WithTimeout(ctx, time.Millisecond)
|
||||
err = p2.Lock(ctx2)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// Test the Unlock:
|
||||
// - can unlock a lock granted via TryLock
|
||||
// - can unlock a lock granted via Lock
|
||||
func TestUnlock(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
p, _, u := setup(ctx, t)
|
||||
|
||||
err := p.Lock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
p2, err := postgres.New(ctx, d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// cannot get lock since p has it.
|
||||
err = p2.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
// clear lock on p
|
||||
err = p.Unlock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// p2 can now get lock
|
||||
err = p2.TryLock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// p can not get the lock now
|
||||
err = p.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
// clear lock on p2
|
||||
err = p2.Unlock(ctx)
|
||||
|
||||
// p can now get lock
|
||||
err = p.TryLock(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// Test that UnlockShared
|
||||
// - can unlock a lock granted by TrySharedLock
|
||||
func TestUnlockShared(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := context.Background()
|
||||
p, _, u := setup(ctx, t)
|
||||
|
||||
err := p.TrySharedLock(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
p2, err := postgres.New(ctx, d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TryLock(ctx)
|
||||
require.Error(t, err)
|
||||
|
||||
err = p.UnlockShared(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p2.TryLock(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/log"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEnsureMigrationLog(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
|
||||
err := p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureMigrationLogTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestEnsureMigrationLog_NoTxn(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
err := p.EnsureMigrationLogTable(ctx)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
// Test that a database that was created with a log_migration table
|
||||
// prior to edition support, can be updated to support editions,
|
||||
// and any existing log entries can be updated.
|
||||
//
|
||||
// The scenario involves a case where:
|
||||
// - The database was initialized with the original boundary_schema_version table
|
||||
// - The original migrations where run, creating the log_migration table and some entries in the table.
|
||||
func TestEnsureMigrationLog_UpdateForEditionSupport(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, db, _ := setup(ctx, t)
|
||||
|
||||
statements := []string{
|
||||
// original boundary_schema_version table
|
||||
`create table boundary_schema_version (
|
||||
version bigint primary key,
|
||||
dirty boolean not null);`,
|
||||
// populate the table with a version
|
||||
`insert into boundary_schema_version
|
||||
(version, dirty)
|
||||
values
|
||||
(1001, false);`,
|
||||
// need to create some things from other migrations that the original tables used
|
||||
`create domain wt_timestamp as
|
||||
timestamp with time zone
|
||||
default current_timestamp;
|
||||
|
||||
create or replace function
|
||||
default_create_time()
|
||||
returns trigger
|
||||
as $$
|
||||
begin
|
||||
if new.create_time is distinct from now() then
|
||||
raise warning 'create_time cannot be set to %', new.create_time;
|
||||
new.create_time = now();
|
||||
end if;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
|
||||
create or replace function
|
||||
immutable_columns()
|
||||
returns trigger
|
||||
as $$
|
||||
declare
|
||||
col_name text;
|
||||
new_value text;
|
||||
old_value text;
|
||||
begin
|
||||
foreach col_name in array tg_argv loop
|
||||
execute format('SELECT $1.%I', col_name) into new_value using new;
|
||||
execute format('SELECT $1.%I', col_name) into old_value using old;
|
||||
if new_value is distinct from old_value then
|
||||
raise exception 'immutable column: %.%', tg_table_name, col_name using
|
||||
errcode = '23601',
|
||||
schema = tg_table_schema,
|
||||
table = tg_table_name,
|
||||
column = col_name;
|
||||
end if;
|
||||
end loop;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
`,
|
||||
// create original log_migration table, triggers
|
||||
`create table log_migration(
|
||||
id bigint generated always as identity primary key,
|
||||
migration_version bigint not null, -- cannot declare FK since the table is truncated during runtime
|
||||
create_time wt_timestamp,
|
||||
entry text not null
|
||||
);
|
||||
comment on table log_migration is
|
||||
'log_migration entries are logging output from databaes migrations';
|
||||
|
||||
create trigger
|
||||
default_create_time_column
|
||||
before
|
||||
insert on log_migration
|
||||
for each row execute procedure default_create_time();
|
||||
|
||||
create trigger
|
||||
immutable_columns
|
||||
before
|
||||
update on log_migration
|
||||
for each row execute procedure immutable_columns('id', 'migration_version', 'create_time', 'entry');
|
||||
|
||||
create or replace function
|
||||
log_migration_version()
|
||||
returns trigger
|
||||
as $$
|
||||
declare current_version bigint;
|
||||
begin
|
||||
select max(version) from boundary_schema_version into current_version;
|
||||
new.migration_version = current_version;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function log_migration_version() is
|
||||
'log_migration_version will set the log_migration entries to the current migration version';
|
||||
|
||||
create trigger
|
||||
migration_version_column
|
||||
before
|
||||
insert on log_migration
|
||||
for each row execute procedure log_migration_version();
|
||||
`,
|
||||
// insert some logs
|
||||
`insert into log_migration (entry)
|
||||
values
|
||||
('log entry');`,
|
||||
}
|
||||
|
||||
for _, s := range statements {
|
||||
_, err := db.ExecContext(ctx, s)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
err := p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureMigrationLogTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
logs, err := p.GetMigrationLog(ctx, log.WithDeleteLog(true))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, len(logs))
|
||||
assert.NotEqual(t, logs[0].Id, 0)
|
||||
assert.False(t, logs[0].CreateTime.IsZero())
|
||||
assert.Equal(t, "oss", logs[0].MigrationEdition)
|
||||
assert.Equal(t, 1001, logs[0].MigrationVersion)
|
||||
assert.Equal(t, "log entry", logs[0].Entry)
|
||||
|
||||
// now ensure the updated table and trigger still works
|
||||
statements = []string{
|
||||
// update the version, to make it easy to filter on log_migrations
|
||||
`update boundary_schema_version set version = 1002;`,
|
||||
// insert a new log entry
|
||||
`insert into log_migration (entry, edition)
|
||||
values
|
||||
('new log entry', 'oss');`,
|
||||
}
|
||||
for _, s := range statements {
|
||||
_, err := db.ExecContext(ctx, s)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
logs, err = p.GetMigrationLog(ctx, log.WithDeleteLog(true))
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 1, len(logs))
|
||||
assert.NotEqual(t, logs[0].Id, 0)
|
||||
assert.False(t, logs[0].CreateTime.IsZero())
|
||||
assert.Equal(t, "oss", logs[0].MigrationEdition)
|
||||
assert.Equal(t, 1002, logs[0].MigrationVersion)
|
||||
assert.Equal(t, "new log entry", logs[0].Entry)
|
||||
|
||||
// ensure it is idempotent
|
||||
err = p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
err = p.EnsureMigrationLogTable(ctx)
|
||||
require.NoError(t, err)
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
// The MIT License (MIT)
|
||||
//
|
||||
// Original Work
|
||||
// Copyright (c) 2016 Matthias Kadenbach
|
||||
// https://github.com/mattes/migrate
|
||||
//
|
||||
// Modified Work
|
||||
// Copyright (c) 2018 Dale Hui
|
||||
// https://github.com/golang-migrate/migrate
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/log"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/migrations"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/jackc/pgconn"
|
||||
)
|
||||
|
||||
// schemaAccessLockId is a Lock key used to ensure a single boundary binary is operating
|
||||
// on a postgres server at a time. The value has no meaning and was picked randomly.
|
||||
const schemaAccessLockId int64 = 3865661975
|
||||
|
||||
// nilVersion is used to identify when a migration version has not be set.
|
||||
const nilVersion = -1
|
||||
|
||||
// Postgres is a driver usable by a boundary schema.Manager.
|
||||
// This struct is not thread safe.
|
||||
type Postgres struct {
|
||||
// Locking and unlocking need to use the same connection
|
||||
conn *sql.Conn
|
||||
|
||||
tx *sql.Tx
|
||||
}
|
||||
|
||||
// New creates a Postgres with the provided sql.DB verified as connectable
|
||||
func New(ctx context.Context, db *sql.DB) (*Postgres, error) {
|
||||
const op = "postgres.New"
|
||||
if err := db.PingContext(ctx); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
conn, err := db.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
px := &Postgres{
|
||||
conn: conn,
|
||||
}
|
||||
return px, nil
|
||||
}
|
||||
|
||||
// TrySharedLock attempts to capture a shared lock. If it is not successful it returns an error.
|
||||
// https://www.postgresql.org/docs/11/static/explicit-locking.html#ADVISORY-LOCKS
|
||||
func (p *Postgres) TrySharedLock(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).TrySharedLock"
|
||||
|
||||
r := p.conn.QueryRowContext(ctx, trySharedLock, schemaAccessLockId)
|
||||
if r.Err() != nil {
|
||||
return errors.Wrap(ctx, r.Err(), op)
|
||||
}
|
||||
var gotLock bool
|
||||
if err := r.Scan(&gotLock); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if !gotLock {
|
||||
return errors.New(ctx, errors.MigrationLock, op, "Lock failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TryLock attempts to capture an exclusive lock. If it is not successful it returns an error.
|
||||
// https://www.postgresql.org/docs/11/static/explicit-locking.html#ADVISORY-LOCKS
|
||||
func (p *Postgres) TryLock(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).TryLock"
|
||||
|
||||
r := p.conn.QueryRowContext(ctx, tryLock, schemaAccessLockId)
|
||||
if r.Err() != nil {
|
||||
return errors.Wrap(ctx, r.Err(), op)
|
||||
}
|
||||
var gotLock bool
|
||||
if err := r.Scan(&gotLock); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if !gotLock {
|
||||
return errors.New(ctx, errors.MigrationLock, op, "Lock failed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Lock calls pg_advisory_lock with the provided context and returns an error
|
||||
// if we were unable to get the lock before the context cancels.
|
||||
func (p *Postgres) Lock(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).Lock"
|
||||
|
||||
if _, err := p.conn.ExecContext(ctx, lock, schemaAccessLockId); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unlock calls pg_advisory_unlock and returns an error if we were unable to
|
||||
// release the lock before the context cancels.
|
||||
func (p *Postgres) Unlock(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).Unlock"
|
||||
|
||||
if _, err := p.conn.ExecContext(ctx, unlock, schemaAccessLockId); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnlockShared calls pg_advisory_unlock_shared and returns an error if we were unable to
|
||||
// release the lock before the context cancels.
|
||||
func (p *Postgres) UnlockShared(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).UnlockShared"
|
||||
|
||||
if _, err := p.conn.ExecContext(ctx, unlockSharedLock, schemaAccessLockId); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartRun begins a transaction internal to the driver.
|
||||
func (p *Postgres) StartRun(ctx context.Context) error {
|
||||
tx, err := p.conn.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.tx = tx
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommitRun commits a transaction, if there is an error it should rollback the transaction.
|
||||
func (p *Postgres) CommitRun(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).CommitRun"
|
||||
defer func() {
|
||||
p.tx = nil
|
||||
}()
|
||||
if p.tx == nil {
|
||||
return errors.New(ctx, errors.MigrationIntegrity, op, "no pending transaction")
|
||||
}
|
||||
if err := p.tx.Commit(); err != nil {
|
||||
if errRollback := p.tx.Rollback(); errRollback != nil && errRollback != sql.ErrTxDone {
|
||||
err = multierror.Append(err, errRollback)
|
||||
}
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run will apply a migration. The io.Reader should provide the SQL
|
||||
// statements to execute, and the int is the version for that set of
|
||||
// statements. This should always be wrapped by StartRun and CommitRun.
|
||||
func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int, edition string) error {
|
||||
const op = "postgres.(Postgres).Run"
|
||||
|
||||
if p.tx == nil {
|
||||
return errors.New(ctx, errors.MigrationIntegrity, op, "no pending transaction")
|
||||
}
|
||||
|
||||
migr, err := ioutil.ReadAll(migration)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
// Run migration
|
||||
query := string(migr)
|
||||
|
||||
// set the version first, so logs will be associated with this new version.
|
||||
// if there's an error, it will get rollback
|
||||
if err := p.setVersion(ctx, version, edition); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
if _, err := p.conn.ExecContext(ctx, query); err != nil {
|
||||
if pgErr, ok := err.(*pgconn.PgError); ok {
|
||||
var line uint
|
||||
var col uint
|
||||
var lineColOK bool
|
||||
if pgErr.Position != 0 {
|
||||
line, col, lineColOK = computeLineFromPos(query, int(pgErr.Position))
|
||||
}
|
||||
message := "migration failed"
|
||||
if lineColOK {
|
||||
message = fmt.Sprintf("%s (column %d)", message, col)
|
||||
}
|
||||
if pgErr.Detail != "" {
|
||||
message = fmt.Sprintf("%s, %s", message, pgErr.Detail)
|
||||
}
|
||||
message = fmt.Sprintf("%s, on line %v: %s", message, line, migr)
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg(message))
|
||||
}
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("migration failed: %s", migr)))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
var errOldMigrationTable = stderrors.New("old schema migration table")
|
||||
|
||||
func (p *Postgres) schemaInitialized(ctx context.Context) (bool, error) {
|
||||
const op = "postgres.(Postgres).CurrentState"
|
||||
var initialized bool
|
||||
|
||||
tableNames := make([]string, 0, 2)
|
||||
tableResult, err := p.conn.QueryContext(ctx, tablesExist)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
defer tableResult.Close()
|
||||
for tableResult.Next() {
|
||||
var tableName string
|
||||
if err := tableResult.Scan(&tableName); err != nil {
|
||||
return false, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
tableNames = append(tableNames, tableName)
|
||||
}
|
||||
|
||||
if len(tableNames) <= 0 {
|
||||
// No version table found
|
||||
return initialized, nil
|
||||
}
|
||||
|
||||
initialized = true
|
||||
|
||||
if len(tableNames) > 1 {
|
||||
return initialized, errors.New(ctx, errors.MigrationIntegrity, op, "both old and new migration tables exist")
|
||||
}
|
||||
|
||||
if tableNames[0] != schemaVersionTable {
|
||||
return initialized, errOldMigrationTable
|
||||
}
|
||||
|
||||
return initialized, nil
|
||||
}
|
||||
|
||||
// CurrentState returns the state of the given edition.
|
||||
// ver is the current migration version number as recorded in the database.
|
||||
// A version of -1 indicates no version is set.
|
||||
// initialized will be true if the schema was previously initialized.
|
||||
func (p *Postgres) CurrentState(ctx context.Context, edition string) (version int, initialized bool, err error) {
|
||||
const op = "postgres.(Postgres).CurrentState"
|
||||
|
||||
version = nilVersion
|
||||
initialized, err = p.schemaInitialized(ctx)
|
||||
switch {
|
||||
case err == errOldMigrationTable:
|
||||
// only oss edition had the old migration table
|
||||
if edition != "oss" {
|
||||
return nilVersion, initialized, nil
|
||||
}
|
||||
err = p.conn.QueryRowContext(ctx, selectOldVersion).Scan(&version)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
// no version recorded
|
||||
return nilVersion, initialized, nil
|
||||
case err != nil:
|
||||
return nilVersion, initialized, errors.Wrap(ctx, err, op)
|
||||
default:
|
||||
return version, initialized, nil
|
||||
}
|
||||
case err != nil:
|
||||
return nilVersion, initialized, err
|
||||
default:
|
||||
// continue
|
||||
}
|
||||
|
||||
if !initialized {
|
||||
return nilVersion, initialized, nil
|
||||
}
|
||||
|
||||
err = p.conn.QueryRowContext(ctx, selectVersion, edition).Scan(&version)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
// no version recorded
|
||||
return nilVersion, initialized, nil
|
||||
case err != nil:
|
||||
// try to query for an edition in the pre-edition version table
|
||||
if edition == "oss" {
|
||||
preEditionErr := p.conn.QueryRowContext(ctx, selectPreEditionVersion).Scan(&version)
|
||||
switch {
|
||||
case preEditionErr == sql.ErrNoRows:
|
||||
return nilVersion, initialized, nil
|
||||
case preEditionErr != nil:
|
||||
// return the original error
|
||||
return nilVersion, initialized, errors.Wrap(ctx, err, op)
|
||||
default:
|
||||
return version, initialized, nil
|
||||
}
|
||||
}
|
||||
return nilVersion, initialized, errors.Wrap(ctx, err, op)
|
||||
default:
|
||||
return version, initialized, nil
|
||||
}
|
||||
}
|
||||
|
||||
// EnsureVersionTable ensures that the table used to record the schema versions for each edition
|
||||
// exists and is in the correct state.
|
||||
func (p *Postgres) EnsureVersionTable(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).EnsureVersionTable"
|
||||
|
||||
if p.tx == nil {
|
||||
return errors.New(ctx, errors.MigrationIntegrity, op, "no pending transaction")
|
||||
}
|
||||
|
||||
exists := false
|
||||
if err := p.tx.QueryRowContext(ctx, tableExists).Scan(&exists); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
oldExists := false
|
||||
if err := p.tx.QueryRowContext(ctx, oldTableExists).Scan(&oldExists); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if !oldExists {
|
||||
// create table for the first time it its correct state
|
||||
if _, err := p.tx.ExecContext(ctx, migrations.Base("postgres").CreateSchemaVersion); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// else convert old table to new table
|
||||
if _, err := p.tx.ExecContext(ctx, updateTableName); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
}
|
||||
|
||||
// table exists, update it to ensure it has the correct columns and constraints
|
||||
alterations := []string{
|
||||
dropDirtyColumn,
|
||||
addEditionColumn,
|
||||
setVersionNotNull,
|
||||
}
|
||||
|
||||
for _, a := range alterations {
|
||||
if _, err := p.tx.ExecContext(ctx, a); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setVersion sets the version number, and whether the database is in a dirty state.
|
||||
// A version value of -1 indicates no version is set.
|
||||
func (p *Postgres) setVersion(ctx context.Context, version int, edition string) error {
|
||||
const op = "postgres.(Postgres).setVersion"
|
||||
|
||||
if p.tx == nil {
|
||||
return errors.New(ctx, errors.MigrationIntegrity, op, "no pending transaction")
|
||||
}
|
||||
|
||||
if _, err := p.tx.ExecContext(ctx, upsertVersion, edition, version); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// EnsureMigrationLogTable ensures that the table used to record migration lgos
|
||||
// exists and is in the correct state.
|
||||
func (p *Postgres) EnsureMigrationLogTable(ctx context.Context) error {
|
||||
const op = "postgres.(Postgres).EnsureMigrationLogTable"
|
||||
|
||||
if p.tx == nil {
|
||||
return errors.New(ctx, errors.MigrationIntegrity, op, "no pending transaction")
|
||||
}
|
||||
|
||||
exists := false
|
||||
if err := p.tx.QueryRowContext(ctx, migrationLogTableExists).Scan(&exists); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
if _, err := p.tx.ExecContext(ctx, migrations.Base("postgres").CreateLogMigration); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// table exists, update it to ensure it has the correct columns and triggers
|
||||
alterations := []string{
|
||||
migrationLogAlterColumns,
|
||||
migrationLogDropTriggers,
|
||||
migrationLogAddEditionColumn,
|
||||
migrationLogReplaceVersionTrigger,
|
||||
}
|
||||
for _, a := range alterations {
|
||||
if _, err := p.tx.ExecContext(ctx, a); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMigrationLog will retrieve the migration logs from the db for the last
|
||||
// migration.
|
||||
// The WithDeleteLog option is supported and will remove all log entries,
|
||||
// after reading the entries, when provided.
|
||||
func (p *Postgres) GetMigrationLog(ctx context.Context, opt ...log.Option) ([]*log.Entry, error) {
|
||||
const op = "postgres.(Postgres).GetMigrationLog"
|
||||
|
||||
rows, err := p.conn.QueryContext(ctx, getMigrationLogs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []*log.Entry
|
||||
for rows.Next() {
|
||||
e := &log.Entry{}
|
||||
|
||||
if err := rows.Scan(&e.Id, &e.CreateTime, &e.MigrationVersion, &e.MigrationEdition, &e.Entry); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
opts := log.GetOpts(opt...)
|
||||
if opts.WithDeleteLog {
|
||||
// this truncate could change to a delete if FKs are needed in the future
|
||||
_, err = p.conn.ExecContext(ctx, truncateMigrationLogs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRun(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
|
||||
statements := bytes.NewReader([]byte(`
|
||||
create table foo (
|
||||
id bigint primary key,
|
||||
bar text
|
||||
);
|
||||
`))
|
||||
|
||||
err := p.StartRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureVersionTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.EnsureMigrationLogTable(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.Run(ctx, statements, 1001, "oss")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = p.CommitRun(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
v, i, err := p.CurrentState(ctx, "oss")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, i)
|
||||
assert.Equal(t, v, 1001)
|
||||
}
|
||||
|
||||
func TestRun_NoTxn(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, _, _ := setup(ctx, t)
|
||||
|
||||
statements := bytes.NewReader([]byte(`
|
||||
create table foo (
|
||||
id bigint primary key,
|
||||
bar text
|
||||
);
|
||||
`))
|
||||
|
||||
err := p.Run(ctx, statements, 1001, "oss")
|
||||
require.EqualError(
|
||||
t,
|
||||
err,
|
||||
fmt.Sprintf("postgres.(Postgres).Run: no pending transaction: integrity violation: error #%d", errors.MigrationIntegrity),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package postgres
|
||||
|
||||
// Queries for interacting with locks
|
||||
const (
|
||||
trySharedLock = `select pg_try_advisory_lock_shared($1)`
|
||||
tryLock = `select pg_try_advisory_lock($1)`
|
||||
lock = `select pg_advisory_lock($1)`
|
||||
unlock = `select pg_advisory_unlock($1)`
|
||||
unlockSharedLock = `select pg_advisory_unlock_shared($1)`
|
||||
)
|
||||
|
||||
// Queries for interacting with the schema version table
|
||||
const (
|
||||
schemaVersionTable = `boundary_schema_version`
|
||||
upsertVersion = `
|
||||
insert into boundary_schema_version
|
||||
(edition, version)
|
||||
values
|
||||
($1, $2)
|
||||
on conflict (edition)
|
||||
do update set
|
||||
version = $2
|
||||
;`
|
||||
|
||||
selectVersion = `
|
||||
select version
|
||||
from boundary_schema_version
|
||||
where edition = $1
|
||||
;`
|
||||
|
||||
selectOldVersion = `
|
||||
select version from schema_migrations;
|
||||
`
|
||||
|
||||
selectPreEditionVersion = `
|
||||
select max(version) from boundary_schema_version;
|
||||
`
|
||||
|
||||
tablesExist = `
|
||||
select table_name from information_schema.tables
|
||||
where table_schema = (select current_schema())
|
||||
and table_name in ('schema_migrations', 'boundary_schema_version')
|
||||
;`
|
||||
|
||||
tableExists = `
|
||||
select exists (
|
||||
select 1 from information_schema.tables
|
||||
where table_schema = (select current_schema())
|
||||
and table_name = 'boundary_schema_version'
|
||||
);`
|
||||
|
||||
oldTableExists = `
|
||||
select exists (
|
||||
select 1 from information_schema.tables
|
||||
where table_schema = (select current_schema())
|
||||
and table_name = 'schema_migrations'
|
||||
);`
|
||||
|
||||
updateTableName = `
|
||||
alter table if exists schema_migrations
|
||||
rename to boundary_schema_version
|
||||
;`
|
||||
|
||||
dropDirtyColumn = `
|
||||
alter table boundary_schema_version
|
||||
drop column if exists dirty
|
||||
;`
|
||||
|
||||
addEditionColumn = `
|
||||
alter table boundary_schema_version
|
||||
add column if not exists
|
||||
edition text default 'oss';
|
||||
alter table boundary_schema_version
|
||||
alter column edition drop default;
|
||||
alter table boundary_schema_version drop constraint if exists schema_migrations_pkey;
|
||||
alter table boundary_schema_version drop constraint if exists boundary_schema_version_pkey;
|
||||
alter table boundary_schema_version add primary key (edition);
|
||||
`
|
||||
setVersionNotNull = `
|
||||
alter table boundary_schema_version
|
||||
alter column version set not null;
|
||||
`
|
||||
)
|
||||
|
||||
// Quries for interacting with migration logs table
|
||||
const (
|
||||
migrationLogTableExists = `
|
||||
select exists (
|
||||
select 1 from information_schema.tables
|
||||
where table_schema = (select current_schema())
|
||||
and table_name = 'log_migration'
|
||||
);`
|
||||
|
||||
getMigrationLogs = `
|
||||
select
|
||||
id, create_time, migration_version, edition, entry
|
||||
from log_migration
|
||||
where
|
||||
migration_version in (
|
||||
select max(version) from boundary_schema_version
|
||||
);`
|
||||
|
||||
truncateMigrationLogs = `truncate log_migration;`
|
||||
|
||||
migrationLogAlterColumns = `
|
||||
alter table log_migration
|
||||
alter column create_time type timestamp with time zone;
|
||||
alter table log_migration
|
||||
alter column create_time set default current_timestamp;
|
||||
`
|
||||
migrationLogDropTriggers = `
|
||||
drop trigger if exists default_create_time_column on log_migration;
|
||||
drop trigger if exists immutable_columns on log_migration;
|
||||
`
|
||||
migrationLogAddEditionColumn = `
|
||||
alter table log_migration
|
||||
add column if not exists
|
||||
edition text default 'oss';
|
||||
alter table log_migration
|
||||
alter column edition drop default;
|
||||
`
|
||||
migrationLogReplaceVersionTrigger = `
|
||||
create or replace function
|
||||
log_migration_version()
|
||||
returns trigger
|
||||
as $$
|
||||
declare current_version bigint;
|
||||
begin
|
||||
select max(version)
|
||||
from boundary_schema_version into current_version
|
||||
where edition = new.edition;
|
||||
new.migration_version = current_version;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function log_migration_version() is
|
||||
'log_migration_version will set the log_migration entries to the current migration version';
|
||||
`
|
||||
)
|
||||
@@ -0,0 +1,56 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCurrentStatePreEdition(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, db, _ := setup(ctx, t)
|
||||
|
||||
_, err := db.ExecContext(ctx, `
|
||||
create table boundary_schema_version (
|
||||
version bigint primary key,
|
||||
dirty boolean not null
|
||||
);`)
|
||||
require.NoError(t, err)
|
||||
_, err = db.ExecContext(ctx, `
|
||||
insert into boundary_schema_version
|
||||
(version, dirty)
|
||||
values
|
||||
(1001, false);`)
|
||||
require.NoError(t, err)
|
||||
|
||||
version, initialized, err := p.CurrentState(ctx, "oss")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version, 1001)
|
||||
assert.True(t, initialized)
|
||||
}
|
||||
|
||||
func TestCurrentStateOldSchemaTable(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
p, db, _ := setup(ctx, t)
|
||||
|
||||
_, err := db.ExecContext(ctx, `
|
||||
create table schema_migrations (
|
||||
version bigint primary key,
|
||||
dirty boolean not null
|
||||
);`)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
_, err = db.ExecContext(ctx, `
|
||||
insert into schema_migrations
|
||||
(version, dirty)
|
||||
values
|
||||
(1001, false);`)
|
||||
require.NoError(t, err)
|
||||
|
||||
version, initialized, err := p.CurrentState(ctx, "oss")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, version, 1001)
|
||||
assert.True(t, initialized)
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package postgres_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/common"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/postgres"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// setup is a helper function for tests.
|
||||
// It creates a new database using Template1, establishes an connection,
|
||||
// and returns a *postgres.Postgrs.
|
||||
// It also returns the underlying sql.DB and connection url so tests
|
||||
// can establish additional connections if necessary.
|
||||
func setup(ctx context.Context, t *testing.T) (*postgres.Postgres, *sql.DB, string) {
|
||||
t.Helper()
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dbtest.Postgres, dbtest.WithTemplate(dbtest.Template1))
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen(dbtest.Postgres, u)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, d.Close())
|
||||
})
|
||||
p, err := postgres.New(ctx, d)
|
||||
|
||||
return p, d, u
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Package provider provides an iterator for iterating over all of the
|
||||
// migration statements that need to be applied. It will provide the statements
|
||||
// in the correct order based on the Edition priority and migration version.
|
||||
package provider
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
)
|
||||
|
||||
const nilVersion = -1
|
||||
|
||||
type migration struct {
|
||||
version int
|
||||
edition string
|
||||
statements []byte
|
||||
}
|
||||
|
||||
// Provider provides the migrations to the schema.Manager in the correct order.
|
||||
type Provider struct {
|
||||
pos int
|
||||
migrations []migration
|
||||
}
|
||||
|
||||
// DatabaseState is a map of edition names to versions.
|
||||
type DatabaseState map[string]int
|
||||
|
||||
// New creates a Provider. The given DatabaseState is compared against the editions
|
||||
// to determine which migrations need to be applied and the migrations are then ordered
|
||||
// based on the Edition priority and by the migration version.
|
||||
func New(dbState DatabaseState, editions edition.Editions) *Provider {
|
||||
m := &Provider{
|
||||
pos: -1,
|
||||
}
|
||||
|
||||
// ensure editions in priority order
|
||||
editions.Sort()
|
||||
|
||||
allMigrations := make([]migration, 0)
|
||||
|
||||
for _, e := range editions {
|
||||
dbVer, ok := dbState[e.Name]
|
||||
if !ok {
|
||||
dbVer = nilVersion
|
||||
}
|
||||
|
||||
migrations := make([]migration, 0, len(e.Migrations))
|
||||
for ver, statements := range e.Migrations {
|
||||
if ver > dbVer {
|
||||
migrations = append(migrations, migration{
|
||||
version: ver,
|
||||
edition: e.Name,
|
||||
statements: statements,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sort.SliceStable(migrations, func(i, j int) bool {
|
||||
return migrations[i].version < migrations[j].version
|
||||
})
|
||||
|
||||
allMigrations = append(allMigrations, migrations...)
|
||||
}
|
||||
|
||||
m.migrations = allMigrations
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// Next proceeds to the next migration. It returns true on success or false
|
||||
// if there are no more migrations.
|
||||
func (p *Provider) Next() bool {
|
||||
p.pos++
|
||||
return len(p.migrations) > p.pos
|
||||
}
|
||||
|
||||
// Version returns the version for the current migration.
|
||||
func (p *Provider) Version() int {
|
||||
if p.pos < 0 || p.pos >= len(p.migrations) {
|
||||
return -1
|
||||
}
|
||||
return p.migrations[p.pos].version
|
||||
}
|
||||
|
||||
// Edition returns the edition name for the current migration.
|
||||
func (p *Provider) Edition() string {
|
||||
if p.pos < 0 || p.pos >= len(p.migrations) {
|
||||
return ""
|
||||
}
|
||||
return p.migrations[p.pos].edition
|
||||
}
|
||||
|
||||
// Statements returns the sql statements name for the current migration.
|
||||
func (p *Provider) Statements() []byte {
|
||||
if p.pos < 0 || p.pos >= len(p.migrations) {
|
||||
return nil
|
||||
}
|
||||
return p.migrations[p.pos].statements
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
package provider_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/provider"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
type expectedMigration struct {
|
||||
version int
|
||||
edition string
|
||||
statements []byte
|
||||
}
|
||||
|
||||
type expectedMigrations []expectedMigration
|
||||
|
||||
func TestProvider(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
editions edition.Editions
|
||||
dbState provider.DatabaseState
|
||||
expected expectedMigrations
|
||||
}{
|
||||
{
|
||||
"oneEditionNoneApplied",
|
||||
edition.Editions{
|
||||
edition.Edition{
|
||||
Name: "one",
|
||||
LatestVersion: 2,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
2: []byte(`migration two`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
provider.DatabaseState{"one": -1},
|
||||
expectedMigrations{
|
||||
{1, "one", []byte(`migration one`)},
|
||||
{2, "one", []byte(`migration two`)},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditionsNoneApplied",
|
||||
edition.Editions{
|
||||
edition.Edition{
|
||||
Name: "one",
|
||||
LatestVersion: 2,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
2: []byte(`migration two`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
edition.Edition{
|
||||
Name: "two",
|
||||
LatestVersion: 1,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
provider.DatabaseState{
|
||||
"one": -1,
|
||||
},
|
||||
expectedMigrations{
|
||||
{1, "one", []byte(`migration one`)},
|
||||
{2, "one", []byte(`migration two`)},
|
||||
{1, "two", []byte(`migration one`)},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditionsOnePartial",
|
||||
edition.Editions{
|
||||
edition.Edition{
|
||||
Name: "one",
|
||||
LatestVersion: 2,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
2: []byte(`migration two`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
edition.Edition{
|
||||
Name: "two",
|
||||
LatestVersion: 1,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
provider.DatabaseState{
|
||||
"one": 1,
|
||||
"two": -1,
|
||||
},
|
||||
expectedMigrations{
|
||||
{2, "one", []byte(`migration two`)},
|
||||
{1, "two", []byte(`migration one`)},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditionsBothPartial",
|
||||
edition.Editions{
|
||||
edition.Edition{
|
||||
Name: "one",
|
||||
LatestVersion: 2,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
2: []byte(`migration two`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
edition.Edition{
|
||||
Name: "two",
|
||||
LatestVersion: 1,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`migration one`),
|
||||
2: []byte(`migration two`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
provider.DatabaseState{
|
||||
"one": 1,
|
||||
"two": 1,
|
||||
},
|
||||
expectedMigrations{
|
||||
{2, "one", []byte(`migration two`)},
|
||||
{2, "two", []byte(`migration two`)},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := provider.New(tt.dbState, tt.editions)
|
||||
|
||||
for _, expected := range tt.expected {
|
||||
next := p.Next()
|
||||
require.True(t, next)
|
||||
|
||||
assert.Equal(t, p.Version(), expected.version, tt.name)
|
||||
assert.Equal(t, p.Edition(), expected.edition, tt.name)
|
||||
assert.Equal(t, p.Statements(), expected.statements, tt.name)
|
||||
}
|
||||
|
||||
assert.False(t, p.Next(), tt.name)
|
||||
assert.Equal(t, p.Version(), -1, tt.name)
|
||||
assert.Equal(t, p.Edition(), "", tt.name)
|
||||
assert.Nil(t, p.Statements(), tt.name)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
+87
-121
@@ -6,11 +6,12 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/postgres"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/log"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/postgres"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/provider"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
// driver provides functionality to a database.
|
||||
@@ -20,43 +21,59 @@ type driver interface {
|
||||
Lock(context.Context) error
|
||||
Unlock(context.Context) error
|
||||
UnlockShared(context.Context) error
|
||||
// Either starts a transactioon internal to the driver or sets a dirty
|
||||
// bit so if the Run fails the CurrentState reflects it.
|
||||
// StartRun begins a transaction internal to the driver.
|
||||
StartRun(context.Context) error
|
||||
// Either commits the transaction or clears the dirty bit.
|
||||
CommitRun() error
|
||||
// Performs the mutation on the driver. This should always be
|
||||
// wrapped by StartRun and CommitRun. The driver must properly
|
||||
// handle the transaction or dirty bit in case of error when
|
||||
// executing Run.
|
||||
Run(context.Context, io.Reader, int) error
|
||||
// CommitRun commits a transaction, if there is an error it should rollback the transaction.
|
||||
CommitRun(context.Context) error
|
||||
// Run will apply a migration. The io.Reader should provide the SQL
|
||||
// statements to execute, and the int is the version for that set of
|
||||
// statements. This should always be wrapped by StartRun and CommitRun.
|
||||
Run(ctx context.Context, migration io.Reader, version int, edition string) error
|
||||
// CurrentState returns the state of the given edition.
|
||||
// ver is the current migration version number as recorded in the database.
|
||||
// A version of -1 indicates no version is set.
|
||||
CurrentState(context.Context) (ver int, everRan bool, dirty bool, err error)
|
||||
// initialized will be true if the schema was previously initialized.
|
||||
CurrentState(ctx context.Context, edition string) (version int, initialized bool, err error)
|
||||
// EnsureVersionTable ensures that the table used to record the schema versions for each edition
|
||||
// exists and is in the correct state.
|
||||
EnsureVersionTable(ctx context.Context) error
|
||||
// EnsureMigrationLogTable ensures that the table used to record migration lgos
|
||||
// exists and is in the correct state.
|
||||
EnsureMigrationLogTable(ctx context.Context) error
|
||||
// GetMigrationLog will retrieve the migration logs from the db for the last
|
||||
// migration.
|
||||
// The WithDeleteLog option is supported and will remove all log entries,
|
||||
// after reading the entries, when provided.
|
||||
GetMigrationLog(ctx context.Context, opt ...log.Option) ([]*log.Entry, error)
|
||||
}
|
||||
|
||||
// Manager provides a way to run operations and retrieve information regarding
|
||||
// the underlying boundary database schema.
|
||||
// Manager is not thread safe.
|
||||
type Manager struct {
|
||||
db *sql.DB
|
||||
driver driver
|
||||
dialect string
|
||||
migrationStates map[string]migrationState
|
||||
db *sql.DB
|
||||
driver driver
|
||||
dialect string
|
||||
editions edition.Editions
|
||||
}
|
||||
|
||||
// NewManager creates a new schema manager. An error is returned
|
||||
// if the provided dialect is unrecognized or if the passed in db is unreachable.
|
||||
func NewManager(ctx context.Context, dialect string, db *sql.DB, opt ...Option) (*Manager, error) {
|
||||
func NewManager(ctx context.Context, dialect Dialect, db *sql.DB, opt ...Option) (*Manager, error) {
|
||||
const op = "schema.NewManager"
|
||||
dbM := Manager{db: db, dialect: dialect}
|
||||
|
||||
editions.Lock()
|
||||
defer editions.Unlock()
|
||||
|
||||
dbM := Manager{db: db, dialect: string(dialect)}
|
||||
opts := getOpts(opt...)
|
||||
if opts.withMigrationStates != nil {
|
||||
dbM.migrationStates = opts.withMigrationStates
|
||||
if opts.withEditions != nil {
|
||||
dbM.editions = opts.withEditions
|
||||
} else {
|
||||
// intentionally set it to the reference, so changes to the global var
|
||||
// will be reflected in the manager instance
|
||||
dbM.migrationStates = migrationStates
|
||||
dbM.editions = make(edition.Editions, 0, len(editions.m[edition.Dialect(dialect)]))
|
||||
for _, e := range editions.m[edition.Dialect(dialect)] {
|
||||
dbM.editions = append(dbM.editions, e)
|
||||
}
|
||||
}
|
||||
switch dialect {
|
||||
case "postgres":
|
||||
@@ -71,32 +88,25 @@ func NewManager(ctx context.Context, dialect string, db *sql.DB, opt ...Option)
|
||||
return &dbM, nil
|
||||
}
|
||||
|
||||
// State contains information regarding the current state of a boundary database's schema.
|
||||
type State struct {
|
||||
// InitializationStarted indicates if the current database has been initialized previously.
|
||||
InitializationStarted bool
|
||||
// Dirty is set to true if the database failed in a previous migration/initialization.
|
||||
Dirty bool
|
||||
// DatabaseSchemaVersion is the schema version that is currently running in the database.
|
||||
DatabaseSchemaVersion int
|
||||
// BinarySchemaVersion is the schema version which this boundary binary supports.
|
||||
BinarySchemaVersion int
|
||||
}
|
||||
|
||||
// CurrentState provides the state of the boundary schema contained in the backing database.
|
||||
func (b *Manager) CurrentState(ctx context.Context) (*State, error) {
|
||||
const op = "schema.(Manager).CurrentState"
|
||||
dbS := State{
|
||||
BinarySchemaVersion: BinarySchemaVersion(b.dialect),
|
||||
var dbS State
|
||||
|
||||
for _, e := range b.editions {
|
||||
v, initialized, err := b.driver.CurrentState(ctx, e.Name)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
dbS.Initialized = initialized || dbS.Initialized
|
||||
dbS.Editions = append(dbS.Editions, EditionState{
|
||||
Name: e.Name,
|
||||
DatabaseSchemaVersion: v,
|
||||
BinarySchemaVersion: e.LatestVersion,
|
||||
DatabaseSchemaState: compareVersions(v, e.LatestVersion),
|
||||
})
|
||||
}
|
||||
|
||||
v, initialized, dirty, err := b.driver.CurrentState(ctx)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
dbS.InitializationStarted = initialized
|
||||
dbS.DatabaseSchemaVersion = v
|
||||
dbS.Dirty = dirty
|
||||
return &dbS, nil
|
||||
}
|
||||
|
||||
@@ -143,11 +153,11 @@ func (b *Manager) ExclusiveUnlock(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RollForward updates the database schema to match the latest version known by
|
||||
// ApplyMigrations updates the database schema to match the latest version known by
|
||||
// the boundary binary. An error is not returned if the database is already at
|
||||
// the most recent version.
|
||||
func (b *Manager) RollForward(ctx context.Context) error {
|
||||
const op = "schema.(Manager).RollForward"
|
||||
func (b *Manager) ApplyMigrations(ctx context.Context) error {
|
||||
const op = "schema.(Manager).ApplyMigrations"
|
||||
|
||||
// Capturing a lock that this session to the db already possesses is okay.
|
||||
if err := b.driver.Lock(ctx); err != nil {
|
||||
@@ -161,101 +171,57 @@ func (b *Manager) RollForward(ctx context.Context) error {
|
||||
}
|
||||
}()
|
||||
|
||||
curVersion, _, dirty, err := b.driver.CurrentState(ctx)
|
||||
state, err := b.CurrentState(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
if dirty {
|
||||
return errors.New(ctx, errors.NotSpecificIntegrity, op, fmt.Sprintf("schema is dirty with version %d", curVersion))
|
||||
}
|
||||
|
||||
if err = b.runMigrations(ctx, newStatementProvider(b.dialect, curVersion, WithMigrationStates(b.migrationStates))); err != nil {
|
||||
if err = b.runMigrations(ctx, provider.New(state.databaseState(), b.editions)); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type rollbacker interface {
|
||||
Rollback() error
|
||||
}
|
||||
|
||||
// runMigrations passes migration queries to a database driver and manages
|
||||
// the version and dirty bit. Cancellation or deadline/timeout is managed
|
||||
// through the passed in context.
|
||||
func (b *Manager) runMigrations(ctx context.Context, qp *statementProvider) error {
|
||||
func (b *Manager) runMigrations(ctx context.Context, p *provider.Provider) (err error) {
|
||||
const op = "schema.(Manager).runMigrations"
|
||||
|
||||
if err := b.driver.StartRun(ctx); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
if startErr := b.driver.StartRun(ctx); startErr != nil {
|
||||
err = errors.Wrap(ctx, startErr, op)
|
||||
return err
|
||||
}
|
||||
if err := b.driver.EnsureVersionTable(ctx); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
|
||||
defer func() {
|
||||
if commitErr := b.driver.CommitRun(ctx); commitErr != nil {
|
||||
err = errors.Wrap(ctx, commitErr, op)
|
||||
}
|
||||
}()
|
||||
|
||||
if ensureErr := b.driver.EnsureVersionTable(ctx); ensureErr != nil {
|
||||
err = errors.Wrap(ctx, ensureErr, op)
|
||||
return err
|
||||
}
|
||||
for qp.Next() {
|
||||
|
||||
if ensureErr := b.driver.EnsureMigrationLogTable(ctx); ensureErr != nil {
|
||||
err = errors.Wrap(ctx, ensureErr, op)
|
||||
return err
|
||||
}
|
||||
|
||||
for p.Next() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
err := ctx.Err()
|
||||
if d, ok := b.driver.(rollbacker); ok {
|
||||
if rbErr := d.Rollback(); rbErr != nil {
|
||||
err = multierror.Append(err, rbErr)
|
||||
}
|
||||
}
|
||||
return errors.Wrap(ctx, err, op)
|
||||
err = errors.Wrap(ctx, ctx.Err(), op)
|
||||
return err
|
||||
default:
|
||||
// context is not done yet. Continue on to the next query to execute.
|
||||
}
|
||||
if err := b.driver.Run(ctx, bytes.NewReader(qp.ReadUp()), qp.Version()); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
if runErr := b.driver.Run(ctx, bytes.NewReader(p.Statements()), p.Version(), p.Edition()); err != nil {
|
||||
err = errors.Wrap(ctx, runErr, op)
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := b.driver.CommitRun(); err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LogEntry represents a log entry generated during migrations.
|
||||
type LogEntry struct {
|
||||
Id int
|
||||
MigrationVersion string
|
||||
CreateTime time.Time
|
||||
Entry string
|
||||
}
|
||||
|
||||
// GetMigrationLog will retrieve the migration logs from the db for the last
|
||||
// migration. Once it's read the entries, it will delete them from the database.
|
||||
// The WithDeleteLog option is supported and will remove all log entries when provided.
|
||||
func GetMigrationLog(ctx context.Context, d *sql.DB, opt ...Option) ([]LogEntry, error) {
|
||||
const op = "schema.GetMigrationLog"
|
||||
const sql = "select id, create_time, migration_version, entry from log_migration where migration_version in (select max(version) from boundary_schema_version)"
|
||||
if d == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing sql db")
|
||||
}
|
||||
rows, err := d.QueryContext(ctx, sql)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var entries []LogEntry
|
||||
for rows.Next() {
|
||||
var e LogEntry
|
||||
if err := rows.Scan(&e.Id, &e.CreateTime, &e.MigrationVersion, &e.Entry); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
entries = append(entries, e)
|
||||
}
|
||||
if rows.Err() != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
if opts.withDeleteLog {
|
||||
// this truncate could change to a delete if FKs are needed in the future
|
||||
_, err = d.ExecContext(ctx, "truncate log_migration")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
+262
-135
@@ -1,14 +1,14 @@
|
||||
package schema
|
||||
package schema_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/common"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/postgres"
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/edition"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -27,13 +27,13 @@ func TestNewManager(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
_, err = NewManager(ctx, dialect, d)
|
||||
_, err = schema.NewManager(ctx, schema.Dialect(dialect), d)
|
||||
require.NoError(t, err)
|
||||
_, err = NewManager(ctx, "unknown", d)
|
||||
_, err = schema.NewManager(ctx, schema.Dialect("unknown"), d)
|
||||
assert.True(t, errors.Match(errors.T(errors.InvalidParameter), err))
|
||||
|
||||
d.Close()
|
||||
_, err = NewManager(ctx, dialect, d)
|
||||
_, err = schema.NewManager(ctx, schema.Dialect(dialect), d)
|
||||
assert.True(t, errors.Match(errors.T(errors.Op("schema.NewManager")), err))
|
||||
}
|
||||
|
||||
@@ -51,32 +51,232 @@ func TestCurrentState(t *testing.T) {
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err := NewManager(ctx, dialect, d)
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "oss",
|
||||
Dialect: schema.Postgres,
|
||||
LatestVersion: 2,
|
||||
Migrations: map[int][]byte{
|
||||
2: []byte(`select 1`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
))
|
||||
require.NoError(t, err)
|
||||
want := &State{
|
||||
BinarySchemaVersion: BinarySchemaVersion(dialect),
|
||||
DatabaseSchemaVersion: nilVersion,
|
||||
want := &schema.State{
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "oss",
|
||||
BinarySchemaVersion: 2,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
},
|
||||
}
|
||||
s, err := m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, want, s)
|
||||
|
||||
testDriver, err := postgres.New(ctx, d)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, testDriver.EnsureVersionTable(ctx))
|
||||
require.NoError(t, testDriver.Run(ctx, strings.NewReader("select 1"), 2))
|
||||
assert.NoError(t, m.ApplyMigrations(ctx))
|
||||
|
||||
want = &State{
|
||||
InitializationStarted: true,
|
||||
BinarySchemaVersion: BinarySchemaVersion(dialect),
|
||||
DatabaseSchemaVersion: 2,
|
||||
want = &schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "oss",
|
||||
BinarySchemaVersion: 2,
|
||||
DatabaseSchemaVersion: 2,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
}
|
||||
s, err = m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, want, s)
|
||||
assert.True(t, s.MigrationsApplied())
|
||||
}
|
||||
|
||||
func TestRollForward(t *testing.T) {
|
||||
func TestApplyMigration(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
editions edition.Editions
|
||||
expectErr bool
|
||||
state *schema.State
|
||||
}{
|
||||
{
|
||||
"oneEdition",
|
||||
edition.Editions{
|
||||
edition.New("one", schema.Postgres, one, 0),
|
||||
},
|
||||
false,
|
||||
&schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "one",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditions",
|
||||
edition.Editions{
|
||||
edition.New("one", schema.Postgres, one, 0),
|
||||
edition.New("two", schema.Postgres, two, 1),
|
||||
},
|
||||
false,
|
||||
&schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "one",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"twoEditionsIncorrectPriority",
|
||||
edition.Editions{
|
||||
edition.New("one", schema.Postgres, one, 1),
|
||||
edition.New("two", schema.Postgres, two, 0),
|
||||
},
|
||||
true,
|
||||
&schema.State{
|
||||
Initialized: false,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "one",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"threeEditions",
|
||||
edition.Editions{
|
||||
edition.New("one", schema.Postgres, one, 0),
|
||||
edition.New("two", schema.Postgres, two, 1),
|
||||
edition.New("three", schema.Postgres, three, 2),
|
||||
},
|
||||
false,
|
||||
&schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "one",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"threeEditionsIncorrectPriority",
|
||||
edition.Editions{
|
||||
edition.New("one", schema.Postgres, one, 0),
|
||||
edition.New("two", schema.Postgres, two, 2),
|
||||
edition.New("three", schema.Postgres, three, 1),
|
||||
},
|
||||
true,
|
||||
&schema.State{
|
||||
Initialized: false,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "one",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
{
|
||||
Name: "two",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
{
|
||||
Name: "three",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
|
||||
t.Cleanup(func() {
|
||||
if err := c(); err != nil {
|
||||
t.Fatalf("Got error at cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
require.NoError(t, err)
|
||||
ctx := context.Background()
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(tt.editions))
|
||||
require.NoError(t, err)
|
||||
if tt.expectErr {
|
||||
assert.Error(t, m.ApplyMigrations(ctx))
|
||||
} else {
|
||||
assert.NoError(t, m.ApplyMigrations(ctx))
|
||||
}
|
||||
|
||||
s, err := m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.state.Initialized, s.Initialized)
|
||||
assert.ElementsMatch(t, tt.state.Editions, s.Editions)
|
||||
|
||||
if tt.expectErr {
|
||||
assert.False(t, s.MigrationsApplied())
|
||||
} else {
|
||||
assert.True(t, s.MigrationsApplied())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyMigration_canceledContext(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect)
|
||||
@@ -88,87 +288,16 @@ func TestRollForward(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
m, err := NewManager(ctx, dialect, d)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, m.RollForward(ctx))
|
||||
|
||||
// Now set to dirty at an early version
|
||||
_, err = postgres.New(ctx, d)
|
||||
require.NoError(t, err)
|
||||
// TODO: Extract out a way to mock the db to test failing rollforwards.
|
||||
_, err = d.ExecContext(ctx, "TRUNCATE boundary_schema_version; INSERT INTO boundary_schema_version (version, dirty) VALUES (2, true)")
|
||||
require.NoError(t, err)
|
||||
assert.Error(t, m.RollForward(ctx))
|
||||
}
|
||||
|
||||
func TestRollForward_NotFromFresh(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
oState := migrationStates[dialect]
|
||||
|
||||
nState := createPartialMigrationState(oState, 8)
|
||||
migrationStates[dialect] = nState
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Initialize the DB with only a portion of the current sql scripts.
|
||||
ctx := context.Background()
|
||||
m, err := NewManager(ctx, dialect, d)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, m.RollForward(ctx))
|
||||
|
||||
state, err := m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, nState.binarySchemaVersion, state.DatabaseSchemaVersion)
|
||||
assert.False(t, state.Dirty)
|
||||
|
||||
// Restore the full set of sql scripts and roll the rest of the way forward.
|
||||
migrationStates[dialect] = oState
|
||||
|
||||
newM, err := NewManager(ctx, dialect, d)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, newM.RollForward(ctx))
|
||||
state, err = newM.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, oState.binarySchemaVersion, state.DatabaseSchemaVersion)
|
||||
assert.False(t, state.Dirty)
|
||||
}
|
||||
|
||||
func TestRunMigration_canceledContext(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
m, err := NewManager(ctx, dialect, d)
|
||||
require.NoError(t, err)
|
||||
|
||||
// TODO: Find a way to test different parts of the runMigrations loop.
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
cancel()
|
||||
assert.Error(t, m.runMigrations(ctx, newStatementProvider(dialect, 0)))
|
||||
assert.Error(t, m.ApplyMigrations(ctx))
|
||||
}
|
||||
|
||||
func TestRollForward_BadSQL(t *testing.T) {
|
||||
func TestApplyMigrations_BadSQL(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
oState := migrationStates[dialect]
|
||||
defer func() { migrationStates[dialect] = oState }()
|
||||
|
||||
nState := createPartialMigrationState(oState, 8)
|
||||
nState.binarySchemaVersion = 10
|
||||
nState.upMigrations[10] = []byte("SELECT 1 FROM NonExistantTable;")
|
||||
migrationStates[dialect] = nState
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
|
||||
require.NoError(t, err)
|
||||
@@ -180,14 +309,37 @@ func TestRollForward_BadSQL(t *testing.T) {
|
||||
|
||||
// Initialize the DB with only a portion of the current sql scripts.
|
||||
ctx := context.Background()
|
||||
m, err := NewManager(ctx, dialect, d)
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
|
||||
edition.Editions{
|
||||
{
|
||||
Name: "oss",
|
||||
Dialect: schema.Postgres,
|
||||
LatestVersion: 1,
|
||||
Migrations: map[int][]byte{
|
||||
1: []byte(`select 1 from nonexistanttable;`),
|
||||
},
|
||||
Priority: 0,
|
||||
},
|
||||
},
|
||||
))
|
||||
require.NoError(t, err)
|
||||
assert.Error(t, m.RollForward(ctx))
|
||||
assert.Error(t, m.ApplyMigrations(ctx))
|
||||
|
||||
state, err := m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, nilVersion, state.DatabaseSchemaVersion)
|
||||
assert.False(t, state.Dirty)
|
||||
want := &schema.State{
|
||||
Initialized: false,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "oss",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: schema.NilVersion,
|
||||
DatabaseSchemaState: schema.Behind,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, want, state)
|
||||
assert.False(t, state.MigrationsApplied())
|
||||
}
|
||||
|
||||
func TestManager_ExclusiveLock(t *testing.T) {
|
||||
@@ -201,12 +353,12 @@ func TestManager_ExclusiveLock(t *testing.T) {
|
||||
})
|
||||
d1, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
m1, err := NewManager(ctx, dialect, d1)
|
||||
m1, err := schema.NewManager(ctx, schema.Dialect(dialect), d1)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
m2, err := NewManager(ctx, dialect, d2)
|
||||
m2, err := schema.NewManager(ctx, schema.Dialect(dialect), d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NoError(t, m1.ExclusiveLock(ctx))
|
||||
@@ -224,14 +376,14 @@ func TestManager_SharedLock(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d1, err := common.SqlOpen("postgres", u)
|
||||
d1, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
m1, err := NewManager(ctx, "postgres", d1)
|
||||
m1, err := schema.NewManager(ctx, schema.Dialect(dialect), d1)
|
||||
require.NoError(t, err)
|
||||
|
||||
d2, err := common.SqlOpen("postgres", u)
|
||||
d2, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
m2, err := NewManager(ctx, "postgres", d2)
|
||||
m2, err := schema.NewManager(ctx, schema.Dialect(dialect), d2)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NoError(t, m1.SharedLock(ctx))
|
||||
@@ -253,22 +405,21 @@ func Test_GetMigrationLog(t *testing.T) {
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen("postgres", u)
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
m, err := NewManager(ctx, "postgres", d)
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, m.RollForward(ctx))
|
||||
require.NoError(t, m.ApplyMigrations(ctx))
|
||||
|
||||
const insert = `insert into log_migration(entry) values ($1)`
|
||||
const insert = `insert into log_migration(entry, edition) values ($1, $2)`
|
||||
createEntries := func(entries ...string) {
|
||||
for _, e := range entries {
|
||||
_, err := d.Exec(insert, e)
|
||||
_, err := d.Exec(insert, e, "oss")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
d *sql.DB
|
||||
setup func()
|
||||
withDeleteLog bool
|
||||
wantEntries []string
|
||||
@@ -276,21 +427,15 @@ func Test_GetMigrationLog(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "simple",
|
||||
d: d,
|
||||
setup: func() { createEntries("alice", "eve", "bob") },
|
||||
wantEntries: []string{"alice", "eve", "bob"},
|
||||
},
|
||||
{
|
||||
name: "with-delete-log",
|
||||
d: d,
|
||||
setup: func() { createEntries("alice", "eve", "bob") },
|
||||
withDeleteLog: true,
|
||||
wantEntries: []string{"alice", "eve", "bob"},
|
||||
},
|
||||
{
|
||||
name: "missing-sql-DB",
|
||||
wantErrMatch: errors.T(errors.InvalidParameter),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -303,7 +448,7 @@ func Test_GetMigrationLog(t *testing.T) {
|
||||
if tt.setup != nil {
|
||||
tt.setup()
|
||||
}
|
||||
gotLog, err := GetMigrationLog(ctx, tt.d, WithDeleteLog(tt.withDeleteLog))
|
||||
gotLog, err := m.GetMigrationLog(ctx, schema.WithDeleteLog(tt.withDeleteLog))
|
||||
if tt.wantErrMatch != nil {
|
||||
require.Error(err)
|
||||
assert.Truef(errors.Match(tt.wantErrMatch, err), "expected error with code: %s and got err: %q", tt.wantErrMatch.Code, err)
|
||||
@@ -330,21 +475,3 @@ func Test_GetMigrationLog(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a new migrationState only with the versions <= the provided maxVer
|
||||
func createPartialMigrationState(om migrationState, maxVer int) migrationState {
|
||||
nState := migrationState{
|
||||
upMigrations: make(map[int][]byte),
|
||||
}
|
||||
for k := range om.upMigrations {
|
||||
if k > maxVer {
|
||||
// Don't store any versions past our test version.
|
||||
continue
|
||||
}
|
||||
nState.upMigrations[k] = om.upMigrations[k]
|
||||
if nState.binarySchemaVersion < k {
|
||||
nState.binarySchemaVersion = k
|
||||
}
|
||||
}
|
||||
return nState
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema/internal/log"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
)
|
||||
|
||||
// LogEntry represents a log entry generated during migrations.
|
||||
type LogEntry struct {
|
||||
Id int
|
||||
MigrationVersion int
|
||||
MigrationEdition string
|
||||
CreateTime time.Time
|
||||
Entry string
|
||||
}
|
||||
|
||||
// GetMigrationLog will retrieve the migration logs from the db for the last
|
||||
// migration. Once it's read the entries, it will delete them from the database.
|
||||
// The WithDeleteLog option is supported and will remove all log entries when provided.
|
||||
func (b *Manager) GetMigrationLog(ctx context.Context, opt ...Option) ([]LogEntry, error) {
|
||||
const op = "schema.GetMigrationLog"
|
||||
|
||||
var logOpts []log.Option
|
||||
opts := getOpts(opt...)
|
||||
if opts.withDeleteLog {
|
||||
logOpts = append(logOpts, log.WithDeleteLog(opts.withDeleteLog))
|
||||
}
|
||||
|
||||
entries, err := b.driver.GetMigrationLog(ctx, logOpts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
logEntries := make([]LogEntry, 0, len(entries))
|
||||
for _, e := range entries {
|
||||
logEntries = append(logEntries, LogEntry{
|
||||
Id: e.Id,
|
||||
MigrationVersion: e.MigrationVersion,
|
||||
MigrationEdition: e.MigrationEdition,
|
||||
CreateTime: e.CreateTime,
|
||||
Entry: e.Entry,
|
||||
})
|
||||
}
|
||||
|
||||
return logEntries, nil
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
# migrations package
|
||||
This package handles the generation of the database schema in a format that can
|
||||
be compiled into the boundary binary.
|
||||
|
||||
## Organization
|
||||
|
||||
* `./generate`: contains the makefile, code, and templates needed to generate the schema info.
|
||||
* `./postgres`: contains the versioned schema folders. The contents of these folders, except
|
||||
for `dev` should not be modified.
|
||||
|
||||
## Usage
|
||||
To regenerate the schema information into the format the boundary binary uses run
|
||||
`make migrations` or `make gen` to recreate all generated code.
|
||||
|
||||
The content of the folders under `./postgres` are compiled into the
|
||||
boundary binary and when the `boundary database init` or `boundary database migrate`
|
||||
commands are executed they are applied in order of their version.
|
||||
|
||||
The `./postgres/dev` directory contains schema files that are under development and
|
||||
are not included in a release yet and so it is the only directory where additions and
|
||||
modifications are allowed. When a boundary binary is built when this directory is not
|
||||
empty a special flag is required to run the `boundary database init` command to indicate
|
||||
the user is aware that this is a development release and running this command can
|
||||
result in a completely broken schema and dataloss.
|
||||
|
||||
When a new release is made the contents of the `dev` directory are moved into a new
|
||||
versioned directory.
|
||||
@@ -0,0 +1,66 @@
|
||||
// Package migrations contains the base sql statements needed to bootstrap the
|
||||
// migration process. These statements setup the tables necessary for tracking
|
||||
// the state of migrations.
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// postgres contains the sql for creating the base tables used to manage
|
||||
// migrations.
|
||||
//go:embed base/postgres
|
||||
var postgres embed.FS
|
||||
|
||||
// Base contains the sql migrtaions needed to create the initial based tables used
|
||||
// to manage other migrations.
|
||||
// Unlike the other migrations these create statements represent the "current" state of the tables
|
||||
// and are only used on a fresh install.
|
||||
type base struct {
|
||||
CreateSchemaVersion string
|
||||
CreateLogMigration string
|
||||
}
|
||||
|
||||
var baseByDialect map[string]base
|
||||
|
||||
func stripBeginCommit(c []byte) string {
|
||||
contents := strings.TrimSpace(string(c))
|
||||
if strings.ToLower(contents[:len("begin;")]) == "begin;" {
|
||||
contents = contents[len("begin;"):]
|
||||
}
|
||||
if strings.ToLower(contents[len(contents)-len("commit;"):]) == "commit;" {
|
||||
contents = contents[:len(contents)-len("commit;")]
|
||||
}
|
||||
contents = strings.TrimSpace(contents)
|
||||
return contents
|
||||
}
|
||||
|
||||
func newBase(root string, m embed.FS) base {
|
||||
schemaVersion, err := m.ReadFile(filepath.Join(root, "01_boundary_schema_version.up.sql"))
|
||||
if err != nil {
|
||||
panic("missing base migration file 01_boundary_schema_version.up.sql")
|
||||
}
|
||||
|
||||
logMigration, err := m.ReadFile(filepath.Join(root, "02_log_migration.up.sql"))
|
||||
if err != nil {
|
||||
panic("missing base migration file 02_log_migration.up.sql")
|
||||
}
|
||||
|
||||
return base{
|
||||
CreateSchemaVersion: stripBeginCommit(schemaVersion),
|
||||
CreateLogMigration: stripBeginCommit(logMigration),
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
baseByDialect = map[string]base{
|
||||
"postgres": newBase("base/postgres", postgres),
|
||||
}
|
||||
}
|
||||
|
||||
// Base returns the base create statements for the given dialect.
|
||||
func Base(dialect string) base {
|
||||
return baseByDialect[dialect]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
begin;
|
||||
create table boundary_schema_version (
|
||||
edition text primary key,
|
||||
version bigint not null
|
||||
);
|
||||
commit;
|
||||
@@ -0,0 +1,34 @@
|
||||
begin;
|
||||
create table log_migration(
|
||||
id bigint generated always as identity primary key,
|
||||
migration_version bigint not null, -- cannot declare FK since the table is truncated during runtime
|
||||
edition text not null, -- cannot declare FK since the table is truncated during runtime
|
||||
create_time timestamp with time zone default current_timestamp,
|
||||
entry text not null
|
||||
);
|
||||
comment on table log_migration is
|
||||
'log_migration entries are logging output from database migrations';
|
||||
|
||||
create or replace function
|
||||
log_migration_version()
|
||||
returns trigger
|
||||
as $$
|
||||
declare current_version bigint;
|
||||
begin
|
||||
select max(version)
|
||||
from boundary_schema_version into current_version
|
||||
where edition = new.edition;
|
||||
new.migration_version = current_version;
|
||||
return new;
|
||||
end;
|
||||
$$ language plpgsql;
|
||||
comment on function log_migration_version() is
|
||||
'log_migration_version will set the log_migration entries to the current migration version';
|
||||
|
||||
create trigger
|
||||
version_column
|
||||
before
|
||||
insert on log_migration
|
||||
for each row execute procedure log_migration_version();
|
||||
|
||||
commit;
|
||||
@@ -1,9 +0,0 @@
|
||||
# Be sure to place this BEFORE `include` directives, if any.
|
||||
THIS_FILE := $(lastword $(MAKEFILE_LIST))
|
||||
|
||||
migrations:
|
||||
go run .
|
||||
goimports -w ${GEN_BASEPATH}/internal/db/schema
|
||||
gofumpt -w ${GEN_BASEPATH}/internal/db/schema
|
||||
|
||||
.PHONY: migrations
|
||||
@@ -1,145 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// generate looks for migration sql in a directory for the given dialect and
|
||||
// applies the templates below to the contents of the files, building up a
|
||||
// migrations map for the dialect
|
||||
func generate(dialect string) {
|
||||
baseDir := os.Getenv("GEN_BASEPATH") + "/internal/db/schema"
|
||||
srcDir := baseDir + "/migrations"
|
||||
dir, err := os.Open(fmt.Sprintf("%s/%s", srcDir, dialect))
|
||||
if err != nil {
|
||||
fmt.Printf("error opening dir with dialect %s: %v\n", dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
versions, err := dir.Readdirnames(0)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading dir names with dialect %s: %v\n", dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
sort.Strings(versions)
|
||||
|
||||
type ContentValues struct {
|
||||
Name string
|
||||
Content string
|
||||
}
|
||||
var upContents []ContentValues
|
||||
|
||||
var largestSchemaVersion int
|
||||
for _, ver := range versions {
|
||||
if strings.HasPrefix(ver, ".") {
|
||||
continue
|
||||
}
|
||||
|
||||
var verVal int
|
||||
verVal, err := strconv.Atoi(ver)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading major schema version directory %q. Must be a number: %v\n", ver, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
dir, err := os.Open(fmt.Sprintf("%s/%s/%s", srcDir, dialect, ver))
|
||||
if err != nil {
|
||||
fmt.Printf("error opening dir with dialect %s: %v\n", dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
names, err := dir.Readdirnames(0)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading dir names with dialect %s: %v\n", dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
sort.Strings(names)
|
||||
for _, name := range names {
|
||||
if !strings.HasSuffix(name, ".sql") {
|
||||
continue
|
||||
}
|
||||
|
||||
nameParts := strings.SplitN(name, "_", 2)
|
||||
if len(nameParts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
v, err := strconv.Atoi(nameParts[0])
|
||||
if err != nil {
|
||||
fmt.Printf("Unable to get file version from %q\n", name)
|
||||
continue
|
||||
}
|
||||
|
||||
fullV := (verVal * 1000) + v
|
||||
if fullV > largestSchemaVersion {
|
||||
largestSchemaVersion = fullV
|
||||
}
|
||||
|
||||
cbts, err := ioutil.ReadFile(fmt.Sprintf("%s/%s/%s/%s", srcDir, dialect, ver, name))
|
||||
if err != nil {
|
||||
fmt.Printf("error opening file %s with dialect %s: %v", name, dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
contents := strings.TrimSpace(string(cbts))
|
||||
if strings.ToLower(contents[:len("begin;")]) == "begin;" {
|
||||
contents = contents[len("begin;"):]
|
||||
}
|
||||
if strings.ToLower(contents[len(contents)-len("commit;"):]) == "commit;" {
|
||||
contents = contents[:len(contents)-len("commit;")]
|
||||
}
|
||||
contents = strings.TrimSpace(contents)
|
||||
|
||||
cv := ContentValues{
|
||||
Name: fmt.Sprint(fullV),
|
||||
Content: contents,
|
||||
}
|
||||
switch {
|
||||
case strings.Contains(nameParts[1], ".up."):
|
||||
upContents = append(upContents, cv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outBuf := bytes.NewBuffer(nil)
|
||||
if err := migrationsTemplate.Execute(outBuf, struct {
|
||||
Type string
|
||||
UpValues []ContentValues
|
||||
BinarySchemaVersion int
|
||||
}{
|
||||
Type: dialect,
|
||||
UpValues: upContents,
|
||||
BinarySchemaVersion: largestSchemaVersion,
|
||||
}); err != nil {
|
||||
fmt.Printf("error executing migrations value template for dialect %s: %s", dialect, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
outFile := fmt.Sprintf("%s/%s_migration.gen.go", baseDir, dialect)
|
||||
if err := ioutil.WriteFile(outFile, outBuf.Bytes(), 0o644); err != nil {
|
||||
fmt.Printf("error writing file %q: %v\n", outFile, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
var migrationsTemplate = template.Must(template.Must(template.New("Content").Parse(
|
||||
`{{ .Name }}: []byte(` + "`\n{{ .Content }}\n`" + `),
|
||||
`)).New("MainPage").Parse(`package schema
|
||||
|
||||
// Code generated by "make migrations"; DO NOT EDIT.
|
||||
|
||||
func init() {
|
||||
migrationStates["{{ .Type }}"] = migrationState{
|
||||
binarySchemaVersion: {{ .BinarySchemaVersion }},
|
||||
upMigrations: map[int][]byte{
|
||||
{{range .UpValues }}{{ template "Content" . }}{{end}}
|
||||
},
|
||||
}
|
||||
}
|
||||
`))
|
||||
@@ -1,5 +0,0 @@
|
||||
package main
|
||||
|
||||
func main() {
|
||||
generate("postgres")
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Package oss is used to embed the sql statements for the oss edition and
|
||||
// registering the edition for the schema.Manager.
|
||||
package oss
|
||||
|
||||
import (
|
||||
"embed"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
)
|
||||
|
||||
// postgres contains the migrations sql files for postgres oss edition
|
||||
//go:embed postgres
|
||||
var postgres embed.FS
|
||||
|
||||
func init() {
|
||||
schema.RegisterEdition("oss", schema.Postgres, postgres, 0)
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package oss_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db/common"
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
"github.com/hashicorp/boundary/testing/dbtest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
// import for init side-effects to include migrations
|
||||
_ "github.com/hashicorp/boundary/internal/db/schema/migrations/oss"
|
||||
)
|
||||
|
||||
func TestApplyMigrations(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
ctx := context.Background()
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d)
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, m.ApplyMigrations(ctx))
|
||||
}
|
||||
|
||||
func TestApplyMigrations_NotFromFresh(t *testing.T) {
|
||||
dialect := dbtest.Postgres
|
||||
|
||||
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, c())
|
||||
})
|
||||
d, err := common.SqlOpen(dialect, u)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Initialize the DB with only a portion of the current sql scripts.
|
||||
ctx := context.Background()
|
||||
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
|
||||
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": 1}),
|
||||
))
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, m.ApplyMigrations(ctx))
|
||||
|
||||
state, err := m.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
want := &schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "oss",
|
||||
BinarySchemaVersion: 1,
|
||||
DatabaseSchemaVersion: 1,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, want, state)
|
||||
|
||||
newM, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
|
||||
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": 3}),
|
||||
))
|
||||
require.NoError(t, err)
|
||||
assert.NoError(t, newM.ApplyMigrations(ctx))
|
||||
state, err = newM.CurrentState(ctx)
|
||||
require.NoError(t, err)
|
||||
want = &schema.State{
|
||||
Initialized: true,
|
||||
Editions: []schema.EditionState{
|
||||
{
|
||||
Name: "oss",
|
||||
BinarySchemaVersion: 3,
|
||||
DatabaseSchemaVersion: 3,
|
||||
DatabaseSchemaState: schema.Equal,
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, want, state)
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,54 @@
|
||||
begin;
|
||||
|
||||
-- management of the log_migation table is moved into
|
||||
-- the schema.Manager prior to migrations running
|
||||
-- since it interacts with the boundary_schema_version table
|
||||
|
||||
-- log_migration entries represent logs generated during migrations
|
||||
-- create table log_migration(
|
||||
-- id bigint generated always as identity primary key,
|
||||
-- migration_version bigint not null, -- cannot declare FK since the table is truncated during runtime
|
||||
-- create_time wt_timestamp,
|
||||
-- entry text not null
|
||||
-- );
|
||||
-- comment on table log_migration is
|
||||
-- 'log_migration entries are logging output from databaes migrations';
|
||||
--
|
||||
-- -- log_migration triggers
|
||||
-- create trigger
|
||||
-- default_create_time_column
|
||||
-- before
|
||||
-- insert on log_migration
|
||||
-- for each row execute procedure default_create_time();
|
||||
--
|
||||
-- create trigger
|
||||
-- immutable_columns
|
||||
-- before
|
||||
-- update on log_migration
|
||||
-- for each row execute procedure immutable_columns('id', 'migration_version', 'create_time', 'entry');
|
||||
--
|
||||
--
|
||||
-- -- log_migration_version() defines a function to be used in a "before update"
|
||||
-- -- trigger for log_migrations entries. Its intent: set the log_migration
|
||||
-- -- version column to the current migration version.
|
||||
-- create or replace function
|
||||
-- log_migration_version()
|
||||
-- returns trigger
|
||||
-- as $$
|
||||
-- declare current_version bigint;
|
||||
-- begin
|
||||
-- select max(version) from boundary_schema_version into current_version;
|
||||
-- new.migration_version = current_version;
|
||||
-- return new;
|
||||
-- end;
|
||||
-- $$ language plpgsql;
|
||||
-- comment on function log_migration_version() is
|
||||
-- 'log_migration_version will set the log_migration entries to the current migration version';
|
||||
--
|
||||
-- create trigger
|
||||
-- migration_version_column
|
||||
-- before
|
||||
-- insert on log_migration
|
||||
-- for each row execute procedure log_migration_version();
|
||||
--
|
||||
commit;
|
||||
File renamed without changes.
File renamed without changes.
Loaded 100 of 153 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user