@@ -5,27 +5,22 @@ import * as core from '@actions/core'
55import * as cache from '@actions/cache'
66import { ExecOptions } from '@actions/exec/lib/interfaces'
77import { promises as fs } from 'fs'
8- import { assertManifests , Manifest , Manifests } from './Tar'
8+ import { assertManifests , Manifest , Manifests , loadManifests , loadRawManifests } from './Tar'
99import format from 'string-format'
1010import PromisePool from 'native-promise-pool'
1111
1212class LayerCache {
13- // repotag: string
14- ids : string [ ]
15- unformattedOrigianlKey : string = ''
16- restoredOriginalKey ?: string
17- // tarFile: string = ''
13+ ids : string [ ] = [ ]
14+ unformattedSaveKey : string = ''
15+ restoredRootKey : string = ''
1816 imagesDir : string = path . resolve ( `${ process . cwd ( ) } /./.action-docker-layer-caching-docker_images` )
1917 enabledParallel = true
20- // unpackedTarDir: string = ''
21- // manifests: Manifests = []
2218 concurrency : number = 4
2319
2420 static ERROR_CACHE_ALREAD_EXISTS_STR = `Cache already exists`
2521 static ERROR_LAYER_CACHE_NOT_FOUND_STR = `Layer cache not found`
2622
2723 constructor ( ids : string [ ] ) {
28- // this.repotag = repotag
2924 this . ids = ids
3025 }
3126
@@ -39,10 +34,8 @@ class LayerCache {
3934 }
4035
4136 async store ( key : string ) {
42- this . unformattedOrigianlKey = key
43- // this.originalKeyToStore = format(key, {
44- // hash: this.getIdhashesPathFriendly()
45- // })
37+ this . unformattedSaveKey = key
38+
4639 await this . saveImageAsUnpacked ( )
4740 if ( this . enabledParallel ) {
4841 await this . separateAllLayerCaches ( )
@@ -76,13 +69,11 @@ class LayerCache {
7669 }
7770
7871 private async getManifests ( ) {
79- const manifests = JSON . parse ( ( await fs . readFile ( `${ this . getUnpackedTarDir ( ) } /manifest.json` ) ) . toString ( ) )
80- assertManifests ( manifests )
81- return manifests
72+ return loadManifests ( this . getUnpackedTarDir ( ) )
8273 }
8374
8475 private async storeRoot ( ) {
85- const rootKey = this . getRootKey ( )
76+ const rootKey = await this . generateRootSaveKey ( )
8677 const paths = [
8778 this . getUnpackedTarDir ( ) ,
8879 ]
@@ -143,7 +134,7 @@ class LayerCache {
143134
144135 private async storeSingleLayerBy ( id : string ) : Promise < number > {
145136 const path = this . genSingleLayerStorePath ( id )
146- const key = this . genSingleLayerStoreKey ( id )
137+ const key = await this . generateSingleLayerSaveKey ( id )
147138
148139 core . info ( `Start storing layer cache: ${ key } ` )
149140 const cacheId = await LayerCache . dismissError ( cache . saveCache ( [ path ] , key ) , LayerCache . ERROR_CACHE_ALREAD_EXISTS_STR , - 1 )
@@ -155,8 +146,6 @@ class LayerCache {
155146 // ---
156147
157148 async restore ( key : string , restoreKeys ?: string [ ] ) {
158- this . unformattedOrigianlKey = key
159- // const restoreKeysIncludedRootKey = [key, ...(restoreKeys !== undefined ? restoreKeys : [])]
160149 const restoredCacheKey = await this . restoreRoot ( restoreKeys )
161150 if ( restoredCacheKey === undefined ) {
162151 core . info ( `Root cache could not be found. aborting.` )
@@ -175,14 +164,13 @@ class LayerCache {
175164 }
176165
177166 private async restoreRoot ( restoreKeys ?: string [ ] ) : Promise < string | undefined > {
178- core . debug ( `Trying to restore root cache: ${ JSON . stringify ( { primaryKey : this . getRootKey ( ) , restoreKeys, dir : this . getUnpackedTarDir ( ) } ) } ` )
179- const restoredCacheKeyMayUndefined = await cache . restoreCache ( [ this . getUnpackedTarDir ( ) ] , this . getRootKey ( ) , restoreKeys )
180- core . debug ( `restoredCacheKeyMayUndefined : ${ restoredCacheKeyMayUndefined } ` )
181- if ( restoredCacheKeyMayUndefined === undefined ) {
167+ core . debug ( `Trying to restore root cache: ${ JSON . stringify ( { restoreKeys, dir : this . getUnpackedTarDir ( ) } ) } ` )
168+ const restoredRootKey = await cache . restoreCache ( [ this . getUnpackedTarDir ( ) ] , `` , restoreKeys )
169+ core . debug ( `restoredRootKey : ${ restoredRootKey } ` )
170+ if ( restoredRootKey === undefined ) {
182171 return undefined
183172 }
184- this . restoredOriginalKey = restoredCacheKeyMayUndefined . replace ( / - r o o t $ / , '' )
185- return this . restoredOriginalKey
173+ this . restoredRootKey = restoredRootKey
186174 }
187175
188176 private async restoreLayers ( ) : Promise < boolean > {
@@ -208,7 +196,7 @@ class LayerCache {
208196 private async restoreSingleLayerBy ( id : string ) : Promise < string > {
209197 core . debug ( JSON . stringify ( { log : `restoreSingleLayerBy` , id } ) )
210198
211- const result = await cache . restoreCache ( [ this . genSingleLayerStorePath ( id ) ] , this . genSingleLayerStoreKey ( id ) )
199+ const result = await cache . restoreCache ( [ this . genSingleLayerStorePath ( id ) ] , await this . recoverSingleLayerKey ( id ) )
212200
213201 if ( result == null ) {
214202 throw new Error ( `${ LayerCache . ERROR_LAYER_CACHE_NOT_FOUND_STR } : ${ JSON . stringify ( { id } ) } ` )
@@ -247,33 +235,51 @@ class LayerCache {
247235 return 'image'
248236 }
249237
250- getIdhashesPathFriendly ( ) : string {
251- const result = crypto . createHash ( `sha256` ) . update ( this . ids . join ( `-` ) , `utf8` ) . digest ( `hex` )
238+ async getIdhashesPathFriendly ( ) : Promise < string > {
239+ const result = crypto . createHash ( `sha256` ) . update ( ( await this . getLayerIds ( ) ) . join ( `-` ) , `utf8` ) . digest ( `hex` )
252240 core . debug ( JSON . stringify ( { log : `getIdhashesPathFriendly` , result } ) )
253241 return result
254242 }
255243
256- getRootKey ( ) : string {
257- return `${ this . getFormattedOriginalCacheKey ( ) } -root`
258- }
259244
260245 genSingleLayerStorePath ( id : string ) {
261246 return `${ this . getLayerCachesDir ( ) } /${ id } /layer.tar`
262247 }
263248
264- genSingleLayerStoreKey ( id : string ) {
265- const singleLayerStoreKey = this . getFormattedOriginalCacheKey ( id )
266- core . debug ( JSON . stringify ( { log : `genSingleLayerStoreKey` , singleLayerStoreKey, id } ) )
267- return `layer-${ singleLayerStoreKey } `
249+ async generateRootHashFromManifest ( ) : Promise < string > {
250+ const manifest = await loadRawManifests ( this . getUnpackedTarDir ( ) )
251+ return crypto . createHash ( `sha256` ) . update ( manifest , `utf8` ) . digest ( `hex` )
268252 }
269253
270- getFormattedOriginalCacheKey ( hashThatMayBeSpecified ?: string ) {
271- const hash = hashThatMayBeSpecified !== undefined ? hashThatMayBeSpecified : this . getIdhashesPathFriendly ( )
272- const result = format ( this . unformattedOrigianlKey , { hash } )
273- core . debug ( JSON . stringify ( { log : `getFormattedOriginalCacheKey` , hash, hashThatMayBeSpecified, result } ) )
254+ async generateRootSaveKey ( ) : Promise < string > {
255+ const rootHash = await this . generateRootHashFromManifest ( )
256+ const formatted = await this . getFormattedSaveKey ( rootHash )
257+ core . debug ( JSON . stringify ( { log : `generateRootSaveKey` , rootHash, formatted } ) )
258+ return `${ formatted } -root`
259+ }
260+
261+ async generateSingleLayerSaveKey ( id : string ) {
262+ const formatted = await this . getFormattedSaveKey ( id )
263+ core . debug ( JSON . stringify ( { log : `generateSingleLayerSaveKey` , formatted, id } ) )
264+ return `layer-${ formatted } `
265+ }
266+
267+ async recoverSingleLayerKey ( id : string ) {
268+ const unformatted = await this . recoverUnformattedSaveKey ( )
269+ return format ( unformatted , { hash : id } )
270+ }
271+
272+ async getFormattedSaveKey ( hash : string ) {
273+ const result = format ( this . unformattedSaveKey , { hash } )
274+ core . debug ( JSON . stringify ( { log : `getFormattedSaveKey` , hash, result } ) )
274275 return result
275276 }
276277
278+ async recoverUnformattedSaveKey ( ) {
279+ const hash = await loadRawManifests ( this . getUnpackedTarDir ( ) )
280+ return this . restoredRootKey . replace ( hash , `{hash}` )
281+ }
282+
277283 async getLayerTarFiles ( ) : Promise < string [ ] > {
278284 const getTarFilesFromManifest = ( manifest : Manifest ) => manifest . Layers
279285
0 commit comments