zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/scrub/scrub_test.go (about) 1 //go:build scrub 2 // +build scrub 3 4 package scrub_test 5 6 import ( 7 "context" 8 "fmt" 9 "os" 10 "path" 11 "testing" 12 "time" 13 14 . "github.com/smartystreets/goconvey/convey" 15 16 "zotregistry.dev/zot/pkg/api" 17 "zotregistry.dev/zot/pkg/api/config" 18 extconf "zotregistry.dev/zot/pkg/extensions/config" 19 "zotregistry.dev/zot/pkg/extensions/monitoring" 20 "zotregistry.dev/zot/pkg/extensions/scrub" 21 "zotregistry.dev/zot/pkg/log" 22 "zotregistry.dev/zot/pkg/storage" 23 "zotregistry.dev/zot/pkg/storage/cache" 24 "zotregistry.dev/zot/pkg/storage/local" 25 test "zotregistry.dev/zot/pkg/test/common" 26 . "zotregistry.dev/zot/pkg/test/image-utils" 27 ociutils "zotregistry.dev/zot/pkg/test/oci-utils" 28 ) 29 30 const ( 31 repoName = "test" 32 ) 33 34 func TestScrubExtension(t *testing.T) { 35 Convey("Blobs integrity not affected", t, func(c C) { 36 port := test.GetFreePort() 37 38 logFile, err := os.CreateTemp("", "zot-log*.txt") 39 So(err, ShouldBeNil) 40 41 defer os.Remove(logFile.Name()) // clean up 42 43 conf := config.New() 44 conf.HTTP.Port = port 45 46 dir := t.TempDir() 47 subdir := t.TempDir() 48 49 conf.Storage.RootDirectory = dir 50 conf.Storage.Dedupe = false 51 conf.Storage.GC = false 52 53 substore := config.StorageConfig{RootDirectory: subdir} 54 conf.Storage.SubPaths = map[string]config.StorageConfig{"/a": substore} 55 conf.Log.Output = logFile.Name() 56 trueValue := true 57 scrubConfig := &extconf.ScrubConfig{ 58 BaseConfig: extconf.BaseConfig{Enable: &trueValue}, 59 Interval: 2, 60 } 61 conf.Extensions = &extconf.ExtensionConfig{ 62 Scrub: scrubConfig, 63 } 64 65 ctlr := api.NewController(conf) 66 67 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log.NewLogger("debug", "")) 68 err = WriteImageToFileSystem(CreateDefaultVulnerableImage(), repoName, "0.0.1", srcStorageCtlr) 69 So(err, ShouldBeNil) 70 71 cm := test.NewControllerManager(ctlr) 72 cm.StartAndWait(port) 73 defer cm.StopServer() 74 75 found, err := test.ReadLogFileAndSearchString(logFile.Name(), "blobs/manifest ok", 60*time.Second) 76 So(found, ShouldBeTrue) 77 So(err, ShouldBeNil) 78 }) 79 80 Convey("Blobs integrity affected", t, func(c C) { 81 port := test.GetFreePort() 82 83 logFile, err := os.CreateTemp("", "zot-log*.txt") 84 So(err, ShouldBeNil) 85 86 defer os.Remove(logFile.Name()) // clean up 87 88 conf := config.New() 89 conf.HTTP.Port = port 90 91 dir := t.TempDir() 92 93 conf.Storage.RootDirectory = dir 94 conf.Storage.Dedupe = false 95 conf.Storage.GC = false 96 97 conf.Log.Output = logFile.Name() 98 trueValue := true 99 scrubConfig := &extconf.ScrubConfig{ 100 BaseConfig: extconf.BaseConfig{Enable: &trueValue}, 101 Interval: 2, 102 } 103 conf.Extensions = &extconf.ExtensionConfig{ 104 Scrub: scrubConfig, 105 } 106 107 ctlr := api.NewController(conf) 108 109 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log.NewLogger("debug", "")) 110 image := CreateDefaultVulnerableImage() 111 err = WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr) 112 So(err, ShouldBeNil) 113 114 layerDigest := image.Manifest.Layers[0].Digest 115 116 err = os.Remove(path.Join(dir, repoName, "blobs/sha256", layerDigest.Encoded())) 117 if err != nil { 118 panic(err) 119 } 120 121 cm := test.NewControllerManager(ctlr) 122 cm.StartAndWait(port) 123 defer cm.StopServer() 124 125 found, err := test.ReadLogFileAndSearchString(logFile.Name(), "blobs/manifest affected", 60*time.Second) 126 So(found, ShouldBeTrue) 127 So(err, ShouldBeNil) 128 }) 129 130 Convey("Generator error - not enough permissions to access root directory", t, func(c C) { 131 port := test.GetFreePort() 132 133 logFile, err := os.CreateTemp("", "zot-log*.txt") 134 So(err, ShouldBeNil) 135 136 defer os.Remove(logFile.Name()) // clean up 137 138 conf := config.New() 139 conf.HTTP.Port = port 140 141 dir := t.TempDir() 142 143 conf.Storage.RootDirectory = dir 144 conf.Storage.Dedupe = false 145 conf.Storage.GC = false 146 147 conf.Log.Output = logFile.Name() 148 trueValue := true 149 scrubConfig := &extconf.ScrubConfig{ 150 BaseConfig: extconf.BaseConfig{Enable: &trueValue}, 151 Interval: 2, 152 } 153 conf.Extensions = &extconf.ExtensionConfig{ 154 Scrub: scrubConfig, 155 } 156 157 ctlr := api.NewController(conf) 158 159 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log.NewLogger("debug", "")) 160 image := CreateDefaultVulnerableImage() 161 162 err = WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr) 163 So(err, ShouldBeNil) 164 165 So(os.Chmod(path.Join(dir, repoName), 0o000), ShouldBeNil) 166 167 cm := test.NewControllerManager(ctlr) 168 cm.StartAndWait(port) 169 defer cm.StopServer() 170 171 found, err := test.ReadLogFileAndSearchString(logFile.Name(), "failed to execute generator", 60*time.Second) 172 So(found, ShouldBeTrue) 173 So(err, ShouldBeNil) 174 175 So(os.Chmod(path.Join(dir, repoName), 0o755), ShouldBeNil) 176 }) 177 } 178 179 func TestRunScrubRepo(t *testing.T) { 180 Convey("Blobs integrity not affected", t, func(c C) { 181 logFile, err := os.CreateTemp("", "zot-log*.txt") 182 So(err, ShouldBeNil) 183 184 defer os.Remove(logFile.Name()) // clean up 185 186 conf := config.New() 187 conf.Extensions = &extconf.ExtensionConfig{} 188 conf.Extensions.Lint = &extconf.LintConfig{} 189 190 dir := t.TempDir() 191 log := log.NewLogger("debug", logFile.Name()) 192 metrics := monitoring.NewMetricsServer(false, log) 193 cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{ 194 RootDir: dir, 195 Name: "cache", 196 UseRelPaths: true, 197 }, log) 198 imgStore := local.NewImageStore(dir, true, 199 true, log, metrics, nil, cacheDriver) 200 201 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log) 202 image := CreateDefaultVulnerableImage() 203 204 err = WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr) 205 So(err, ShouldBeNil) 206 207 err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log) 208 So(err, ShouldBeNil) 209 210 data, err := os.ReadFile(logFile.Name()) 211 So(err, ShouldBeNil) 212 So(string(data), ShouldContainSubstring, "blobs/manifest ok") 213 }) 214 215 Convey("Blobs integrity affected", t, func(c C) { 216 logFile, err := os.CreateTemp("", "zot-log*.txt") 217 So(err, ShouldBeNil) 218 219 defer os.Remove(logFile.Name()) // clean up 220 221 conf := config.New() 222 223 conf.Extensions = &extconf.ExtensionConfig{} 224 conf.Extensions.Lint = &extconf.LintConfig{} 225 226 dir := t.TempDir() 227 log := log.NewLogger("debug", logFile.Name()) 228 metrics := monitoring.NewMetricsServer(false, log) 229 cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{ 230 RootDir: dir, 231 Name: "cache", 232 UseRelPaths: true, 233 }, log) 234 imgStore := local.NewImageStore(dir, true, 235 true, log, metrics, nil, cacheDriver) 236 237 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log) 238 image := CreateDefaultVulnerableImage() 239 240 err = WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr) 241 So(err, ShouldBeNil) 242 243 layerDigest := image.Manifest.Layers[0].Digest 244 245 err = os.Remove(path.Join(dir, repoName, "blobs/sha256", layerDigest.Encoded())) 246 if err != nil { 247 panic(err) 248 } 249 250 err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log) 251 So(err, ShouldBeNil) 252 253 data, err := os.ReadFile(logFile.Name()) 254 So(err, ShouldBeNil) 255 So(string(data), ShouldContainSubstring, "blobs/manifest affected") 256 }) 257 258 Convey("CheckRepo error - not enough permissions to access root directory", t, func(c C) { 259 logFile, err := os.CreateTemp("", "zot-log*.txt") 260 So(err, ShouldBeNil) 261 262 defer os.Remove(logFile.Name()) // clean up 263 264 conf := config.New() 265 conf.Extensions = &extconf.ExtensionConfig{} 266 conf.Extensions.Lint = &extconf.LintConfig{} 267 268 dir := t.TempDir() 269 log := log.NewLogger("debug", logFile.Name()) 270 metrics := monitoring.NewMetricsServer(false, log) 271 cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{ 272 RootDir: dir, 273 Name: "cache", 274 UseRelPaths: true, 275 }, log) 276 imgStore := local.NewImageStore(dir, true, true, log, metrics, nil, cacheDriver) 277 278 srcStorageCtlr := ociutils.GetDefaultStoreController(dir, log) 279 image := CreateDefaultVulnerableImage() 280 281 err = WriteImageToFileSystem(image, repoName, "0.0.1", srcStorageCtlr) 282 So(err, ShouldBeNil) 283 284 So(os.Chmod(path.Join(dir, repoName), 0o000), ShouldBeNil) 285 286 err = scrub.RunScrubRepo(context.Background(), imgStore, repoName, log) 287 So(err, ShouldNotBeNil) 288 289 data, err := os.ReadFile(logFile.Name()) 290 So(err, ShouldBeNil) 291 So(string(data), ShouldContainSubstring, 292 fmt.Sprintf("failed to run scrub for %s", imgStore.RootDir())) 293 So(os.Chmod(path.Join(dir, repoName), 0o755), ShouldBeNil) 294 }) 295 }