github.com/weaviate/weaviate@v1.24.6/test/docker/compose.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 package docker 13 14 import ( 15 "context" 16 "fmt" 17 "os" 18 19 "github.com/pkg/errors" 20 tescontainersnetwork "github.com/testcontainers/testcontainers-go/network" 21 modstgazure "github.com/weaviate/weaviate/modules/backup-azure" 22 modstgfilesystem "github.com/weaviate/weaviate/modules/backup-filesystem" 23 modstggcs "github.com/weaviate/weaviate/modules/backup-gcs" 24 modstgs3 "github.com/weaviate/weaviate/modules/backup-s3" 25 modgenerativeanyscale "github.com/weaviate/weaviate/modules/generative-anyscale" 26 modgenerativeaws "github.com/weaviate/weaviate/modules/generative-aws" 27 modgenerativecohere "github.com/weaviate/weaviate/modules/generative-cohere" 28 modgenerativeopenai "github.com/weaviate/weaviate/modules/generative-openai" 29 modgenerativepalm "github.com/weaviate/weaviate/modules/generative-palm" 30 modmulti2vecpalm "github.com/weaviate/weaviate/modules/multi2vec-palm" 31 modqnaopenai "github.com/weaviate/weaviate/modules/qna-openai" 32 modrerankercohere "github.com/weaviate/weaviate/modules/reranker-cohere" 33 modaws "github.com/weaviate/weaviate/modules/text2vec-aws" 34 modcohere "github.com/weaviate/weaviate/modules/text2vec-cohere" 35 modhuggingface "github.com/weaviate/weaviate/modules/text2vec-huggingface" 36 modopenai "github.com/weaviate/weaviate/modules/text2vec-openai" 37 modpalm "github.com/weaviate/weaviate/modules/text2vec-palm" 38 modvoyageai "github.com/weaviate/weaviate/modules/text2vec-voyageai" 39 ) 40 41 const ( 42 // envTestWeaviateImage can be passed to tests to spin up docker compose with given image 43 envTestWeaviateImage = "TEST_WEAVIATE_IMAGE" 44 // envTestText2vecTransformersImage adds ability to pass a custom image to module tests 45 envTestText2vecTransformersImage = "TEST_TEXT2VEC_TRANSFORMERS_IMAGE" 46 // envTestText2vecContextionaryImage adds ability to pass a custom image to module tests 47 envTestText2vecContextionaryImage = "TEST_TEXT2VEC_CONTEXTIONARY_IMAGE" 48 // envTestQnATransformersImage adds ability to pass a custom image to module tests 49 envTestQnATransformersImage = "TEST_QNA_TRANSFORMERS_IMAGE" 50 // envTestSUMTransformersImage adds ability to pass a custom image to module tests 51 envTestSUMTransformersImage = "TEST_SUM_TRANSFORMERS_IMAGE" 52 // envTestMulti2VecCLIPImage adds ability to pass a custom CLIP image to module tests 53 envTestMulti2VecCLIPImage = "TEST_MULTI2VEC_CLIP_IMAGE" 54 // envTestMulti2VecBindImage adds ability to pass a custom BIND image to module tests 55 envTestMulti2VecBindImage = "TEST_MULTI2VEC_BIND_IMAGE" 56 // envTestImg2VecNeuralImage adds ability to pass a custom Im2Vec Neural image to module tests 57 envTestImg2VecNeuralImage = "TEST_IMG2VEC_NEURAL_IMAGE" 58 // envTestRerankerTransformersImage adds ability to pass a custom image to module tests 59 envTestRerankerTransformersImage = "TEST_RERANKER_TRANSFORMERS_IMAGE" 60 ) 61 62 const ( 63 Ref2VecCentroid = "ref2vec-centroid" 64 ) 65 66 type Compose struct { 67 enableModules []string 68 defaultVectorizerModule string 69 withMinIO bool 70 withGCS bool 71 withAzurite bool 72 withBackendFilesystem bool 73 withBackendS3 bool 74 withBackendS3Bucket string 75 withBackendGCS bool 76 withBackendGCSBucket string 77 withBackendAzure bool 78 withBackendAzureContainer string 79 withTransformers bool 80 withContextionary bool 81 withQnATransformers bool 82 withWeaviate bool 83 withWeaviateExposeGRPCPort bool 84 withSecondWeaviate bool 85 withWeaviateAuth bool 86 withWeaviateBasicAuth bool 87 withWeaviateBasicAuthUsername string 88 withWeaviateBasicAuthPassword string 89 withWeaviateCluster bool 90 withSUMTransformers bool 91 withCentroid bool 92 withCLIP bool 93 withMulti2VecPaLM bool 94 withPaLMApiKey string 95 withBind bool 96 withImg2Vec bool 97 withRerankerTransformers bool 98 weaviateEnvs map[string]string 99 } 100 101 func New() *Compose { 102 return &Compose{enableModules: []string{}, weaviateEnvs: make(map[string]string)} 103 } 104 105 func (d *Compose) WithMinIO() *Compose { 106 d.withMinIO = true 107 d.enableModules = append(d.enableModules, modstgs3.Name) 108 return d 109 } 110 111 func (d *Compose) WithGCS() *Compose { 112 d.withGCS = true 113 d.enableModules = append(d.enableModules, modstggcs.Name) 114 return d 115 } 116 117 func (d *Compose) WithAzurite() *Compose { 118 d.withAzurite = true 119 d.enableModules = append(d.enableModules, modstgazure.Name) 120 return d 121 } 122 123 func (d *Compose) WithText2VecTransformers() *Compose { 124 d.withTransformers = true 125 d.enableModules = append(d.enableModules, Text2VecTransformers) 126 d.defaultVectorizerModule = Text2VecTransformers 127 return d 128 } 129 130 func (d *Compose) WithText2VecContextionary() *Compose { 131 d.withContextionary = true 132 d.enableModules = append(d.enableModules, Text2VecContextionary) 133 d.defaultVectorizerModule = Text2VecContextionary 134 return d 135 } 136 137 func (d *Compose) WithQnATransformers() *Compose { 138 d.withQnATransformers = true 139 d.enableModules = append(d.enableModules, QnATransformers) 140 return d 141 } 142 143 func (d *Compose) WithBackendFilesystem() *Compose { 144 d.withBackendFilesystem = true 145 d.enableModules = append(d.enableModules, modstgfilesystem.Name) 146 return d 147 } 148 149 func (d *Compose) WithBackendS3(bucket string) *Compose { 150 d.withBackendS3 = true 151 d.withBackendS3Bucket = bucket 152 d.withMinIO = true 153 d.enableModules = append(d.enableModules, modstgs3.Name) 154 return d 155 } 156 157 func (d *Compose) WithBackendGCS(bucket string) *Compose { 158 d.withBackendGCS = true 159 d.withBackendGCSBucket = bucket 160 d.withGCS = true 161 d.enableModules = append(d.enableModules, modstggcs.Name) 162 return d 163 } 164 165 func (d *Compose) WithBackendAzure(container string) *Compose { 166 d.withBackendAzure = true 167 d.withBackendAzureContainer = container 168 d.withAzurite = true 169 d.enableModules = append(d.enableModules, modstgazure.Name) 170 return d 171 } 172 173 func (d *Compose) WithSUMTransformers() *Compose { 174 d.withSUMTransformers = true 175 d.enableModules = append(d.enableModules, SUMTransformers) 176 return d 177 } 178 179 func (d *Compose) WithMulti2VecCLIP() *Compose { 180 d.withCLIP = true 181 d.enableModules = append(d.enableModules, Multi2VecCLIP) 182 return d 183 } 184 185 func (d *Compose) WithMulti2VecPaLM(apiKey string) *Compose { 186 d.withMulti2VecPaLM = true 187 d.withPaLMApiKey = apiKey 188 d.enableModules = append(d.enableModules, modmulti2vecpalm.Name) 189 return d 190 } 191 192 func (d *Compose) WithMulti2VecBind() *Compose { 193 d.withBind = true 194 d.enableModules = append(d.enableModules, Multi2VecBind) 195 return d 196 } 197 198 func (d *Compose) WithImg2VecNeural() *Compose { 199 d.withImg2Vec = true 200 d.enableModules = append(d.enableModules, Img2VecNeural) 201 return d 202 } 203 204 func (d *Compose) WithRef2VecCentroid() *Compose { 205 d.withCentroid = true 206 d.enableModules = append(d.enableModules, Ref2VecCentroid) 207 return d 208 } 209 210 func (d *Compose) WithText2VecOpenAI() *Compose { 211 d.enableModules = append(d.enableModules, modopenai.Name) 212 return d 213 } 214 215 func (d *Compose) WithText2VecCohere() *Compose { 216 d.enableModules = append(d.enableModules, modcohere.Name) 217 return d 218 } 219 220 func (d *Compose) WithText2VecVoyageAI() *Compose { 221 d.enableModules = append(d.enableModules, modvoyageai.Name) 222 return d 223 } 224 225 func (d *Compose) WithText2VecPaLM() *Compose { 226 d.enableModules = append(d.enableModules, modpalm.Name) 227 return d 228 } 229 230 func (d *Compose) WithText2VecAWS() *Compose { 231 d.enableModules = append(d.enableModules, modaws.Name) 232 return d 233 } 234 235 func (d *Compose) WithText2VecHuggingFace() *Compose { 236 d.enableModules = append(d.enableModules, modhuggingface.Name) 237 return d 238 } 239 240 func (d *Compose) WithGenerativeOpenAI() *Compose { 241 d.enableModules = append(d.enableModules, modgenerativeopenai.Name) 242 return d 243 } 244 245 func (d *Compose) WithGenerativeAWS() *Compose { 246 d.enableModules = append(d.enableModules, modgenerativeaws.Name) 247 return d 248 } 249 250 func (d *Compose) WithGenerativeCohere() *Compose { 251 d.enableModules = append(d.enableModules, modgenerativecohere.Name) 252 return d 253 } 254 255 func (d *Compose) WithGenerativePaLM() *Compose { 256 d.enableModules = append(d.enableModules, modgenerativepalm.Name) 257 return d 258 } 259 260 func (d *Compose) WithGenerativeAnyscale() *Compose { 261 d.enableModules = append(d.enableModules, modgenerativeanyscale.Name) 262 return d 263 } 264 265 func (d *Compose) WithQnAOpenAI() *Compose { 266 d.enableModules = append(d.enableModules, modqnaopenai.Name) 267 return d 268 } 269 270 func (d *Compose) WithRerankerCohere() *Compose { 271 d.enableModules = append(d.enableModules, modrerankercohere.Name) 272 return d 273 } 274 275 func (d *Compose) WithRerankerTransformers() *Compose { 276 d.withRerankerTransformers = true 277 d.enableModules = append(d.enableModules, RerankerTransformers) 278 return d 279 } 280 281 func (d *Compose) WithWeaviate() *Compose { 282 d.withWeaviate = true 283 return d 284 } 285 286 func (d *Compose) WithWeaviateWithGRPC() *Compose { 287 d.withWeaviate = true 288 d.withWeaviateExposeGRPCPort = true 289 return d 290 } 291 292 func (d *Compose) WithSecondWeaviate() *Compose { 293 d.withSecondWeaviate = true 294 return d 295 } 296 297 func (d *Compose) WithWeaviateCluster() *Compose { 298 d.withWeaviate = true 299 d.withWeaviateCluster = true 300 return d 301 } 302 303 func (d *Compose) WithWeaviateClusterWithGRPC() *Compose { 304 d.withWeaviate = true 305 d.withWeaviateCluster = true 306 d.withWeaviateExposeGRPCPort = true 307 return d 308 } 309 310 func (d *Compose) WithWeaviateClusterWithBasicAuth(username, password string) *Compose { 311 d.withWeaviate = true 312 d.withWeaviateCluster = true 313 d.withWeaviateBasicAuth = true 314 d.withWeaviateBasicAuthUsername = username 315 d.withWeaviateBasicAuthPassword = password 316 return d 317 } 318 319 func (d *Compose) WithWeaviateAuth() *Compose { 320 d.withWeaviate = true 321 d.withWeaviateAuth = true 322 return d 323 } 324 325 func (d *Compose) WithWeaviateEnv(name, value string) *Compose { 326 d.weaviateEnvs[name] = value 327 return d 328 } 329 330 func (d *Compose) Start(ctx context.Context) (*DockerCompose, error) { 331 d.weaviateEnvs["DISABLE_TELEMETRY"] = "true" 332 network, err := tescontainersnetwork.New( 333 ctx, 334 tescontainersnetwork.WithCheckDuplicate(), 335 tescontainersnetwork.WithAttachable(), 336 ) 337 networkName := network.Name 338 if err != nil { 339 return nil, errors.Wrapf(err, "network: %s", networkName) 340 } 341 envSettings := make(map[string]string) 342 containers := []*DockerContainer{} 343 if d.withMinIO { 344 container, err := startMinIO(ctx, networkName) 345 if err != nil { 346 return nil, errors.Wrapf(err, "start %s", MinIO) 347 } 348 containers = append(containers, container) 349 if d.withBackendS3 { 350 for k, v := range container.envSettings { 351 envSettings[k] = v 352 } 353 envSettings["BACKUP_S3_BUCKET"] = d.withBackendS3Bucket 354 } 355 } 356 if d.withGCS { 357 container, err := startGCS(ctx, networkName) 358 if err != nil { 359 return nil, errors.Wrapf(err, "start %s", GCS) 360 } 361 containers = append(containers, container) 362 if d.withBackendGCS { 363 for k, v := range container.envSettings { 364 envSettings[k] = v 365 } 366 envSettings["BACKUP_GCS_BUCKET"] = d.withBackendGCSBucket 367 } 368 } 369 if d.withAzurite { 370 container, err := startAzurite(ctx, networkName) 371 if err != nil { 372 return nil, errors.Wrapf(err, "start %s", Azurite) 373 } 374 containers = append(containers, container) 375 if d.withBackendAzure { 376 for k, v := range container.envSettings { 377 envSettings[k] = v 378 } 379 envSettings["BACKUP_AZURE_CONTAINER"] = d.withBackendAzureContainer 380 } 381 } 382 if d.withBackendFilesystem { 383 envSettings["BACKUP_FILESYSTEM_PATH"] = "/tmp/backups" 384 } 385 if d.withTransformers { 386 image := os.Getenv(envTestText2vecTransformersImage) 387 container, err := startT2VTransformers(ctx, networkName, image) 388 if err != nil { 389 return nil, errors.Wrapf(err, "start %s", Text2VecTransformers) 390 } 391 for k, v := range container.envSettings { 392 envSettings[k] = v 393 } 394 containers = append(containers, container) 395 } 396 if d.withContextionary { 397 image := os.Getenv(envTestText2vecContextionaryImage) 398 container, err := startT2VContextionary(ctx, networkName, image) 399 if err != nil { 400 return nil, errors.Wrapf(err, "start %s", Text2VecContextionary) 401 } 402 for k, v := range container.envSettings { 403 envSettings[k] = v 404 } 405 containers = append(containers, container) 406 } 407 if d.withQnATransformers { 408 image := os.Getenv(envTestQnATransformersImage) 409 container, err := startQnATransformers(ctx, networkName, image) 410 if err != nil { 411 return nil, errors.Wrapf(err, "start %s", QnATransformers) 412 } 413 for k, v := range container.envSettings { 414 envSettings[k] = v 415 } 416 containers = append(containers, container) 417 } 418 if d.withSUMTransformers { 419 image := os.Getenv(envTestSUMTransformersImage) 420 container, err := startSUMTransformers(ctx, networkName, image) 421 if err != nil { 422 return nil, errors.Wrapf(err, "start %s", SUMTransformers) 423 } 424 for k, v := range container.envSettings { 425 envSettings[k] = v 426 } 427 containers = append(containers, container) 428 } 429 if d.withCLIP { 430 image := os.Getenv(envTestMulti2VecCLIPImage) 431 container, err := startM2VClip(ctx, networkName, image) 432 if err != nil { 433 return nil, errors.Wrapf(err, "start %s", Multi2VecCLIP) 434 } 435 for k, v := range container.envSettings { 436 envSettings[k] = v 437 } 438 containers = append(containers, container) 439 } 440 if d.withMulti2VecPaLM { 441 envSettings["PALM_APIKEY"] = d.withPaLMApiKey 442 } 443 if d.withBind { 444 image := os.Getenv(envTestMulti2VecBindImage) 445 container, err := startM2VBind(ctx, networkName, image) 446 if err != nil { 447 return nil, errors.Wrapf(err, "start %s", Multi2VecBind) 448 } 449 for k, v := range container.envSettings { 450 envSettings[k] = v 451 } 452 containers = append(containers, container) 453 } 454 if d.withImg2Vec { 455 image := os.Getenv(envTestImg2VecNeuralImage) 456 container, err := startI2VNeural(ctx, networkName, image) 457 if err != nil { 458 return nil, errors.Wrapf(err, "start %s", Img2VecNeural) 459 } 460 for k, v := range container.envSettings { 461 envSettings[k] = v 462 } 463 containers = append(containers, container) 464 } 465 if d.withRerankerTransformers { 466 image := os.Getenv(envTestRerankerTransformersImage) 467 container, err := startRerankerTransformers(ctx, networkName, image) 468 if err != nil { 469 return nil, errors.Wrapf(err, "start %s", RerankerTransformers) 470 } 471 for k, v := range container.envSettings { 472 envSettings[k] = v 473 } 474 containers = append(containers, container) 475 } 476 if d.withWeaviate { 477 image := os.Getenv(envTestWeaviateImage) 478 hostname := Weaviate 479 if d.withWeaviateCluster { 480 envSettings["CLUSTER_HOSTNAME"] = "node1" 481 envSettings["CLUSTER_GOSSIP_BIND_PORT"] = "7100" 482 envSettings["CLUSTER_DATA_BIND_PORT"] = "7101" 483 } 484 if d.withWeaviateBasicAuth { 485 envSettings["CLUSTER_BASIC_AUTH_USERNAME"] = d.withWeaviateBasicAuthUsername 486 envSettings["CLUSTER_BASIC_AUTH_PASSWORD"] = d.withWeaviateBasicAuthPassword 487 } 488 if d.withWeaviateAuth { 489 envSettings["AUTHENTICATION_OIDC_ENABLED"] = "true" 490 envSettings["AUTHENTICATION_OIDC_CLIENT_ID"] = "wcs" 491 envSettings["AUTHENTICATION_OIDC_ISSUER"] = "https://auth.wcs.api.semi.technology/auth/realms/SeMI" 492 envSettings["AUTHENTICATION_OIDC_USERNAME_CLAIM"] = "email" 493 envSettings["AUTHENTICATION_OIDC_GROUPS_CLAIM"] = "groups" 494 envSettings["AUTHORIZATION_ADMINLIST_ENABLED"] = "true" 495 envSettings["AUTHORIZATION_ADMINLIST_USERS"] = "ms_2d0e007e7136de11d5f29fce7a53dae219a51458@existiert.net" 496 } 497 for k, v := range d.weaviateEnvs { 498 envSettings[k] = v 499 } 500 container, err := startWeaviate(ctx, d.enableModules, d.defaultVectorizerModule, 501 envSettings, networkName, image, hostname, d.withWeaviateExposeGRPCPort) 502 if err != nil { 503 return nil, errors.Wrapf(err, "start %s", hostname) 504 } 505 containers = append(containers, container) 506 } 507 if d.withWeaviateCluster { 508 image := os.Getenv(envTestWeaviateImage) 509 hostname := WeaviateNode2 510 envSettings["CLUSTER_HOSTNAME"] = "node2" 511 envSettings["CLUSTER_GOSSIP_BIND_PORT"] = "7102" 512 envSettings["CLUSTER_DATA_BIND_PORT"] = "7103" 513 envSettings["CLUSTER_JOIN"] = fmt.Sprintf("%s:7100", Weaviate) 514 for k, v := range d.weaviateEnvs { 515 envSettings[k] = v 516 } 517 container, err := startWeaviate(ctx, d.enableModules, d.defaultVectorizerModule, 518 envSettings, networkName, image, hostname, d.withWeaviateExposeGRPCPort) 519 if err != nil { 520 return nil, errors.Wrapf(err, "start %s", hostname) 521 } 522 containers = append(containers, container) 523 } 524 525 if d.withSecondWeaviate { 526 image := os.Getenv(envTestWeaviateImage) 527 hostname := SecondWeaviate 528 secondWeaviateSettings := envSettings 529 // Ensure second weaviate doesn't get cluster settings from the first cluster if any. 530 delete(secondWeaviateSettings, "CLUSTER_HOSTNAME") 531 delete(secondWeaviateSettings, "CLUSTER_GOSSIP_BIND_PORT") 532 delete(secondWeaviateSettings, "CLUSTER_DATA_BIND_PORT") 533 delete(secondWeaviateSettings, "CLUSTER_JOIN") 534 for k, v := range d.weaviateEnvs { 535 envSettings[k] = v 536 } 537 container, err := startWeaviate(ctx, d.enableModules, d.defaultVectorizerModule, 538 envSettings, networkName, image, hostname, d.withWeaviateExposeGRPCPort) 539 if err != nil { 540 return nil, errors.Wrapf(err, "start %s", hostname) 541 } 542 containers = append(containers, container) 543 } 544 545 return &DockerCompose{network, containers}, nil 546 }