@@ -2,12 +2,10 @@ package state
2
2
3
3
import (
4
4
"context"
5
- "encoding/json"
6
5
"fmt"
7
6
"strings"
8
7
"sync"
9
8
10
- "container-registry.com/harbor-satellite/internal/config"
11
9
"container-registry.com/harbor-satellite/internal/notifier"
12
10
"container-registry.com/harbor-satellite/internal/scheduler"
13
11
"container-registry.com/harbor-satellite/internal/utils"
@@ -41,14 +39,15 @@ type FetchAndReplicateStateProcess struct {
41
39
}
42
40
43
41
type StateMap struct {
44
- url string
45
- State StateReader
42
+ url string
43
+ State StateReader
44
+ Entities []Entity
46
45
}
47
46
48
47
func NewStateMap (url []string ) []StateMap {
49
48
var stateMap []StateMap
50
49
for _ , u := range url {
51
- stateMap = append (stateMap , StateMap {url : u , State : nil })
50
+ stateMap = append (stateMap , StateMap {url : u , State : nil , Entities : nil })
52
51
}
53
52
return stateMap
54
53
}
@@ -98,7 +97,7 @@ func (f *FetchAndReplicateStateProcess) Execute(ctx context.Context) error {
98
97
return err
99
98
}
100
99
log .Info ().Msgf ("State fetched successfully for %s" , f .stateMap [i ].url )
101
- deleteEntity , replicateEntity , newState := f .GetChanges (newStateFetched , log , f .stateMap [i ].State )
100
+ deleteEntity , replicateEntity , newState := f .GetChanges (newStateFetched , log , f .stateMap [i ].Entities )
102
101
f .LogChanges (deleteEntity , replicateEntity , log )
103
102
if err := f .notifier .Notify (); err != nil {
104
103
log .Error ().Err (err ).Msg ("Error sending notification" )
@@ -117,51 +116,52 @@ func (f *FetchAndReplicateStateProcess) Execute(ctx context.Context) error {
117
116
}
118
117
// Update the state directly in the slice
119
118
f .stateMap [i ].State = newState
119
+ f .stateMap [i ].Entities = FetchEntitiesFromState (newState )
120
120
}
121
121
return nil
122
122
}
123
123
124
- func (f * FetchAndReplicateStateProcess ) GetChanges (newState StateReader , log * zerolog.Logger , oldState StateReader ) ([]ArtifactReader , []ArtifactReader , StateReader ) {
124
+ func (f * FetchAndReplicateStateProcess ) GetChanges (newState StateReader , log * zerolog.Logger , oldEntites [] Entity ) ([]Entity , []Entity , StateReader ) {
125
125
log .Info ().Msg ("Getting changes" )
126
126
// Remove artifacts with null tags from the new state
127
127
newState = f .RemoveNullTagArtifacts (newState )
128
+ newEntites := FetchEntitiesFromState (newState )
128
129
129
- var entityToDelete []ArtifactReader
130
- var entityToReplicate []ArtifactReader
130
+ var entityToDelete []Entity
131
+ var entityToReplicate []Entity
131
132
132
- if oldState == nil {
133
- log .Warn ().Msg ("Old state is nil " )
134
- return entityToDelete , newState . GetArtifacts () , newState
133
+ if oldEntites == nil {
134
+ log .Warn ().Msg ("Old state has zero entites, replicating the complete state " )
135
+ return entityToDelete , newEntites , newState
135
136
}
136
137
137
138
// Create maps for quick lookups
138
- oldArtifactsMap := make (map [string ]ArtifactReader )
139
- for _ , oldArtifact := range oldState .GetArtifacts () {
140
- tag := oldArtifact .GetTags ()[0 ]
141
- oldArtifactsMap [oldArtifact .GetName ()+ "|" + tag ] = oldArtifact
139
+ oldEntityMap := make (map [string ]Entity )
140
+ for _ , oldEntity := range oldEntites {
141
+ oldEntityMap [oldEntity .Name + "|" + oldEntity .Tag ] = oldEntity
142
142
}
143
143
144
144
// Check new artifacts and update lists
145
- for _ , newArtifact := range newState . GetArtifacts () {
146
- nameTagKey := newArtifact . GetName () + "|" + newArtifact . GetTags ()[ 0 ]
147
- oldArtifact , exists := oldArtifactsMap [nameTagKey ]
145
+ for _ , newEntity := range newEntites {
146
+ nameTagKey := newEntity . Name + "|" + newEntity . Tag
147
+ oldEntity , exists := oldEntityMap [nameTagKey ]
148
148
149
149
if ! exists {
150
150
// New artifact doesn't exist in old state, add to replication list
151
- entityToReplicate = append (entityToReplicate , newArtifact )
152
- } else if newArtifact . GetDigest () != oldArtifact . GetDigest () {
151
+ entityToReplicate = append (entityToReplicate , newEntity )
152
+ } else if newEntity . Digest != oldEntity . Digest {
153
153
// Artifact exists but has changed, add to both lists
154
- entityToReplicate = append (entityToReplicate , newArtifact )
155
- entityToDelete = append (entityToDelete , oldArtifact )
154
+ entityToReplicate = append (entityToReplicate , newEntity )
155
+ entityToDelete = append (entityToDelete , oldEntity )
156
156
}
157
157
158
158
// Remove processed old artifact from map
159
- delete (oldArtifactsMap , nameTagKey )
159
+ delete (oldEntityMap , nameTagKey )
160
160
}
161
161
162
162
// Remaining artifacts in oldArtifactsMap should be deleted
163
- for _ , oldArtifact := range oldArtifactsMap {
164
- entityToDelete = append (entityToDelete , oldArtifact )
163
+ for _ , oldEntity := range oldEntityMap {
164
+ entityToDelete = append (entityToDelete , oldEntity )
165
165
}
166
166
167
167
return entityToDelete , entityToReplicate , newState
@@ -239,17 +239,6 @@ func (f *FetchAndReplicateStateProcess) RemoveNullTagArtifacts(state StateReader
239
239
return state
240
240
}
241
241
242
- func PrintPrettyJson (info interface {}, log * zerolog.Logger , message string ) error {
243
- log .Warn ().Msg ("Printing pretty JSON" )
244
- stateJSON , err := json .MarshalIndent (info , "" , " " )
245
- if err != nil {
246
- log .Error ().Err (err ).Msg ("Error marshalling state to JSON" )
247
- return err
248
- }
249
- log .Info ().Msgf ("%s: %s" , message , stateJSON )
250
- return nil
251
- }
252
-
253
242
func ProcessState (state * StateReader ) (* StateReader , error ) {
254
243
for _ , artifact := range (* state ).GetArtifacts () {
255
244
repo , image , err := utils .GetRepositoryAndImageNameFromArtifact (artifact .GetRepository ())
@@ -274,50 +263,24 @@ func (f *FetchAndReplicateStateProcess) FetchAndProcessState(fetcher StateFetche
274
263
return state , nil
275
264
}
276
265
277
- func (f * FetchAndReplicateStateProcess ) LogChanges (deleteEntity , replicateEntity []ArtifactReader , log * zerolog.Logger ) {
266
+ func (f * FetchAndReplicateStateProcess ) LogChanges (deleteEntity , replicateEntity []Entity , log * zerolog.Logger ) {
278
267
log .Warn ().Msgf ("Total artifacts to delete: %d" , len (deleteEntity ))
279
268
log .Warn ().Msgf ("Total artifacts to replicate: %d" , len (replicateEntity ))
280
269
}
281
270
282
- func processInput (input , username , password string , log * zerolog.Logger ) (StateFetcher , error ) {
283
-
284
- if utils .IsValidURL (input ) {
285
- return processURLInput (utils .FormatRegistryURL (input ), username , password , log )
286
- }
287
-
288
- log .Info ().Msg ("Input is not a valid URL, checking if it is a file path" )
289
- if err := validateFilePath (input , log ); err != nil {
290
- return nil , err
291
- }
292
-
293
- return processFileInput (input , username , password , log )
294
- }
295
-
296
- func validateFilePath (path string , log * zerolog.Logger ) error {
297
- if utils .HasInvalidPathChars (path ) {
298
- log .Error ().Msg ("Path contains invalid characters" )
299
- return fmt .Errorf ("invalid file path: %s" , path )
300
- }
301
- if err := utils .GetAbsFilePath (path ); err != nil {
302
- log .Error ().Err (err ).Msg ("No file found" )
303
- return fmt .Errorf ("no file found: %s" , path )
271
+ func FetchEntitiesFromState (state StateReader ) []Entity {
272
+ var entities []Entity
273
+ for _ , artifact := range state .GetArtifacts () {
274
+ for _ , tag := range artifact .GetTags () {
275
+ entities = append (entities , Entity {
276
+ Name : artifact .GetName (),
277
+ Repository : artifact .GetRepository (),
278
+ Tag : tag ,
279
+ Digest : artifact .GetDigest (),
280
+ })
281
+ }
304
282
}
305
- return nil
306
- }
307
-
308
- func processURLInput (input , username , password string , log * zerolog.Logger ) (StateFetcher , error ) {
309
- log .Info ().Msg ("Input is a valid URL" )
310
- config .SetRemoteRegistryURL (input )
311
-
312
- stateArtifactFetcher := NewURLStateFetcher (input , username , password )
313
-
314
- return stateArtifactFetcher , nil
315
- }
316
-
317
- func processFileInput (input , username , password string , log * zerolog.Logger ) (StateFetcher , error ) {
318
- log .Info ().Msg ("Input is a valid file path" )
319
- stateArtifactFetcher := NewFileStateFetcher (input , username , password )
320
- return stateArtifactFetcher , nil
283
+ return entities
321
284
}
322
285
323
286
func (f * FetchAndReplicateStateProcess ) AddEventBroker (eventBroker * scheduler.EventBroker , ctx context.Context ) {
0 commit comments