├── .codespellignore
├── .editorconfig
├── .github
├── actions
│ ├── deploy
│ │ └── action.yml
│ └── spelling
│ │ └── allow.txt
└── workflows
│ ├── build-singularity.yml
│ ├── build.yml
│ ├── codespell.yml
│ ├── pre-commit.yml.bak
│ ├── security-submit-dependecy-graph.yml
│ ├── seqera_docs_changelog.yml
│ └── typespec.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .prettierignore
├── .prettierrc
├── LICENSE
├── Makefile
├── README.md
├── VERSION
├── build.gradle
├── buildSrc
├── build.gradle
└── src
│ └── main
│ └── groovy
│ ├── io.seqera.wave.groovy-application-conventions.gradle
│ ├── io.seqera.wave.groovy-common-conventions.gradle
│ ├── io.seqera.wave.groovy-library-conventions.gradle
│ └── io.seqera.wave.java-library-conventions.gradle
├── changelog.txt
├── config.yml
├── container-request.json
├── debug.sh
├── docs.sh
├── docs
├── _images
│ ├── wave_container_augmentation.png
│ └── wave_container_build_failure_details.png
├── api.mdx
├── cli
│ ├── index.mdx
│ └── reference.mdx
├── configuration.mdx
├── faq.mdx
├── get-started.mdx
├── index.mdx
├── metrics.mdx
├── nextflow.mdx
├── provisioning.mdx
├── sidebar.json
└── troubleshoot.mdx
├── gradle.properties
├── gradle
├── config
│ └── groovyc.groovy
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── misc
├── image-config.json
├── image-config.v2.json
├── manifest-v1-319b8d4eca0fc0367d192941f221f7fcd29a6b96996c63cbf8931dbb66e53348.json
├── resp2.975f4b14f326b05db86e16de00144f9c12257553bba9484fed41f9b6f2257800.json
├── resp2.formatted.json
├── resp3.f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4.json
├── resp3.formatted.json
├── resp4.feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412.json
├── resp4.formatted.json
└── tldr.md
├── reg.sh
├── run.sh
├── s5cmd
├── Dockerfile
├── Makefile
└── dist.sh
├── settings.gradle
├── singularity
├── Dockerfile
└── Makefile
├── src
├── main
│ ├── groovy
│ │ └── io
│ │ │ └── seqera
│ │ │ ├── util
│ │ │ └── trace
│ │ │ │ ├── TraceElapsedTime.groovy
│ │ │ │ └── TraceElapsedTimeInterceptor.groovy
│ │ │ └── wave
│ │ │ ├── Application.groovy
│ │ │ ├── Bootstrap.groovy
│ │ │ ├── ErrorHandler.groovy
│ │ │ ├── WaveDefault.groovy
│ │ │ ├── auth
│ │ │ ├── BasicAuthenticationProvider.groovy
│ │ │ ├── MissingCredentials.groovy
│ │ │ ├── RegistryAuth.groovy
│ │ │ ├── RegistryAuthService.groovy
│ │ │ ├── RegistryAuthServiceImpl.groovy
│ │ │ ├── RegistryConfig.groovy
│ │ │ ├── RegistryCredentials.groovy
│ │ │ ├── RegistryCredentialsFactory.groovy
│ │ │ ├── RegistryCredentialsFactoryImpl.groovy
│ │ │ ├── RegistryCredentialsProvider.groovy
│ │ │ ├── RegistryCredentialsProviderImpl.groovy
│ │ │ ├── RegistryInfo.groovy
│ │ │ ├── RegistryLookupCache.groovy
│ │ │ ├── RegistryLookupException.groovy
│ │ │ ├── RegistryLookupService.groovy
│ │ │ ├── RegistryLookupServiceImpl.groovy
│ │ │ ├── RegistryTokenStore.groovy
│ │ │ └── RegistryUtils.groovy
│ │ │ ├── configuration
│ │ │ ├── BlobCacheConfig.groovy
│ │ │ ├── BuildConfig.groovy
│ │ │ ├── HttpClientConfig.groovy
│ │ │ ├── JobManagerConfig.groovy
│ │ │ ├── LimitConfig.groovy
│ │ │ ├── MirrorConfig.groovy
│ │ │ ├── ProxyCacheConfig.groovy
│ │ │ ├── RateLimitConverter.groovy
│ │ │ ├── RateLimiterConfig.groovy
│ │ │ ├── RedisConfig.groovy
│ │ │ ├── ScanConfig.groovy
│ │ │ └── TokenConfig.groovy
│ │ │ ├── controller
│ │ │ ├── BuildController.groovy
│ │ │ ├── ContainerController.groovy
│ │ │ ├── ErrorController.groovy
│ │ │ ├── InspectController.groovy
│ │ │ ├── MetricsController.groovy
│ │ │ ├── MirrorController.groovy
│ │ │ ├── RegistryProxyController.groovy
│ │ │ ├── ScanController.groovy
│ │ │ ├── ServiceInfoController.groovy
│ │ │ ├── ValidateController.groovy
│ │ │ ├── ValidateRegistryCredsRequest.groovy
│ │ │ └── ViewController.groovy
│ │ │ ├── core
│ │ │ ├── ContainerAugmenter.groovy
│ │ │ ├── ContainerDigestPair.groovy
│ │ │ ├── ContainerPath.groovy
│ │ │ ├── ContainerPlatform.groovy
│ │ │ ├── RegistryProxyService.groovy
│ │ │ ├── RouteHandler.groovy
│ │ │ └── RoutePath.groovy
│ │ │ ├── cron
│ │ │ └── ThreadMonitorCron.groovy
│ │ │ ├── encoder
│ │ │ ├── ByteArrayAdapter.groovy
│ │ │ ├── DateTimeAdapter.groovy
│ │ │ ├── EncodingStrategy.groovy
│ │ │ ├── MoshiEncodeStrategy.groovy
│ │ │ ├── MoshiSerializable.groovy
│ │ │ ├── PathAdapter.groovy
│ │ │ └── UriAdapter.groovy
│ │ │ ├── exception
│ │ │ ├── BadRequestException.groovy
│ │ │ ├── BuildRuntimeException.groovy
│ │ │ ├── BuildTimeoutException.groovy
│ │ │ ├── DockerRegistryException.groovy
│ │ │ ├── ForbiddenException.groovy
│ │ │ ├── HttpError.groovy
│ │ │ ├── HttpResponseException.groovy
│ │ │ ├── HttpServerRetryableErrorException.groovy
│ │ │ ├── NoSenderAvailException.groovy
│ │ │ ├── NotFoundException.groovy
│ │ │ ├── RegistryForwardException.groovy
│ │ │ ├── RegistryUnauthorizedAccessException.groovy
│ │ │ ├── ScanRuntimeException.groovy
│ │ │ ├── SlowDownException.groovy
│ │ │ ├── UnauthorizedException.groovy
│ │ │ └── WaveException.groovy
│ │ │ ├── exchange
│ │ │ ├── DescribeWaveContainerResponse.groovy
│ │ │ ├── EmptyBodyRequest.groovy
│ │ │ ├── ErrorResponse.groovy
│ │ │ ├── PairingRequest.groovy
│ │ │ ├── PairingResponse.groovy
│ │ │ └── RegistryErrorResponse.groovy
│ │ │ ├── filter
│ │ │ ├── DenyCrawlerFilter.groovy
│ │ │ ├── DenyPathsFilter.groovy
│ │ │ ├── FilterOrder.groovy
│ │ │ ├── MetricsQueryParamValidationFilter.groovy
│ │ │ ├── PullMetricsRequestsFilter.groovy
│ │ │ ├── RateLimiterFilter.groovy
│ │ │ ├── RateLimiterOptions.groovy
│ │ │ ├── TraceContextFilter.groovy
│ │ │ ├── TraceSlowEndpointFilter.java
│ │ │ └── TraceSlowEndpointPublisher.java
│ │ │ ├── http
│ │ │ └── HttpClientFactory.groovy
│ │ │ ├── metrics
│ │ │ └── ExecutorsMetricsBinder.groovy
│ │ │ ├── model
│ │ │ └── ContainerCoordinates.groovy
│ │ │ ├── proxy
│ │ │ ├── ClientResponseException.groovy
│ │ │ ├── DelegateResponse.groovy
│ │ │ ├── ErrResponse.groovy
│ │ │ ├── LoginRequest.groovy
│ │ │ ├── LoginResponse.groovy
│ │ │ ├── ProxyCache.groovy
│ │ │ └── ProxyClient.groovy
│ │ │ ├── ratelimit
│ │ │ ├── AcquireRequest.groovy
│ │ │ ├── RateLimiterService.groovy
│ │ │ └── impl
│ │ │ │ ├── SpillWayStorageFactory.groovy
│ │ │ │ └── SpillwayRateLimiter.groovy
│ │ │ ├── redis
│ │ │ ├── JedisPoolMetricsBinder.groovy
│ │ │ └── RedisFactory.groovy
│ │ │ ├── service
│ │ │ ├── ContainerRegistryKeys.groovy
│ │ │ ├── CredentialServiceImpl.groovy
│ │ │ ├── CredentialsService.groovy
│ │ │ ├── UserService.groovy
│ │ │ ├── UserServiceImpl.groovy
│ │ │ ├── account
│ │ │ │ ├── AccountService.groovy
│ │ │ │ └── AccountServiceImpl.groovy
│ │ │ ├── aws
│ │ │ │ ├── AwsEcrAuthException.groovy
│ │ │ │ ├── AwsEcrService.groovy
│ │ │ │ ├── AwsMailProvider.groovy
│ │ │ │ ├── ObjectStorageOperationsFactory.groovy
│ │ │ │ ├── S3ClientFactory.groovy
│ │ │ │ └── cache
│ │ │ │ │ ├── AwsEcrAuthToken.groovy
│ │ │ │ │ └── AwsEcrCache.groovy
│ │ │ ├── blob
│ │ │ │ ├── BlobCacheService.groovy
│ │ │ │ ├── BlobEntry.groovy
│ │ │ │ ├── BlobSigningService.groovy
│ │ │ │ ├── BlobStateStore.groovy
│ │ │ │ ├── BlobStoreImpl.groovy
│ │ │ │ ├── TransferStrategy.groovy
│ │ │ │ ├── impl
│ │ │ │ │ ├── AwsS3PresignerFactory.groovy
│ │ │ │ │ ├── BlobCacheServiceImpl.groovy
│ │ │ │ │ ├── DockerTransferStrategy.groovy
│ │ │ │ │ └── KubeTransferStrategy.groovy
│ │ │ │ └── signing
│ │ │ │ │ ├── AwsS3BlobSigningService.groovy
│ │ │ │ │ ├── CloudflareBlobSigningService.groovy
│ │ │ │ │ └── NoBlobSigningService.groovy
│ │ │ ├── builder
│ │ │ │ ├── BuildCounterStore.groovy
│ │ │ │ ├── BuildEntry.groovy
│ │ │ │ ├── BuildEvent.groovy
│ │ │ │ ├── BuildFormat.groovy
│ │ │ │ ├── BuildRequest.groovy
│ │ │ │ ├── BuildResult.groovy
│ │ │ │ ├── BuildStateStore.groovy
│ │ │ │ ├── BuildStrategy.groovy
│ │ │ │ ├── BuildTrack.groovy
│ │ │ │ ├── ContainerBuildService.groovy
│ │ │ │ ├── DockerBuildStrategy.groovy
│ │ │ │ ├── FreezeService.groovy
│ │ │ │ ├── FreezeServiceImpl.groovy
│ │ │ │ ├── KubeBuildStrategy.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── BuildStateStoreImpl.groovy
│ │ │ │ │ └── ContainerBuildServiceImpl.groovy
│ │ │ ├── cleanup
│ │ │ │ ├── CleanupConfig.groovy
│ │ │ │ ├── CleanupService.groovy
│ │ │ │ ├── CleanupServiceImpl.groovy
│ │ │ │ ├── CleanupStore.groovy
│ │ │ │ └── CleanupStrategy.groovy
│ │ │ ├── counter
│ │ │ │ ├── AbstractCounterStore.groovy
│ │ │ │ ├── CounterStore.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── CounterProvider.groovy
│ │ │ │ │ ├── LocalCounterProvider.groovy
│ │ │ │ │ └── RedisCounterProvider.groovy
│ │ │ ├── data
│ │ │ │ ├── future
│ │ │ │ │ ├── AbstractFutureStore.groovy
│ │ │ │ │ ├── FutureHash.groovy
│ │ │ │ │ ├── FutureStore.groovy
│ │ │ │ │ └── impl
│ │ │ │ │ │ ├── LocalFutureHash.groovy
│ │ │ │ │ │ └── RedisFutureHash.groovy
│ │ │ │ ├── queue
│ │ │ │ │ ├── AbstractMessageQueue.groovy
│ │ │ │ │ ├── MessageQueue.groovy
│ │ │ │ │ └── impl
│ │ │ │ │ │ ├── LocalMessageQueue.groovy
│ │ │ │ │ │ └── RedisMessageQueue.groovy
│ │ │ │ └── stream
│ │ │ │ │ ├── AbstractMessageStream.groovy
│ │ │ │ │ ├── MessageConsumer.groovy
│ │ │ │ │ ├── MessageStream.groovy
│ │ │ │ │ └── impl
│ │ │ │ │ ├── LocalMessageStream.groovy
│ │ │ │ │ └── RedisMessageStream.groovy
│ │ │ ├── inclusion
│ │ │ │ ├── ContainerInclusionImpl.groovy
│ │ │ │ └── ContainerInclusionService.groovy
│ │ │ ├── inspect
│ │ │ │ ├── ContainerInspectService.groovy
│ │ │ │ └── ContainerInspectServiceImpl.groovy
│ │ │ ├── job
│ │ │ │ ├── JobDispatcher.groovy
│ │ │ │ ├── JobEntry.groovy
│ │ │ │ ├── JobFactory.groovy
│ │ │ │ ├── JobHandler.groovy
│ │ │ │ ├── JobHelper.groovy
│ │ │ │ ├── JobManager.groovy
│ │ │ │ ├── JobOperation.groovy
│ │ │ │ ├── JobPendingQueue.groovy
│ │ │ │ ├── JobProcessingQueue.groovy
│ │ │ │ ├── JobService.groovy
│ │ │ │ ├── JobServiceImpl.groovy
│ │ │ │ ├── JobSpec.groovy
│ │ │ │ ├── JobState.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── DockerJobOperation.groovy
│ │ │ │ │ └── K8sJobOperation.groovy
│ │ │ ├── k8s
│ │ │ │ ├── K8sClient.groovy
│ │ │ │ ├── K8sClusterClient.groovy
│ │ │ │ ├── K8sConfigClient.groovy
│ │ │ │ ├── K8sService.groovy
│ │ │ │ └── K8sServiceImpl.groovy
│ │ │ ├── license
│ │ │ │ ├── CheckTokenResponse.groovy
│ │ │ │ ├── LicenceManRetryPredicate.groovy
│ │ │ │ └── LicenseManClient.groovy
│ │ │ ├── logs
│ │ │ │ ├── BuildLogService.groovy
│ │ │ │ └── BuildLogServiceImpl.groovy
│ │ │ ├── mail
│ │ │ │ ├── MailService.groovy
│ │ │ │ ├── MailSpooler.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── MailServiceImpl.groovy
│ │ │ │ │ └── MailSpoolerImpl.groovy
│ │ │ ├── metric
│ │ │ │ ├── MetricsConstants.groovy
│ │ │ │ ├── MetricsCounterStore.groovy
│ │ │ │ ├── MetricsService.groovy
│ │ │ │ ├── impl
│ │ │ │ │ └── MetricsServiceImpl.groovy
│ │ │ │ └── model
│ │ │ │ │ ├── GetOrgArchCountResponse.groovy
│ │ │ │ │ └── GetOrgCountResponse.groovy
│ │ │ ├── mirror
│ │ │ │ ├── ContainerMirrorService.groovy
│ │ │ │ ├── ContainerMirrorServiceImpl.groovy
│ │ │ │ ├── MirrorEntry.groovy
│ │ │ │ ├── MirrorRequest.groovy
│ │ │ │ ├── MirrorResult.groovy
│ │ │ │ ├── MirrorStateStore.groovy
│ │ │ │ └── strategy
│ │ │ │ │ ├── DockerMirrorStrategy.groovy
│ │ │ │ │ ├── KubeMirrorStrategy.groovy
│ │ │ │ │ └── MirrorStrategy.groovy
│ │ │ ├── pairing
│ │ │ │ ├── PairingRecord.groovy
│ │ │ │ ├── PairingService.groovy
│ │ │ │ ├── PairingServiceImpl.groovy
│ │ │ │ ├── PairingStore.groovy
│ │ │ │ └── socket
│ │ │ │ │ ├── MessageSender.groovy
│ │ │ │ │ ├── PairingChannel.groovy
│ │ │ │ │ ├── PairingInboundStore.groovy
│ │ │ │ │ ├── PairingOutboundQueue.groovy
│ │ │ │ │ ├── PairingWebSocket.groovy
│ │ │ │ │ └── msg
│ │ │ │ │ ├── PairingHeartbeat.groovy
│ │ │ │ │ ├── PairingMessage.groovy
│ │ │ │ │ ├── PairingResponse.groovy
│ │ │ │ │ ├── ProxyHttpRequest.groovy
│ │ │ │ │ └── ProxyHttpResponse.groovy
│ │ │ ├── persistence
│ │ │ │ ├── PersistenceService.groovy
│ │ │ │ ├── PostgresIgnore.groovy
│ │ │ │ ├── WaveBuildRecord.groovy
│ │ │ │ ├── WaveContainerRecord.groovy
│ │ │ │ ├── WaveScanRecord.groovy
│ │ │ │ ├── impl
│ │ │ │ │ ├── LocalPersistenceService.groovy
│ │ │ │ │ ├── RetryOnIOException.groovy
│ │ │ │ │ ├── SurrealClient.groovy
│ │ │ │ │ ├── SurrealPersistenceService.groovy
│ │ │ │ │ └── SurrealResult.groovy
│ │ │ │ ├── migrate
│ │ │ │ │ ├── DataMigrationService.groovy
│ │ │ │ │ ├── MigrationOnly.groovy
│ │ │ │ │ └── cache
│ │ │ │ │ │ ├── DataMigrateCache.groovy
│ │ │ │ │ │ └── DataMigrateEntry.groovy
│ │ │ │ └── postgres
│ │ │ │ │ ├── Mapper.groovy
│ │ │ │ │ ├── PostgresPersistentService.groovy
│ │ │ │ │ ├── PostgresSchemaService.groovy
│ │ │ │ │ └── data
│ │ │ │ │ ├── BuildRepository.groovy
│ │ │ │ │ ├── BuildRow.groovy
│ │ │ │ │ ├── MirrorRepository.groovy
│ │ │ │ │ ├── MirrorRow.groovy
│ │ │ │ │ ├── RequestRepository.groovy
│ │ │ │ │ ├── RequestRow.groovy
│ │ │ │ │ ├── ScanRepository.groovy
│ │ │ │ │ └── ScanRow.groovy
│ │ │ ├── request
│ │ │ │ ├── ContainerRequest.groovy
│ │ │ │ ├── ContainerRequestService.groovy
│ │ │ │ ├── ContainerRequestServiceImpl.groovy
│ │ │ │ ├── ContainerRequestStore.groovy
│ │ │ │ ├── ContainerRequestStoreImpl.groovy
│ │ │ │ ├── ContainerState.groovy
│ │ │ │ ├── ContainerStatusService.groovy
│ │ │ │ ├── ContainerStatusServiceImpl.groovy
│ │ │ │ └── TokenData.groovy
│ │ │ ├── scan
│ │ │ │ ├── ContainerScanService.groovy
│ │ │ │ ├── ContainerScanServiceImpl.groovy
│ │ │ │ ├── DockerScanStrategy.groovy
│ │ │ │ ├── KubeScanStrategy.groovy
│ │ │ │ ├── ScanEntry.groovy
│ │ │ │ ├── ScanId.groovy
│ │ │ │ ├── ScanIdStore.groovy
│ │ │ │ ├── ScanRequest.groovy
│ │ │ │ ├── ScanStateStore.groovy
│ │ │ │ ├── ScanStrategy.groovy
│ │ │ │ ├── ScanVulnerability.groovy
│ │ │ │ ├── Trivy.groovy
│ │ │ │ └── TrivyResultProcessor.groovy
│ │ │ ├── stream
│ │ │ │ ├── StreamService.groovy
│ │ │ │ └── StreamServiceImpl.groovy
│ │ │ └── validation
│ │ │ │ ├── ValidationService.groovy
│ │ │ │ ├── ValidationServiceImpl.groovy
│ │ │ │ └── ValidationServiceProd.groovy
│ │ │ ├── storage
│ │ │ ├── DigestStore.java
│ │ │ ├── DigestStoreFactory.java
│ │ │ ├── DockerDigestStore.java
│ │ │ ├── HttpDigestStore.java
│ │ │ ├── ManifestCacheStore.groovy
│ │ │ ├── Storage.java
│ │ │ └── ZippedDigestStore.java
│ │ │ ├── store
│ │ │ ├── cache
│ │ │ │ ├── AbstractTieredCache.groovy
│ │ │ │ ├── L2TieredCache.groovy
│ │ │ │ ├── RedisL2TieredCache.groovy
│ │ │ │ ├── TieredCache.groovy
│ │ │ │ └── TieredKey.groovy
│ │ │ ├── range
│ │ │ │ ├── AbstractRangeStore.groovy
│ │ │ │ ├── RangeStore.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── LocalRangeProvider.groovy
│ │ │ │ │ ├── RangeProvider.groovy
│ │ │ │ │ └── RedisRangeProvider.groovy
│ │ │ └── state
│ │ │ │ ├── AbstractStateStore.groovy
│ │ │ │ ├── CountParams.groovy
│ │ │ │ ├── CountResult.groovy
│ │ │ │ ├── RequestIdAware.groovy
│ │ │ │ ├── StateEntry.groovy
│ │ │ │ ├── StateStore.groovy
│ │ │ │ └── impl
│ │ │ │ ├── LocalStateProvider.groovy
│ │ │ │ ├── RedisStateProvider.groovy
│ │ │ │ └── StateProvider.groovy
│ │ │ ├── tower
│ │ │ ├── PlatformId.groovy
│ │ │ ├── User.groovy
│ │ │ ├── auth
│ │ │ │ ├── JwtAuth.groovy
│ │ │ │ ├── JwtAuthStore.groovy
│ │ │ │ ├── JwtConfig.groovy
│ │ │ │ ├── JwtMonitor.groovy
│ │ │ │ └── JwtTimeStore.groovy
│ │ │ ├── client
│ │ │ │ ├── CredentialsDescription.groovy
│ │ │ │ ├── GetCredentialsKeysResponse.groovy
│ │ │ │ ├── GetServiceInfoResponse.groovy
│ │ │ │ ├── GetUserInfoResponse.groovy
│ │ │ │ ├── ListCredentialsResponse.groovy
│ │ │ │ ├── TowerClient.groovy
│ │ │ │ ├── cache
│ │ │ │ │ └── ClientCache.groovy
│ │ │ │ └── connector
│ │ │ │ │ ├── HttpTowerConnector.groovy
│ │ │ │ │ ├── JwtRefreshParams.groovy
│ │ │ │ │ ├── TowerConnector.groovy
│ │ │ │ │ └── WebSocketTowerConnector.groovy
│ │ │ └── compute
│ │ │ │ ├── ComputeEnv.groovy
│ │ │ │ ├── DescribeWorkflowLaunchResponse.groovy
│ │ │ │ └── WorkflowLaunch.groovy
│ │ │ └── util
│ │ │ ├── BucketTokenizer.groovy
│ │ │ ├── BuildInfo.groovy
│ │ │ ├── ContainerConfigFactory.groovy
│ │ │ ├── ContainerHelper.groovy
│ │ │ ├── CryptoHelper.groovy
│ │ │ ├── CustomThreadFactory.groovy
│ │ │ ├── DurationUtils.groovy
│ │ │ ├── Escape.groovy
│ │ │ ├── ExponentialAttempt.groovy
│ │ │ ├── FusionVersionStringDeserializer.groovy
│ │ │ ├── FutureUtils.groovy
│ │ │ ├── JacksonHelper.groovy
│ │ │ ├── K8sHelper.groovy
│ │ │ ├── LoggerLevelFilter.java
│ │ │ ├── NameVersionPair.groovy
│ │ │ ├── RegHelper.groovy
│ │ │ ├── Retryable.groovy
│ │ │ ├── RuntimeInfo.groovy
│ │ │ ├── StringUtils.groovy
│ │ │ ├── TypeHelper.groovy
│ │ │ └── Views.groovy
│ ├── jib
│ │ └── launch.sh
│ └── resources
│ │ ├── application-blobcache-dev.yml
│ │ ├── application-buildlogs-aws-test.yml
│ │ ├── application-dev-k8s.yml
│ │ ├── application-dev.yml
│ │ ├── application-licman.yml
│ │ ├── application-mysql.yml
│ │ ├── application-postgres.yml
│ │ ├── application-prometheus.yml
│ │ ├── application-rate-limit.yml
│ │ ├── application-redis.yml
│ │ ├── application-reserved-words.yml
│ │ ├── application-surrealdb-legacy.yml
│ │ ├── application-surrealdb.yml
│ │ ├── application.yml
│ │ ├── bootstrap-ec2.yml
│ │ ├── bootstrap.yml
│ │ ├── io
│ │ └── seqera
│ │ │ └── wave
│ │ │ ├── assets
│ │ │ ├── robots.txt
│ │ │ ├── seqera-logo.png
│ │ │ ├── wave-logo.png
│ │ │ └── wave.ico
│ │ │ ├── build-list.hbs
│ │ │ ├── build-notification.html
│ │ │ ├── build-view.hbs
│ │ │ ├── container-view.hbs
│ │ │ ├── inspect-view.hbs
│ │ │ ├── mirror-view.hbs
│ │ │ ├── scan-list.hbs
│ │ │ └── scan-view.hbs
│ │ └── logback.xml
└── test
│ ├── groovy
│ ├── io
│ │ └── seqera
│ │ │ └── wave
│ │ │ ├── ContainerConfigTest.groovy
│ │ │ ├── auth
│ │ │ ├── MissingCredentialsTest.groovy
│ │ │ ├── RegistryAuthServiceTest.groovy
│ │ │ ├── RegistryAuthTest.groovy
│ │ │ ├── RegistryCredentialsFactoryImplTest.groovy
│ │ │ ├── RegistryCredentialsProviderTest.groovy
│ │ │ ├── RegistryInfoTest.groovy
│ │ │ ├── RegistryLookupCacheTest.groovy
│ │ │ ├── RegistryLookupServiceTest.groovy
│ │ │ └── RegistryTokenStoreTest.groovy
│ │ │ ├── configuration
│ │ │ ├── BlobCacheConfigTest.groovy
│ │ │ └── ScanConfigTest.groovy
│ │ │ ├── controller
│ │ │ ├── BuildConfigTest.groovy
│ │ │ ├── BuildControllerTest.groovy
│ │ │ ├── ContainerControllerHttpTest.groovy
│ │ │ ├── ContainerControllerTest.groovy
│ │ │ ├── CustomImageControllerTest.groovy
│ │ │ ├── ErrorHandlingTest.groovy
│ │ │ ├── InspectControllerTest.groovy
│ │ │ ├── MetricsControllerTest.groovy
│ │ │ ├── RegistryControllerLocalTest.groovy
│ │ │ ├── RegistryControllerLookupFailureTest.groovy
│ │ │ ├── RegistryControllerPullLimitTest.groovy
│ │ │ ├── RegistryControllerRedisTest.groovy
│ │ │ ├── ScanControllerTest.groovy
│ │ │ ├── ServiceInfoControllerTest.groovy
│ │ │ ├── ValidateCredsControllerTest.groovy
│ │ │ └── ViewControllerTest.groovy
│ │ │ ├── core
│ │ │ ├── ContainerAugmenterTest.groovy
│ │ │ ├── ContainerPathTest.groovy
│ │ │ ├── ContainerPlatformTest.groovy
│ │ │ ├── RegistryProxyServiceTest.groovy
│ │ │ ├── RouteHandlerTest.groovy
│ │ │ └── RoutePathTest.groovy
│ │ │ ├── cron
│ │ │ └── ThreadMonitorCronTest.groovy
│ │ │ ├── encoder
│ │ │ └── MoshiEncodingStrategyTest.groovy
│ │ │ ├── exchange
│ │ │ ├── BuildStatusResponseTest.groovy
│ │ │ └── RegistryErrorResponseTest.groovy
│ │ │ ├── filter
│ │ │ ├── DenyCrawlerFilterTest.groovy
│ │ │ ├── DenyPathsFilterTest.groovy
│ │ │ ├── PullMetricsRequestsFilterTest.groovy
│ │ │ └── TraceContextFilterTest.groovy
│ │ │ ├── model
│ │ │ └── ContainerCoordinatesTest.groovy
│ │ │ ├── proxy
│ │ │ ├── ProxyCacheTest.groovy
│ │ │ ├── ProxyClientTest.groovy
│ │ │ └── ProxyClientWithLocalRegistryTest.groovy
│ │ │ ├── ratelimit
│ │ │ ├── BuildServiceRateLimitTest.groovy
│ │ │ ├── SpillwayMemoryRateLimiterTest.groovy
│ │ │ ├── SpillwayRedisRateLimiterTest.groovy
│ │ │ └── SpillwayRegistryControllerTest.groovy
│ │ │ ├── redis
│ │ │ └── RedisFactoryTest.groovy
│ │ │ ├── service
│ │ │ ├── CredentialsServiceTest.groovy
│ │ │ ├── UserServiceTest.groovy
│ │ │ ├── account
│ │ │ │ └── AccountServiceTest.groovy
│ │ │ ├── aws
│ │ │ │ ├── AwsEcrServiceTest.groovy
│ │ │ │ └── cache
│ │ │ │ │ └── AwsEcrCacheTest.groovy
│ │ │ ├── blob
│ │ │ │ ├── BlobCacheInfoTest.groovy
│ │ │ │ ├── BlobStateStoreImplTest.groovy
│ │ │ │ ├── impl
│ │ │ │ │ ├── BlobCacheServiceImplTest.groovy
│ │ │ │ │ ├── BlobCacheServiceImplTest2.groovy
│ │ │ │ │ ├── DockerTransferStrategyTest.groovy
│ │ │ │ │ └── KubeTransferStrategyTest.groovy
│ │ │ │ └── signing
│ │ │ │ │ └── AwsS3BlobSigningServiceTest.groovy
│ │ │ ├── builder
│ │ │ │ ├── BuildEntryTest.groovy
│ │ │ │ ├── BuildRequestTest.groovy
│ │ │ │ ├── BuildResultTest.groovy
│ │ │ │ ├── BuildStateStoreImplTest.groovy
│ │ │ │ ├── BuildStoreLocalTest.groovy
│ │ │ │ ├── BuildStoreRedisTest.groovy
│ │ │ │ ├── BuildStrategyTest.groovy
│ │ │ │ ├── ContainerBuildServiceLiveTest.groovy
│ │ │ │ ├── ContainerBuildServiceTest.groovy
│ │ │ │ ├── DockerBuildStrategyTest.groovy
│ │ │ │ ├── FreezeServiceImplTest.groovy
│ │ │ │ └── KubeBuildStrategyTest.groovy
│ │ │ ├── cleanup
│ │ │ │ ├── CleanupConfigTest.groovy
│ │ │ │ ├── CleanupServiceTest.groovy
│ │ │ │ └── CleanupStrategyTest.groovy
│ │ │ ├── counter
│ │ │ │ └── impl
│ │ │ │ │ ├── LocalCounterProviderTest.groovy
│ │ │ │ │ └── RedisCounterProviderTest.groovy
│ │ │ ├── data
│ │ │ │ ├── future
│ │ │ │ │ ├── AbstractFutureStoreTest.groovy
│ │ │ │ │ └── impl
│ │ │ │ │ │ ├── LocalFutureHashTest.groovy
│ │ │ │ │ │ └── RedisFutureHashTest.groovy
│ │ │ │ ├── queue
│ │ │ │ │ ├── AbstractMessageQueueLocalTest.groovy
│ │ │ │ │ ├── AbstractMessageQueueRedisTest.groovy
│ │ │ │ │ ├── LocalMessageQueueTest.groovy
│ │ │ │ │ └── RedisMessageQueueTest.groovy
│ │ │ │ └── stream
│ │ │ │ │ ├── AbstractMessageStreamLocalTest.groovy
│ │ │ │ │ ├── AbstractMessageStreamRedisTest.groovy
│ │ │ │ │ ├── LocalMessageStreamTest.groovy
│ │ │ │ │ ├── RedisMessageStreamTest.groovy
│ │ │ │ │ ├── TestMessage.groovy
│ │ │ │ │ └── TestStream.groovy
│ │ │ ├── inclusion
│ │ │ │ └── ContainerInclusionImplTest.groovy
│ │ │ ├── inspect
│ │ │ │ └── ContainerInspectServiceImplTest.groovy
│ │ │ ├── job
│ │ │ │ ├── JobFactoryTest.groovy
│ │ │ │ ├── JobManagerTest.groovy
│ │ │ │ ├── JobSpecTest.groovy
│ │ │ │ ├── JobStateTest.groovy
│ │ │ │ └── impl
│ │ │ │ │ ├── DockerJobOperationTest.groovy
│ │ │ │ │ └── K8SJobOperationTest.groovy
│ │ │ ├── k8s
│ │ │ │ └── K8sServiceImplTest.groovy
│ │ │ ├── logs
│ │ │ │ └── BuildLogsServiceTest.groovy
│ │ │ ├── mail
│ │ │ │ └── MailServiceImplTest.groovy
│ │ │ ├── metric
│ │ │ │ ├── MetricsCounterStoreLocalTest.groovy
│ │ │ │ ├── MetricsCounterStoreRedisTest.groovy
│ │ │ │ └── impl
│ │ │ │ │ └── MetricsServiceImplTest.groovy
│ │ │ ├── mirror
│ │ │ │ ├── ContainerMirrorServiceTest.groovy
│ │ │ │ ├── MirrorEntryTest.groovy
│ │ │ │ ├── MirrorRequestTest.groovy
│ │ │ │ ├── MirrorResultTest.groovy
│ │ │ │ ├── MirrorStateStoreTest.groovy
│ │ │ │ └── strategy
│ │ │ │ │ ├── DockerMirrorStrategyTest.groovy
│ │ │ │ │ └── MirrorStrategyTest.groovy
│ │ │ ├── pairing
│ │ │ │ ├── PairingServiceTest.groovy
│ │ │ │ ├── PairingStoreTest.groovy
│ │ │ │ └── PairingWebSocketTest.groovy
│ │ │ ├── persistence
│ │ │ │ ├── WaveBuildRecordTest.groovy
│ │ │ │ ├── WaveContainerRecordTest.groovy
│ │ │ │ ├── WaveScanRecordTest.groovy
│ │ │ │ ├── impl
│ │ │ │ │ └── SurrealPersistenceServiceTest.groovy
│ │ │ │ ├── migrate
│ │ │ │ │ ├── DataMigrationLockTest.groovy
│ │ │ │ │ └── DataMigrationServiceTest.groovy
│ │ │ │ └── postgres
│ │ │ │ │ ├── MapperTest.groovy
│ │ │ │ │ ├── PostgresPersistentServiceTest.groovy
│ │ │ │ │ └── PostgresSchemaServiceTest.groovy
│ │ │ ├── request
│ │ │ │ ├── ContainerRequestServiceImplTest.groovy
│ │ │ │ ├── ContainerRequestStoreImplTest.groovy
│ │ │ │ ├── ContainerRequestTest.groovy
│ │ │ │ ├── ContainerStatusServiceTest.groovy
│ │ │ │ └── ContainerStatusTest.groovy
│ │ │ ├── scan
│ │ │ │ ├── ContainerScanServiceImplTest.groovy
│ │ │ │ ├── ContainerScanStrategyTest.groovy
│ │ │ │ ├── DockerScanStrategyTest.groovy
│ │ │ │ ├── ScanEntryTest.groovy
│ │ │ │ ├── ScanIdStoreLocalTest.groovy
│ │ │ │ ├── ScanIdStoreRedisTest.groovy
│ │ │ │ ├── ScanIdTest.groovy
│ │ │ │ ├── ScanRequestTest.groovy
│ │ │ │ ├── ScanStateStoreTest.groovy
│ │ │ │ ├── ScanVulnerabilityTest.groovy
│ │ │ │ └── TrivyResultProcessorTest.groovy
│ │ │ ├── stream
│ │ │ │ └── StreamServiceTest.groovy
│ │ │ └── validation
│ │ │ │ ├── ValidationServiceProdTest.groovy
│ │ │ │ └── ValidationServiceTest.groovy
│ │ │ ├── storage
│ │ │ ├── DigestStoreFactoryTest.groovy
│ │ │ ├── DockerDigestStoreTest.groovy
│ │ │ ├── HttpDigestStoreTest.groovy
│ │ │ ├── ManifestCacheStoreTest.groovy
│ │ │ └── ZippedDigestStoreTest.groovy
│ │ │ ├── store
│ │ │ ├── cache
│ │ │ │ ├── AbstractTieredCacheTest.groovy
│ │ │ │ └── RedisL2TieredCacheTest.groovy
│ │ │ ├── range
│ │ │ │ ├── LocalRangeProviderTest.groovy
│ │ │ │ └── RedisRangeProviderTest.groovy
│ │ │ └── state
│ │ │ │ ├── AbstractStateStoreTest.groovy
│ │ │ │ ├── CountParamsTest.groovy
│ │ │ │ └── impl
│ │ │ │ ├── LocalStateProviderTest.groovy
│ │ │ │ └── RedisStateProviderTest.groovy
│ │ │ ├── test
│ │ │ ├── AwsS3TestContainer.groovy
│ │ │ ├── BaseTestContainerRegistry.groovy
│ │ │ ├── DockerRegistryContainer.groovy
│ │ │ ├── ManifestConst.groovy
│ │ │ ├── RedisTestContainer.groovy
│ │ │ ├── SecureDockerRegistryContainer.groovy
│ │ │ ├── SurrealDBTestContainer.groovy
│ │ │ └── TestHelper.groovy
│ │ │ ├── tower
│ │ │ ├── PlatformIdTest.groovy
│ │ │ ├── auth
│ │ │ │ ├── JwtAuthStoreTest.groovy
│ │ │ │ ├── JwtAuthTest.groovy
│ │ │ │ ├── JwtConfigTest.groovy
│ │ │ │ ├── JwtTimeLocalTest.groovy
│ │ │ │ └── JwtTimeRedisTest.groovy
│ │ │ └── client
│ │ │ │ ├── ListCredentialsDeserTest.groovy
│ │ │ │ ├── TowerClientHttpTest.groovy
│ │ │ │ ├── TowerClientTest.groovy
│ │ │ │ ├── cache
│ │ │ │ └── ClientCacheTest.groovy
│ │ │ │ └── connector
│ │ │ │ └── JwtRefreshParamsTest.groovy
│ │ │ └── util
│ │ │ ├── BucketTokenizerTest.groovy
│ │ │ ├── BuildInfoTest.groovy
│ │ │ ├── ContainerHelperTest.groovy
│ │ │ ├── CryptoHelperTest.groovy
│ │ │ ├── DurationUtilsTest.groovy
│ │ │ ├── EscapeTest.groovy
│ │ │ ├── ExponentialAttemptTest.groovy
│ │ │ ├── FusionVersionStringDeserializerTest.groovy
│ │ │ ├── K8sHelperTest.groovy
│ │ │ ├── NameVersionPairTest.groovy
│ │ │ ├── RegHelperTest.groovy
│ │ │ ├── RetryableTest.groovy
│ │ │ └── StringUtilsTest.groovy
│ └── test
│ │ └── RedisTestFactory.groovy
│ └── resources
│ ├── application-rate-limit.yml
│ ├── application-test-deny-paths.yml
│ ├── application-test.yml
│ ├── foo
│ ├── dummy.gzip
│ ├── layer.json
│ └── manifest_schema1.json
│ ├── logback-test.xml
│ ├── pack
│ └── layers
│ │ ├── layer.json
│ │ ├── layer.tar
│ │ └── layer.tar.gzip
│ └── registry.password
├── tag-and-push.sh
├── test.sh
└── typespec
├── Dockerfile
├── index.html
├── main.tsp
├── models
├── BuildStatusResponse.tsp
├── CondaOpts.tsp
├── CondaPackages.tsp
├── ContainerConfig.tsp
├── ContainerInspectConfig.tsp
├── ContainerInspectRequest.tsp
├── ContainerInspectResponse.tsp
├── ContainerLayer.tsp
├── ContainerMirrorResponse.tsp
├── ContainerPlatform.tsp
├── ContainerRequest.tsp
├── ContainerResponse.tsp
├── ContainerStatus.tsp
├── ContainerStatusResponse.tsp
├── Manifest.tsp
├── ManifestLayer.tsp
├── RootFS.tsp
├── ScanLevel.tsp
├── ScanMode.tsp
├── Status.tsp
├── User.tsp
├── ValidateRegistryCredsRequest.tsp
├── Vulnerability.tsp
├── WaveBuildRecord.tsp
├── WaveContainerRecord.tsp
├── WaveScanRecord.tsp
└── models.tsp
├── package.json
├── routes.tsp
├── tag-and-push-openapi.sh
└── tspconfig.yaml
/.codespellignore:
--------------------------------------------------------------------------------
1 | carrer
2 | ser
3 |
--------------------------------------------------------------------------------
/.github/actions/deploy/action.yml:
--------------------------------------------------------------------------------
1 | name: 'Deploy to cluster'
2 | inputs:
3 | app:
4 | required: true
5 | type: string
6 | container:
7 | required: true
8 | type: string
9 | namespace:
10 | required: true
11 | type: string
12 | aws-access-key-id:
13 | required: true
14 | type: string
15 | aws-secret-access-key:
16 | required: true
17 | type: string
18 | aws-region:
19 | required: true
20 | type: string
21 | kube-config-data:
22 | required: true
23 | type: string
24 | runs:
25 | using: "composite"
26 | steps:
27 | - name: Configure AWS credentials
28 | uses: aws-actions/configure-aws-credentials@v1
29 | with:
30 | aws-access-key-id: ${{ inputs.aws-access-key-id }}
31 | aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
32 | aws-region: ${{ inputs.aws-region }}
33 |
34 | - name: Deploy to prod
35 | uses: kodermax/kubectl-aws-eks@master
36 | env:
37 | KUBE_CONFIG_DATA: ${{ inputs.kube-config-data }}
38 | with:
39 | args: set image deployment/${{inputs.app}} ${{inputs.app}}=${{inputs.container}}:$(cat VERSION) -n ${{inputs.namespace}}
40 |
--------------------------------------------------------------------------------
/.github/actions/spelling/allow.txt:
--------------------------------------------------------------------------------
1 | NotIn
2 |
--------------------------------------------------------------------------------
/.github/workflows/build-singularity.yml:
--------------------------------------------------------------------------------
1 | name: Build and publish Singularity container image
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | version:
7 | description: 'Image version (e.g., 4.2.1-r4)'
8 | required: true
9 | default: '4.2.1-r4'
10 |
11 | jobs:
12 | build-and-push:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Checkout code
16 | uses: actions/checkout@v4
17 |
18 | - name: Set up Docker Buildx
19 | id: buildx
20 | uses: docker/setup-buildx-action@v3
21 |
22 | - name: Docker Login
23 | uses: docker/login-action@v3
24 | with:
25 | registry: public.cr.seqera.io
26 | username: ${{ vars.SEQERA_PUBLIC_CR_USERNAME }}
27 | password: ${{ secrets.SEQERA_PUBLIC_CR_PASSWORD }}
28 |
29 | - name: Build and Push Image to public.cr.seqera.io
30 | run: |
31 | cd singularity
32 | make build version=${{ github.event.inputs.version }}
33 |
--------------------------------------------------------------------------------
/.github/workflows/codespell.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Codespell
3 |
4 | on:
5 | push:
6 | branches: [master]
7 | pull_request:
8 | branches: [master]
9 |
10 | permissions:
11 | contents: read
12 |
13 | jobs:
14 | codespell:
15 | name: Check for spelling errors
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v4
21 | - name: Codespell
22 | uses: codespell-project/actions-codespell@v2
23 | with:
24 | only_warn: 1
25 | ignore_words_file: .codespellignore
26 | exclude_file: src/main/resources/application-reserved-words.yml
27 |
--------------------------------------------------------------------------------
/.github/workflows/pre-commit.yml.bak:
--------------------------------------------------------------------------------
1 | name: Lint code
2 | on:
3 | push:
4 | pull_request:
5 |
6 | jobs:
7 | pre-commit:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v3
11 | - uses: actions/setup-python@v3
12 | - uses: pre-commit/action@v3.0.0
13 |
--------------------------------------------------------------------------------
/.github/workflows/security-submit-dependecy-graph.yml:
--------------------------------------------------------------------------------
1 | name: Generate and submit dependency graph for wave
2 | on:
3 | push:
4 | branches: ['master']
5 |
6 | permissions:
7 | contents: write
8 |
9 | jobs:
10 | dependency-submission:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | - uses: actions/setup-java@v4
15 | with:
16 | distribution: temurin
17 | java-version: 17
18 |
19 | - name: Generate and submit dependency graph for wave
20 | uses: gradle/actions/dependency-submission@v4
21 | with:
22 | dependency-resolution-task: "dependencies"
23 | additional-arguments: "--configuration runtimeClasspath"
24 | dependency-graph: generate-and-submit
25 |
--------------------------------------------------------------------------------
/.github/workflows/typespec.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Typespec_Validation
3 |
4 | on:
5 | push:
6 | branches:
7 | - '**'
8 | paths :
9 | - 'typespec/**'
10 | - VERSION
11 | pull_request:
12 | types: [opened, reopened, synchronize]
13 | paths:
14 | - 'typespec/**'
15 | - VERSION
16 |
17 | permissions:
18 | contents: read
19 |
20 | jobs:
21 | typespec_validation:
22 | name: validate typespec files
23 | runs-on: ubuntu-latest
24 |
25 | steps:
26 | - name : Checkout
27 | uses : actions/checkout@v4
28 |
29 | - name : Setup Node.js environment
30 | uses : actions/setup-node@v4
31 | with :
32 | node-version : '20.9.0'
33 |
34 | - name : Install tsp
35 | run : npm install -g @typespec/compiler@0.64.0
36 |
37 | - name : Validate tsp files
38 | run : |
39 | cd typespec
40 | tsp install
41 | tsp compile .
42 |
43 | - name: Configure AWS credentials
44 | uses: aws-actions/configure-aws-credentials@v1
45 | with:
46 | aws-access-key-id: ${{secrets.TOWER_CI_AWS_ACCESS}}
47 | aws-secret-access-key: ${{secrets.TOWER_CI_AWS_SECRET}}
48 | aws-region: eu-west-1
49 |
50 | - name : Login to Amazon ECR
51 | id : login-ecr
52 | uses : aws-actions/amazon-ecr-login@v1
53 |
54 | - name: Release OpenAPI docs
55 | if: "contains(github.event.head_commit.message, '[release]')"
56 | run: |
57 | bash typespec/tag-and-push-openapi.sh
58 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Thumbs.db
2 | .DS_Store
3 | .gradle
4 | .cache
5 | .nextflow*
6 | build/
7 | packtar/
8 | target/
9 | out/
10 | .idea
11 | *.iml
12 | *.ipr
13 | *.iws
14 | .nextflow*
15 | .project
16 | .settings
17 | .classpath
18 | .factorypath
19 | .layer/opt/fusion/fusionfs
20 | .layer/opt/goofys/goofys
21 | .layer/opt/geesefs
22 | .layer/opt/tini
23 | tower-reg.yml
24 | /wave.*.log
25 | wave.log
26 | build-workspace/
27 | scan-workspace/
28 | /k8s/dev/config-k3d.yml
29 |
30 | # Docs
31 | .vercel
32 | .cache
33 | site/
34 | deployment-url.txt
35 |
36 | #typespec
37 | tsp-output/
38 | node_modules/
39 | package-lock.json
40 |
41 | # Seqera Docs clone
42 | seqeralabs-docs
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # Config for pre-commit: https://pre-commit.com/
2 | ---
3 | minimum_pre_commit_version: "2.9.2"
4 | repos:
5 | - repo: meta
6 | hooks:
7 | - id: identity
8 | - id: check-hooks-apply
9 |
10 | - repo: https://github.com/pre-commit/mirrors-prettier
11 | rev: "v2.7.1"
12 | hooks:
13 | - id: prettier
14 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore everything
2 | /*
3 |
4 | # Except docs and markdown files
5 | !docs/
6 | !*.md
7 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 4,
3 | "useTabs": false
4 | }
5 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | config ?= runtimeClasspath
2 |
3 | ifdef module
4 | mm = :${module}:
5 | else
6 | mm =
7 | endif
8 |
9 |
10 | compile:
11 | ./gradlew assemble
12 |
13 | check:
14 | ./gradlew check
15 |
16 | image:
17 | ./gradlew jibDockerBuild
18 |
19 | push:
20 | # docker login
21 | docker login -u pditommaso -p ${DOCKER_PASSWORD}
22 | ./gradlew jib
23 |
24 | #
25 | # Show dependencies try `make deps config=runtime`, `make deps config=google`
26 | #
27 | deps:
28 | ./gradlew -q ${mm}dependencies --configuration ${config}
29 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 1.21.1
2 |
--------------------------------------------------------------------------------
/buildSrc/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | */
4 |
5 | plugins {
6 | // Support convention plugins written in Groovy. Convention plugins are build scripts in 'src/main' that automatically become available as plugins in the main build.
7 | id 'groovy-gradle-plugin'
8 | }
9 |
10 | repositories {
11 | // Use the plugin portal to apply community plugins in convention plugins.
12 | gradlePluginPortal()
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/io.seqera.wave.groovy-application-conventions.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | */
4 |
5 | plugins {
6 | // Apply the common convention plugin for shared build configuration between library and application projects.
7 | id 'io.seqera.wave.groovy-common-conventions'
8 |
9 | // Apply the application plugin to add support for building a CLI application in Java.
10 | id 'application'
11 | }
12 |
13 | group = 'io.seqera'
14 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/io.seqera.wave.groovy-common-conventions.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | */
4 |
5 | plugins {
6 | // Apply the groovy Plugin to add support for Groovy.
7 | id 'groovy'
8 | }
9 |
10 | repositories {
11 | // Use Maven Central for resolving dependencies.
12 | mavenCentral()
13 | }
14 |
15 | java {
16 | // these settings apply to all jvm tooling, including groovy
17 | toolchain {
18 | languageVersion = JavaLanguageVersion.of(21)
19 | }
20 | sourceCompatibility = 17
21 | targetCompatibility = 17
22 | }
23 |
24 | group = 'io.seqera'
25 |
--------------------------------------------------------------------------------
/buildSrc/src/main/groovy/io.seqera.wave.groovy-library-conventions.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | */
4 |
5 | plugins {
6 | // Apply the common convention plugin for shared build configuration between library and application projects.
7 | id 'io.seqera.wave.groovy-common-conventions'
8 |
9 | // Apply the java-library plugin for API and implementation separation.
10 | id 'java-library'
11 | // Micronaut minimal lib
12 | // https://micronaut-projects.github.io/micronaut-gradle-plugin/3.7.x/
13 | id "io.micronaut.minimal.library"
14 | }
15 |
16 | micronaut {
17 | runtime("netty")
18 | testRuntime("spock2")
19 | processing {
20 | incremental(true)
21 | }
22 | }
23 |
24 | group = 'io.seqera'
25 |
--------------------------------------------------------------------------------
/config.yml:
--------------------------------------------------------------------------------
1 | ---
2 | wave:
3 | registries:
4 | default: docker.io
5 | docker.io:
6 | username: "${DOCKER_USER:}"
7 | password: "${DOCKER_PAT:}"
8 | quay.io:
9 | username: "${QUAY_USER:}"
10 | password: "${QUAY_PAT:}"
11 | 195996028523.dkr.ecr.eu-west-1.amazonaws.com:
12 | username : "${AWS_ACCESS_KEY_ID:}"
13 | password : "${AWS_SECRET_ACCESS_KEY:}"
14 | seqeralabs.azurecr.io:
15 | username : "${AZURECR_USER:}"
16 | password : "${AZURECR_PAT:}"
17 | ...
18 |
--------------------------------------------------------------------------------
/container-request.json:
--------------------------------------------------------------------------------
1 | {
2 | "containerImage":"quay.io/nextflow/bash:latest",
3 | "containerConfig": {
4 | "layers": [
5 | {
6 | "location": "https://s3.eu-west-1.amazonaws.com/nf-tower.dev/wave-layer.tar.gzip",
7 | "gzipDigest": "sha256:e9d6f29eecde29c12f0d32a1bc81aa9f4fcb76f8d813b8f1a37e8af5ee6b7657",
8 | "gzipSize": 13219265,
9 | "tarDigest": "sha256:2648cf125a9a4c4c5c9a2d3799b3a57983b5297442d7995746273c615bc4e316"
10 | }
11 | ]
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/debug.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | export JVM_OPTS='-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8010'
20 | . ./run.sh
21 |
--------------------------------------------------------------------------------
/docs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Wave, containers provisioning service
4 | # Copyright (c) 2023-2024, Seqera Labs
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Affero General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Affero General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Affero General Public License
17 | # along with this program. If not, see .
18 | #
19 |
20 | docker run --rm -i -t -p 3000:3000 -v $PWD/docs:/home/node/app/docs \
21 | cr.seqera.io/public/docs-previewer:latest
22 |
--------------------------------------------------------------------------------
/docs/_images/wave_container_augmentation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/docs/_images/wave_container_augmentation.png
--------------------------------------------------------------------------------
/docs/_images/wave_container_build_failure_details.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/docs/_images/wave_container_build_failure_details.png
--------------------------------------------------------------------------------
/docs/sidebar.json:
--------------------------------------------------------------------------------
1 | {
2 | "sidebar": [
3 | {
4 | "type": "category",
5 | "label": "Wave",
6 | "collapsed": false,
7 | "items": [
8 | "index",
9 | "get-started",
10 | "provisioning"
11 | ]
12 | },
13 | "nextflow",
14 | {
15 | "type": "category",
16 | "label": "Developer tools",
17 | "collapsed": false,
18 | "items": [
19 | "cli/index",
20 | "cli/reference",
21 | "api"
22 | ]
23 | },
24 | "faq"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/docs/troubleshoot.mdx:
--------------------------------------------------------------------------------
1 | ## Troubleshoot guide
2 |
3 | 1. How to troubleshoot container build failure?
4 |
5 | If your container build fails, you can check the build details by checking the logs in build details email as shown in below screenshot.
6 |
7 | #### email screenshot:
8 | 
9 |
10 | If there is nothing conclusive in logs, you can check the exit status, e.g. if it is 137 that means out of memory error.
11 | Wave run build process in kubernetes pod, you can check this [link](https://komodor.com/learn/exit-codes-in-containers-and-kubernetes-the-complete-guide/) for more details on exit codes.
12 |
13 | 2. How to solve buildkit error, while running wave build on docker desktop in mac os?
14 |
15 | #### error:
16 | ```
17 | could not connect to unix:///run/user/1000/buildkit/buildkitd.sock after 10 trials
18 | ========== log ==========
19 | [rootlesskit:parent] error: failed to start the child: fork/exec /proc/self/exe: invalid argument
20 | sh: can't kill pid 14: No such process
21 | ```
22 |
23 | #### Solution:
24 | - In case of wave cli use `--platform linux/arm64` flag with wave build command.
25 | - In case of API call use `containerPlatform: linux/arm64` in the request body.
26 |
27 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | micronautVersion=4.8.2
20 | micronautEnvs=dev,mail,aws-ses
21 |
--------------------------------------------------------------------------------
/gradle/config/groovyc.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | import groovy.transform.CompileStatic
20 |
21 | withConfig(configuration) {
22 | ast(CompileStatic)
23 | }
24 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/misc/image-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "architecture":"amd64",
3 | "config":{
4 | "Hostname":"",
5 | "Domainname":"",
6 | "User":"",
7 | "AttachStdin":false,
8 | "AttachStdout":false,
9 | "AttachStderr":false,
10 | "Tty":false,
11 | "OpenStdin":false,
12 | "StdinOnce":false,
13 | "Env":[
14 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
15 | ],
16 | "Cmd":[
17 | "/bin/sh"
18 | ],
19 | "Image":"",
20 | "Volumes":null,
21 | "WorkingDir":"",
22 | "Entrypoint":null,
23 | "OnBuild":null,
24 | "Labels":{
25 |
26 | }
27 | },
28 | "container":"4be9f6b4406ec142e457fd7c43ff338511ab338b33585c30805ba2d5d3da29e3",
29 | "container_config":{
30 | "Hostname":"4be9f6b4406e",
31 | "Domainname":"",
32 | "User":"",
33 | "AttachStdin":false,
34 | "AttachStdout":false,
35 | "AttachStderr":false,
36 | "Tty":false,
37 | "OpenStdin":false,
38 | "StdinOnce":false,
39 | "Env":[
40 | "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
41 | ],
42 | "Cmd":[
43 | "/bin/sh"
44 | ],
45 | "Image":"bgruening/busybox-bash:0.1",
46 | "Volumes":null,
47 | "WorkingDir":"",
48 | "Entrypoint":null,
49 | "OnBuild":null,
50 | "Labels":{
51 |
52 | }
53 | },
54 | "created":"2020-01-24T15:39:30.564518517Z",
55 | "docker_version":"17.09.0-ce",
56 | "id":"f235879f79194a5e3d4b10c3b714c36669e8e98160ba73bd9b044fdec624ceaf",
57 | "os":"linux",
58 | "parent":"b7c0567175be2a551a8ed4e60d695d33347ebae5d8cfc4a5d0381e0ce3c34222"
59 | }
60 |
--------------------------------------------------------------------------------
/misc/resp3.f54a58bc1aac5ea1a25d796ae155dc228b3f0e11d046ae276b39c4bf2f13d8c4.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 2,
3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
4 | "config": {
5 | "mediaType": "application/vnd.docker.container.image.v1+json",
6 | "size": 1469,
7 | "digest": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412"
8 | },
9 | "layers": [
10 | {
11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
12 | "size": 2479,
13 | "digest": "sha256:2db29710123e3e53a794f2694094b9b4338aa9ee5c40b930cb8063a1be392c54"
14 | }
15 | ]
16 | }
--------------------------------------------------------------------------------
/misc/resp3.formatted.json:
--------------------------------------------------------------------------------
1 | {
2 | "schemaVersion": 2,
3 | "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
4 | "config": {
5 | "mediaType": "application/vnd.docker.container.image.v1+json",
6 | "size": 1469,
7 | "digest": "sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412"
8 | },
9 | "layers": [
10 | {
11 | "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
12 | "size": 2479,
13 | "digest": "sha256:2db29710123e3e53a794f2694094b9b4338aa9ee5c40b930cb8063a1be392c54"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/misc/resp4.feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412.json:
--------------------------------------------------------------------------------
1 | {"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/hello"],"Image":"sha256:b9935d4e8431fb1a7f0989304ec86b3329a99a25f5efdc7f09f3f8c41434ca6d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"container":"8746661ca3c2f215da94e6d3f7dfdcafaff5ec0b21c9aff6af3dc379a82fbc72","container_config":{"Hostname":"8746661ca3c2","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd":["/bin/sh","-c","#(nop) ","CMD [\"/hello\"]"],"Image":"sha256:b9935d4e8431fb1a7f0989304ec86b3329a99a25f5efdc7f09f3f8c41434ca6d","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":{}},"created":"2021-09-23T23:47:57.442225064Z","docker_version":"20.10.7","history":[{"created":"2021-09-23T23:47:57.098990892Z","created_by":"/bin/sh -c #(nop) COPY file:50563a97010fd7ce1ceebd1fa4f4891ac3decdf428333fb2683696f4358af6c2 in / "},{"created":"2021-09-23T23:47:57.442225064Z","created_by":"/bin/sh -c #(nop) CMD [\"/hello\"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359"]}}
--------------------------------------------------------------------------------
/reg.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | ngrok http 9090 -hostname reg.ngrok.io
20 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | mv wave.log wave.log.bak
20 | export AWS_REGION=${AWS_REGION:-'eu-west-1'}
21 | ./gradlew run --continuous --watch-fs
22 |
--------------------------------------------------------------------------------
/s5cmd/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu
2 | ARG version
3 | ADD dist.sh /dist.sh
4 | RUN apt update && apt install -y curl tar \
5 | && curl -L $(sh -x /dist.sh ${version}) | tar -zx \
6 | && cp s5cmd /usr/local/bin/s5cmd \
7 |
8 |
--------------------------------------------------------------------------------
/s5cmd/Makefile:
--------------------------------------------------------------------------------
1 | version ?= 2.2.2
2 |
3 | build:
4 | docker buildx build \
5 | --push \
6 | --platform linux/amd64,linux/arm64 \
7 | --build-arg version=${version} \
8 | --tag public.cr.seqera.io/wave/s5cmd:v${version} \
9 | .
10 |
--------------------------------------------------------------------------------
/s5cmd/dist.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | #
4 | # Wave, containers provisioning service
5 | # Copyright (c) 2023-2024, Seqera Labs
6 | #
7 | # This program is free software: you can redistribute it and/or modify
8 | # it under the terms of the GNU Affero General Public License as published by
9 | # the Free Software Foundation, either version 3 of the License, or
10 | # (at your option) any later version.
11 | #
12 | # This program is distributed in the hope that it will be useful,
13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | # GNU Affero General Public License for more details.
16 | #
17 | # You should have received a copy of the GNU Affero General Public License
18 | # along with this program. If not, see .
19 | #
20 |
21 | arch=$(uname -m)
22 |
23 | case $arch in
24 | x86_64|amd64)
25 | echo "https://github.com/peak/s5cmd/releases/download/v$1/s5cmd_$1_Linux-64bit.tar.gz"
26 | ;;
27 | aarch64|arm64)
28 | echo "https://github.com/peak/s5cmd/releases/download/v$1/s5cmd_$1_Linux-arm64.tar.gz"
29 | ;;
30 | *)
31 | echo "Unknown architecture: $arch"
32 | ;;
33 | esac
34 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | // required to download the toolchain (jdk) from a remote repository
3 | // https://github.com/gradle/foojay-toolchains
4 | // https://docs.gradle.org/current/userguide/toolchains.html#sub:download_repositories
5 | id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0"
6 | }
7 |
8 | rootProject.name="wave"
9 |
10 | // only for development
11 | // clone https://github.com/seqeralabs/libseqera
12 | // in a sibling directory and include the build below
13 | //includeBuild('../libseqera')
14 |
--------------------------------------------------------------------------------
/singularity/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine:3.21.3
2 | ARG version
3 | RUN apk update
4 | RUN apk add singularity=${version}
5 | RUN apk add proot-static --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
6 |
7 | RUN ln -s /usr/bin/proot.static /usr/bin/proot
8 |
9 | RUN addgroup -g 1000 builder
10 |
11 | RUN adduser \
12 | -D \
13 | -u 1000 \
14 | -G builder \
15 | -h /home/builder \
16 | -s /bin/sh \
17 | builder
18 |
19 | USER builder
20 |
--------------------------------------------------------------------------------
/singularity/Makefile:
--------------------------------------------------------------------------------
1 | version ?= 4.2.1-r4
2 |
3 | build:
4 | docker buildx build \
5 | --push \
6 | --platform linux/amd64,linux/arm64 \
7 | --build-arg version=${version} \
8 | --tag public.cr.seqera.io/wave/singularity:v${version} \
9 | .
10 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/auth/RegistryCredentials.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | /**
22 | * Simple container registry credentials interface
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface RegistryCredentials {
27 |
28 | String getUsername()
29 | String getPassword()
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/auth/RegistryCredentialsFactory.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | /**
22 | * Define service to create {@link RegistryCredentials} objects
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface RegistryCredentialsFactory {
27 |
28 | RegistryCredentials create(String registry, String userName, String password)
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/auth/RegistryLookupException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | import groovy.transform.CompileStatic
22 | import io.seqera.wave.exception.WaveException
23 | /**
24 | * Generic registry authorization exception
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @CompileStatic
29 | class RegistryLookupException extends WaveException {
30 | RegistryLookupException(String message) {
31 | super(message)
32 | }
33 |
34 | RegistryLookupException(String message, Throwable t) {
35 | super(message, t)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/auth/RegistryLookupService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | /**
22 | * Lookup service for container registry
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface RegistryLookupService {
27 |
28 | /**
29 | * Given a registry name lookup for the corresponding
30 | * auth endpoint
31 | *
32 | * @param registry
33 | * The registry name e.g. {@code docker.io} or {@code quay.io}
34 | * @return The corresponding {@link RegistryAuth} object holding the realm URI and service info,
35 | * or {@code null} if nothing is found
36 | */
37 | RegistryInfo lookup(String registry)
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/auth/RegistryUtils.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | import java.net.http.HttpResponse
22 |
23 | import groovy.transform.CompileStatic
24 | import io.seqera.wave.WaveDefault
25 | /**
26 | * Utility class for registry functions
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @CompileStatic
31 | class RegistryUtils {
32 |
33 | static boolean isServerError(HttpResponse response) {
34 | response.statusCode() in WaveDefault.HTTP_SERVER_ERRORS
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/configuration/LimitConfig.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.configuration
20 |
21 | import java.time.Duration
22 |
23 | import groovy.transform.CompileStatic
24 | import groovy.transform.ToString
25 | /**
26 | * A simple bean to configure a max items per duration
27 | *
28 | * @author : jorge
29 | *
30 | */
31 | @ToString(includePackage = false, includeNames = true)
32 | @CompileStatic
33 | class LimitConfig {
34 | int max
35 | Duration duration
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/configuration/RedisConfig.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.configuration
20 |
21 | import io.micronaut.context.annotation.ConfigurationProperties
22 |
23 |
24 | /**
25 | * Model Redis server configuration settings
26 | *
27 | * @author : jorge
28 | *
29 | */
30 | @ConfigurationProperties('redis')
31 | interface RedisConfig {
32 |
33 | String getUri()
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/controller/ValidateRegistryCredsRequest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.controller
20 |
21 | import io.micronaut.core.annotation.Introspected
22 | import jakarta.validation.constraints.NotBlank
23 |
24 | @Introspected
25 | class ValidateRegistryCredsRequest {
26 | @NotBlank
27 | String userName
28 | @NotBlank
29 | String password
30 | @NotBlank
31 | String registry
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/core/ContainerDigestPair.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.core
20 |
21 | import groovy.transform.Canonical
22 |
23 | /**
24 | * Hold the container digest that originated the request and the
25 | * digest of the resolved container provisioned by wave
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @Canonical
30 | class ContainerDigestPair {
31 | /**
32 | * Digest of the source container image
33 | */
34 | final String source
35 |
36 | /**
37 | * Digest of the augmented container image
38 | */
39 | final String target
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/encoder/ByteArrayAdapter.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.encoder
20 |
21 | import com.squareup.moshi.FromJson
22 | import com.squareup.moshi.ToJson
23 | import groovy.transform.CompileStatic
24 |
25 | /**
26 | * Moshi adapter for JSON serialization
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @CompileStatic
31 | class ByteArrayAdapter {
32 |
33 | @ToJson
34 | String serialize(byte[] data) {
35 | return Base64.getEncoder().encodeToString(data)
36 | }
37 |
38 | @FromJson
39 | byte[] deserialize(String data) {
40 | return Base64.getDecoder().decode(data)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/encoder/EncodingStrategy.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.encoder
20 |
21 | /**
22 | * Define JSON encode-decode core operations
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface EncodingStrategy {
27 |
28 | String encode(V value)
29 |
30 | V decode(String value)
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/encoder/MoshiSerializable.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.encoder
20 |
21 | /**
22 | * Marker interface for Moshi serializable objects
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface MoshiSerializable {
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/encoder/PathAdapter.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.encoder
20 |
21 | import java.nio.file.Path
22 |
23 | import com.squareup.moshi.FromJson
24 | import com.squareup.moshi.ToJson
25 |
26 | /**
27 | * Mosh adapter for {@link Path}. Only support default file system provider
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | class PathAdapter {
32 |
33 | @ToJson
34 | String serialize(Path path) {
35 | return path != null ? path.toString() : null
36 | }
37 |
38 | @FromJson
39 | Path deserialize(String data) {
40 | return data != null ? Path.of(data) : null
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/encoder/UriAdapter.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.encoder
20 |
21 |
22 | import com.squareup.moshi.FromJson
23 | import com.squareup.moshi.ToJson
24 | /**
25 | * Mosh adapter for {@link URI} class
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | class UriAdapter {
30 |
31 | @ToJson
32 | String serialize(URI uri) {
33 | return uri != null ? uri.toString() : null
34 | }
35 |
36 | @FromJson
37 | URI deserialize(String data) {
38 | return data != null ? URI.create(data) : null
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/BadRequestException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | /**
22 | * Base class for Wave exceptions
23 | */
24 | class BadRequestException extends WaveException implements HttpError {
25 |
26 | BadRequestException() {}
27 | BadRequestException(String message) { super(message) }
28 | BadRequestException(String message, Throwable cause) { super(message, cause) }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/BuildRuntimeException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Exception thrown when the build fails for an expected condition
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @CompileStatic
29 | class BuildRuntimeException extends WaveException {
30 |
31 | BuildRuntimeException(String message, Throwable cause) {
32 | super(message, cause)
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/BuildTimeoutException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 |
23 |
24 | /**
25 | *
26 | * Exception fired when the time to build an image is expired
27 | *
28 | * @author : jorge
29 | *
30 | */
31 | @CompileStatic
32 | class BuildTimeoutException extends WaveException{
33 |
34 | BuildTimeoutException(String message) {
35 | super(message)
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/DockerRegistryException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 |
22 | import groovy.transform.CompileStatic
23 | import groovy.util.logging.Slf4j
24 | import io.micronaut.http.HttpStatus
25 | /**
26 | * Hold a generic http error
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @Slf4j
31 | @CompileStatic
32 | class DockerRegistryException extends WaveException implements HttpError {
33 |
34 | final HttpStatus statusCode
35 | final String error
36 |
37 | DockerRegistryException(String message, int code, String error) {
38 | super(message)
39 | this.statusCode = HttpStatus.valueOf(code)
40 | this.error = error
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/ForbiddenException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Exception mapping to HTTP Forbidden error (403)
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @CompileStatic
29 | class ForbiddenException extends WaveException implements HttpError {
30 |
31 | ForbiddenException(String message) {
32 | super(message)
33 | }
34 |
35 | ForbiddenException(String message, Throwable cause) {
36 | super(message, cause)
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/HttpError.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | /**
22 | * Marks exception used to return HTTP errors
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface HttpError {
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/HttpServerRetryableErrorException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | /**
22 | * Capture a HTTP response error that should be manage retrying the HTTP request
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | class HttpServerRetryableErrorException extends IOException {
27 |
28 | HttpServerRetryableErrorException(String message) {
29 | super(message)
30 | }
31 |
32 | HttpServerRetryableErrorException(String message, Throwable t) {
33 | super(message,t)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/NoSenderAvailException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.InheritConstructors
22 |
23 | /**
24 | * Exception thrown when no sender is available for a Websocket target
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @InheritConstructors
29 | class NoSenderAvailException extends Exception {
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/NotFoundException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.InheritConstructors
23 |
24 | /**
25 | * Exception mapping to HTTP Not found error (404)
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @CompileStatic
30 | @InheritConstructors
31 | class NotFoundException extends WaveException implements HttpError {
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/ScanRuntimeException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Exception thrown when the scan fails for an expected condition
25 | *
26 | * @author Munish Chouhan
27 | */
28 | @CompileStatic
29 | class ScanRuntimeException extends WaveException {
30 | ScanRuntimeException(String message, Throwable cause) {
31 | super(message, cause)
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/SlowDownException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.InheritConstructors
23 |
24 |
25 | /**
26 | * @author : jorge
27 | *
28 | */
29 | @CompileStatic
30 | @InheritConstructors
31 | class SlowDownException extends WaveException implements HttpError{
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/UnauthorizedException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.InheritConstructors
23 |
24 | /**
25 | * Exception mapping to HTTP Unauthorized error (401)
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @CompileStatic
30 | @InheritConstructors
31 | class UnauthorizedException extends WaveException implements HttpError {
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exception/WaveException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exception
20 | /**
21 | * Marker interface to annotation exception bringing
22 | * a semantic message that can be visualised in the UI layer
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | abstract class WaveException extends RuntimeException {
27 | WaveException() {}
28 |
29 | WaveException(String message) { super(message) }
30 |
31 | WaveException(String message, Throwable cause) { super(message, cause) }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exchange/EmptyBodyRequest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exchange
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.TupleConstructor
23 |
24 | /**
25 | * Request with an empty body. To be OpenAPI complaint.
26 | *
27 | * @author Jordi Deu-Pons
28 | */
29 | @CompileStatic
30 | @TupleConstructor
31 | final class EmptyBodyRequest {
32 | EmptyBodyRequest() {
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exchange/ErrorResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exchange
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.TupleConstructor
23 |
24 | /**
25 | * Generic error response
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @CompileStatic
30 | @TupleConstructor
31 | final class ErrorResponse {
32 | String message
33 |
34 | ErrorResponse(String message) {
35 | this.message = message
36 | }
37 |
38 | static String of(String message) {
39 | new ErrorResponse(message)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/exchange/PairingResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.exchange
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Model the response for a remote service instance to register
25 | * itself as Wave credentials provider
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @CompileStatic
30 | class PairingResponse {
31 | String pairingId
32 | String publicKey
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/filter/FilterOrder.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.filter
20 |
21 | /**
22 | * Define the order of HTTP filters. The smaller number has higher priority
23 | *
24 | * {@link io.micronaut.core.order.Ordered}
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface FilterOrder {
29 |
30 | final int DENY_CRAWLER = -110
31 | final int DENY_PATHS = -100
32 | final int RATE_LIMITER = -50
33 | final int PULL_METRICS = 10
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/filter/RateLimiterOptions.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.filter
20 |
21 |
22 | import java.time.Duration
23 |
24 | import groovy.transform.CompileStatic
25 | import io.micronaut.context.annotation.ConfigurationProperties
26 | /**
27 | * Rate limiter config options
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | @CompileStatic
32 | @ConfigurationProperties("rate-limit.httpRequest")
33 | class RateLimiterOptions {
34 |
35 | Duration timeoutDuration
36 |
37 | Duration limitRefreshPeriod
38 |
39 | Integer limitForPeriod
40 |
41 | int statusCode
42 |
43 | void validate() {
44 | assert limitForPeriod>0, "Rate-limiter limitForPeriod must be greater than zero"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/proxy/ClientResponseException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.proxy
20 |
21 | import java.net.http.HttpRequest
22 |
23 | import groovy.transform.CompileStatic
24 |
25 | /**
26 | * Model an invalid response got by the registry client client
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @CompileStatic
31 | class ClientResponseException extends Exception {
32 |
33 | private HttpRequest request
34 |
35 | HttpRequest getRequest() { request }
36 |
37 | ClientResponseException(String message, HttpRequest request) {
38 | super(message)
39 | this.request = request
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/proxy/LoginRequest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.proxy
20 |
21 | import groovy.transform.Canonical
22 | import groovy.transform.CompileStatic
23 |
24 | /**
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @Canonical
29 | @CompileStatic
30 | class LoginRequest {
31 | String username
32 | String password
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/proxy/LoginResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.proxy
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 |
25 | /**
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @ToString(includeNames = true, includePackage = false)
30 | @EqualsAndHashCode
31 | @CompileStatic
32 | class LoginResponse {
33 | String token
34 | String access_token
35 | Integer expires_in
36 | String issued_at
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/ratelimit/AcquireRequest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.ratelimit
20 |
21 | import groovy.transform.Canonical
22 | import groovy.transform.CompileStatic
23 |
24 |
25 | /**
26 | * A simple bean to contain the userId and Ip of a request
27 | *
28 | * @author : jorge
29 | *
30 | */
31 | @Canonical
32 | @CompileStatic
33 | class AcquireRequest {
34 |
35 | /**
36 | * Principal key to use in the search. Can be null
37 | */
38 | String user
39 |
40 | /**
41 | * Secondary key to use if principal is not present
42 | */
43 | String ip
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/ratelimit/RateLimiterService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.ratelimit
20 |
21 | import io.seqera.wave.exception.SlowDownException
22 |
23 |
24 | /**
25 | * @author : jorge
26 | *
27 | */
28 | interface RateLimiterService {
29 |
30 | void acquireBuild(AcquireRequest request) throws SlowDownException
31 |
32 | void acquirePull(AcquireRequest request) throws SlowDownException
33 |
34 | boolean acquireTimeoutCounter(String endpoint)
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/CredentialsService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service
20 |
21 | import io.seqera.wave.tower.PlatformId
22 |
23 | /**
24 | * Declare operations to access container registry credentials from Tower
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface CredentialsService {
29 |
30 | ContainerRegistryKeys findRegistryCreds(String registryName, PlatformId identity)
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/UserService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service
20 |
21 |
22 | import io.seqera.wave.tower.User
23 | import io.seqera.wave.tower.auth.JwtAuth
24 | /**
25 | * Declare a service to access a Tower user
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | interface UserService {
30 |
31 | User getUserByAccessToken(String endpoint, JwtAuth auth)
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/account/AccountService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.account
20 |
21 | /**
22 | * Defines the interface for checking account identity
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface AccountService {
27 |
28 | boolean isAuthorised(String username, String password)
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/aws/AwsEcrAuthException.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.aws
20 |
21 | import groovy.transform.CompileStatic
22 | import io.seqera.wave.exception.WaveException
23 |
24 | /**
25 | * Exception thrown when there's a AWS ECR authorization failure
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @CompileStatic
30 | class AwsEcrAuthException extends WaveException {
31 |
32 | AwsEcrAuthException(String msg, Throwable t) {
33 | super(msg, t)
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/aws/cache/AwsEcrAuthToken.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.aws.cache
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 | import io.seqera.wave.encoder.MoshiSerializable
25 | /**
26 | * Model a tiered cache value for {@link AwsEcrCache}
27 | *
28 | * @author Munish Chouhan
29 | */
30 | @CompileStatic
31 | @EqualsAndHashCode
32 | @ToString(includePackage = false, includeNames = true)
33 | class AwsEcrAuthToken implements MoshiSerializable {
34 | String value
35 |
36 | AwsEcrAuthToken(String value) {
37 | this.value = value
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/blob/BlobSigningService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.blob
20 |
21 | /**
22 | * Define the contract for creating signing URLs
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface BlobSigningService {
27 |
28 | String createSignedUri(String uri)
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/blob/TransferStrategy.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.blob
20 | /**
21 | * Defines the contract to transfer a layer blob into a remote object storage
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface TransferStrategy {
26 |
27 | void launchJob(String jobName, List command)
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/blob/signing/NoBlobSigningService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.blob.signing
20 |
21 | import groovy.transform.CompileStatic
22 | import io.micronaut.context.annotation.Requires
23 | import io.seqera.wave.service.blob.BlobSigningService
24 | import jakarta.inject.Singleton
25 |
26 | /**
27 | * Implements no url signing
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | @Requires(missingProperty = 'wave.blobCache.signing-strategy')
32 | @Singleton
33 | @CompileStatic
34 | class NoBlobSigningService implements BlobSigningService{
35 |
36 | @Override
37 | String createSignedUri(String uri) {
38 | return uri
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/builder/BuildEvent.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.builder
20 |
21 | import groovy.transform.Canonical
22 | import groovy.transform.CompileStatic
23 |
24 |
25 | /**
26 | * An event fired when a build has been completed
27 | *
28 | * @author : jorge
29 | *
30 | */
31 | @Canonical
32 | @CompileStatic
33 | class BuildEvent {
34 |
35 | BuildRequest request
36 | BuildResult result
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/builder/BuildFormat.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.builder
20 |
21 | /**
22 | * Define the container file format
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | enum BuildFormat {
27 | DOCKER,
28 | SINGULARITY
29 |
30 | String render() {
31 | this.toString().toLowerCase().capitalize()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/cleanup/CleanupService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.cleanup
20 |
21 |
22 | import io.seqera.wave.service.job.JobSpec
23 | /**
24 | * Define the contract for resources cleanup service
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface CleanupService {
29 |
30 | void cleanupJob(JobSpec job, Integer exitStatus)
31 |
32 | void cleanupScanId(String containerImage)
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/counter/CounterStore.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.counter
20 |
21 | /**
22 | * Define the interface of a generic counter service
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface CounterStore {
27 |
28 | long inc(String key, long value)
29 |
30 | Long get(String key)
31 |
32 | /**
33 | * @param pattern
34 | * @return all the entries whose field matches 'pattern'
35 | */
36 | Map getAllMatchingEntries(String pattern)
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/counter/impl/CounterProvider.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.counter.impl
20 | /**
21 | * Contract interface for a generic distributed "counter" service
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface CounterProvider {
26 |
27 | long inc(String key, String field, long value)
28 |
29 | Long get(String key, String field)
30 |
31 | /**
32 | *
33 | * @param key
34 | * @param pattern
35 | * @return all the entries whose field matches 'pattern'
36 | */
37 | Map getAllMatchingEntries(String key, String pattern)
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/inclusion/ContainerInclusionService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.inclusion
20 |
21 | import io.seqera.wave.api.SubmitContainerTokenRequest
22 | import io.seqera.wave.tower.PlatformId
23 |
24 | /**
25 | * Define the interface for the container inclusion service which takes care of expanding
26 | * a list of container names into a set of layers to the added to the target request
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | interface ContainerInclusionService {
31 |
32 | SubmitContainerTokenRequest addContainerInclusions(SubmitContainerTokenRequest request, PlatformId identity)
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/job/JobEntry.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.job
20 |
21 | /**
22 | * Marker interface for a stored state entry associated with a job execution
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface JobEntry {
27 | boolean done()
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/job/JobOperation.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.job
20 | /**
21 | * Define job operations contract
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface JobOperation {
26 |
27 | JobState status(JobSpec jobSpec)
28 |
29 | void cleanup(JobSpec jobSpec)
30 |
31 | void cleanup(String jobName)
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/license/CheckTokenResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.license
20 |
21 | import java.time.Instant
22 | /**
23 | * Model the response for a License manager license token check request
24 | *
25 | * @author Munish Chouhan
26 | */
27 | class CheckTokenResponse {
28 | String id // license ID
29 | Instant expiration // license expiration timestamp
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/logs/BuildLogService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.logs
20 |
21 | import groovy.transform.Canonical
22 | import io.micronaut.http.server.types.files.StreamedFile
23 |
24 | /**
25 | * Service to manage logs
26 | *
27 | * @author Munish Chouhan
28 | */
29 | interface BuildLogService {
30 |
31 | @Canonical
32 | class BuildLog {
33 | String data
34 | boolean truncated
35 | }
36 |
37 | void storeLog(String buildId, String log)
38 |
39 | StreamedFile fetchLogStream(String buildId)
40 |
41 | BuildLog fetchLogString(String buildId)
42 |
43 | String fetchCondaLockString(String buildId)
44 |
45 | StreamedFile fetchCondaLockStream(String buildId)
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/mail/MailService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.mail
20 |
21 | import io.seqera.wave.service.builder.BuildRequest
22 | import io.seqera.wave.service.builder.BuildResult
23 | /**
24 | * Implements mail notification service
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface MailService {
29 |
30 | void sendCompletionEmail(BuildRequest request, BuildResult result)
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/mail/MailSpooler.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.mail
20 |
21 | import groovy.transform.CompileStatic
22 | import io.seqera.mail.Mail
23 | /**
24 | * Implements a Mail delivery service
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @CompileStatic
29 | interface MailSpooler {
30 |
31 | void sendMail(Mail mail)
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/metric/MetricsCounterStore.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.metric
20 |
21 | import groovy.transform.CompileStatic
22 | import io.seqera.wave.service.counter.AbstractCounterStore
23 | import io.seqera.wave.service.counter.impl.CounterProvider
24 | import jakarta.inject.Singleton
25 | /**
26 | * Implement a persistent counter service for metrics
27 | *
28 | * @author Munish Chouhan
29 | */
30 | @Singleton
31 | @CompileStatic
32 | class MetricsCounterStore extends AbstractCounterStore {
33 |
34 | MetricsCounterStore(CounterProvider provider) {
35 | super(provider)
36 | }
37 |
38 | @Override
39 | protected String getPrefix() {
40 | return 'metrics/v1'
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/metric/model/GetOrgArchCountResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.metric.model
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Model organisations counts with architecture response
25 | *
26 | * @author Munish Chouhan
27 | */
28 | @CompileStatic
29 | class GetOrgArchCountResponse {
30 | String metric
31 | String arch
32 | Long count
33 | Map orgs
34 |
35 | GetOrgArchCountResponse(String metric, String arch, Long count, Map orgs) {
36 | this.metric = metric
37 | this.arch = arch
38 | this.count = count
39 | this.orgs = orgs
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/metric/model/GetOrgCountResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 | package io.seqera.wave.service.metric.model
19 |
20 | import groovy.transform.CompileStatic
21 |
22 | /**
23 | * Model organisations counts response
24 | *
25 | * @author Munish Chouhan
26 | */
27 | @CompileStatic
28 | class GetOrgCountResponse {
29 | String metric
30 | Long count
31 | Map orgs
32 |
33 | GetOrgCountResponse(String metric, Long count, Map orgs) {
34 | this.metric = metric
35 | this.count = count
36 | this.orgs = orgs
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/pairing/socket/MessageSender.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.pairing.socket
20 | /**
21 | * Interface modelling a generic message sender
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface MessageSender {
26 |
27 | void send(M message)
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/pairing/socket/msg/PairingHeartbeat.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.pairing.socket.msg
20 |
21 | import groovy.transform.Canonical
22 | import groovy.transform.CompileStatic
23 | import groovy.transform.ToString
24 |
25 | /**
26 | * Model pairing heartbeat message
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @Canonical
31 | @CompileStatic
32 | @ToString(includePackage = false, includeNames = true)
33 | class PairingHeartbeat implements PairingMessage {
34 | String msgId
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/pairing/socket/msg/PairingResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.pairing.socket.msg
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.ToString
23 |
24 | /**
25 | * Model the response for a remote service instance to register
26 | * itself as Wave credentials provider
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @CompileStatic
31 | @ToString(includePackage = false, includeNames = true)
32 | class PairingResponse implements PairingMessage {
33 | String msgId
34 | String pairingId
35 | String publicKey
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/pairing/socket/msg/ProxyHttpRequest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.pairing.socket.msg
20 |
21 | import groovy.transform.Canonical
22 | import groovy.transform.CompileStatic
23 | import groovy.transform.ToString
24 | /**
25 | * Model a remote HTTP request send via WebSocket connection
26 | *
27 | * @author Jordi Deu-Pons
28 | */
29 | @Canonical
30 | @CompileStatic
31 | @ToString(includePackage = false, includeNames = true)
32 | class ProxyHttpRequest implements PairingMessage {
33 | String msgId
34 | String method
35 | String uri
36 | String auth
37 | String body
38 | Map> headers
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/pairing/socket/msg/ProxyHttpResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.pairing.socket.msg
20 |
21 |
22 | import groovy.transform.Canonical
23 | import groovy.transform.CompileStatic
24 | import groovy.transform.ToString
25 |
26 | /**
27 | * Model a remote HTTP response send via WebSocket connection
28 | *
29 | * @author Jordi Deu-Pons
30 | */
31 | @Canonical
32 | @CompileStatic
33 | @ToString(includePackage = false, includeNames = true)
34 | class ProxyHttpResponse implements PairingMessage {
35 | String msgId
36 | Integer status
37 | String body
38 | Map> headers
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/persistence/PostgresIgnore.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.persistence
20 |
21 | import java.lang.annotation.ElementType
22 | import java.lang.annotation.Retention
23 | import java.lang.annotation.RetentionPolicy
24 | import java.lang.annotation.Target
25 |
26 | /**
27 | * Marker annotation to ignore a field when serializing for PostgreSQL database
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target([ElementType.FIELD])
33 | @interface PostgresIgnore {
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/persistence/impl/SurrealResult.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.persistence.impl
20 |
21 | /**
22 | * Model a Surreal Resultset
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | class SurrealResult {
27 |
28 | String time
29 | String status
30 | T[] result
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/persistence/migrate/MigrationOnly.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.persistence.migrate
20 |
21 | import java.lang.annotation.ElementType
22 | import java.lang.annotation.Retention
23 | import java.lang.annotation.RetentionPolicy
24 | import java.lang.annotation.Target
25 |
26 | /**
27 | * Marker annotation to annotate logic required for Surreal to Postgres migration
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | @Retention(RetentionPolicy.RUNTIME)
32 | @Target([ElementType.TYPE, ElementType.METHOD])
33 | @interface MigrationOnly {
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/persistence/migrate/cache/DataMigrateEntry.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2025, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.persistence.migrate.cache
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 |
25 | /**
26 | * Data migration entry
27 | *
28 | * @author Munish Chouhan
29 | */
30 | @ToString(includeNames = true, includePackage = false)
31 | @EqualsAndHashCode
32 | @CompileStatic
33 | class DataMigrateEntry {
34 | String tableName
35 | int offset
36 |
37 | DataMigrateEntry(String tableName, int offset) {
38 | this.tableName = tableName
39 | this.offset = offset
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/request/ContainerRequestStore.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.request
20 | /**
21 | * Define the container request token persistence operations
22 | *
23 | * @author : jorge
24 | *
25 | */
26 | interface ContainerRequestStore {
27 |
28 | void put(String key, ContainerRequest request)
29 |
30 | ContainerRequest get(String key)
31 |
32 | void remove(String key)
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/request/ContainerStatusService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.request
20 |
21 |
22 | import io.seqera.wave.api.ContainerStatusResponse
23 | /**
24 | * Define the contract for container request status service
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface ContainerStatusService {
29 |
30 | ContainerStatusResponse getContainerStatus(String requestId)
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/request/TokenData.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.request
20 |
21 | import java.time.Instant
22 |
23 | import groovy.transform.Canonical
24 |
25 | /**
26 | * Model container token
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @Canonical
31 | class TokenData {
32 | final String value
33 | final Instant expiration
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/scan/Trivy.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.scan
20 |
21 | /**
22 | * Trivy constants
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface Trivy {
27 |
28 | static final public String CACHE_MOUNT_PATH = '/root/.cache/'
29 |
30 | static final public String CONFIG_MOUNT_PATH = '/root/.docker/config.json'
31 |
32 | static final public String OUTPUT_FILE_NAME = 'report.json'
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/stream/StreamService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.stream
20 |
21 | import io.seqera.wave.tower.PlatformId
22 |
23 | /**
24 | * Define the interface for remote resource steaming
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | interface StreamService {
29 |
30 | InputStream stream(String location, PlatformId identity)
31 |
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/service/validation/ValidationService.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.validation
20 |
21 | /**
22 | * Validation service
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface ValidationService {
27 |
28 | String checkEndpoint(String endpoint)
29 |
30 | String checkContainerName(String name)
31 |
32 | String checkBuildRepository(String repo, ValidationServiceImpl.RepoType type)
33 |
34 | boolean isCustomRepo(String repo)
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/storage/DigestStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage;
20 |
21 | import java.io.Serializable;
22 |
23 | /**
24 | * Define the interface for a container layer digests caching
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | public interface DigestStore extends Serializable {
29 |
30 | byte[] getBytes() throws InterruptedException;
31 | String getMediaType();
32 | String getDigest();
33 | Integer getSize();
34 |
35 | default String toLogString() {
36 | return toString();
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/storage/Storage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage;
20 |
21 |
22 | import java.util.Optional;
23 |
24 | import io.seqera.wave.api.ContainerLayer;
25 |
26 | /**
27 | * @author : jorge
28 | **/
29 | public interface Storage {
30 |
31 | Optional getManifest(String path);
32 |
33 | DigestStore saveManifest(String path, String manifest, String type, String digest);
34 |
35 | DigestStore saveManifest(String path, DigestStore store);
36 |
37 | Optional getBlob(String path);
38 |
39 | DigestStore saveBlob(String path, byte[] content, String type, String digest);
40 |
41 | DigestStore saveBlob(String path, ContainerLayer layer);
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/cache/L2TieredCache.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.cache
20 | /**
21 | * Define the interface for 2nd level tired cache
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface L2TieredCache extends TieredCache {
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/cache/TieredKey.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.cache
20 |
21 | /**
22 | * Define the contract for key used by {@link TieredCache} caches
23 | *
24 | * @author Munish Chouhan
25 | */
26 | interface TieredKey {
27 |
28 | String stableHash()
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/range/RangeStore.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.range
20 | /**
21 | * Define the contract for a storage range set similar to Redis `zrange`
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface RangeStore {
26 |
27 | void add(String member, double score)
28 |
29 | List getRange(double min, double max, int count)
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/range/impl/RangeProvider.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.range.impl
20 | /**
21 | * Contract for range store provider
22 | *
23 | * @author Paolo Di Tommaso
24 | */
25 | interface RangeProvider {
26 |
27 | void add(String key, String member, double score)
28 |
29 | List getRange(String key, double min, double max, int count, boolean remove)
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/state/CountParams.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.state
20 |
21 | import groovy.transform.Canonical
22 |
23 | /**
24 | * Model state store auto increment params
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @Canonical
29 | class CountParams {
30 | final String key
31 | final String field
32 |
33 | static CountParams of(String key) {
34 | final p=key.lastIndexOf('/')
35 | return p==-1
36 | ? new CountParams("counters/v1", key)
37 | : new CountParams(key.substring(0,p), key.substring(p+1))
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/state/CountResult.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.state
20 |
21 | import groovy.transform.Canonical
22 |
23 | /**
24 | * Model the result object of state auto-increment operation
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | @Canonical
29 | class CountResult {
30 | final Boolean succeed
31 | final V value
32 | final Integer count
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/state/RequestIdAware.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.state
20 |
21 | /**
22 | * Marker interface for record object that model long running operation state
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface RequestIdAware {
27 |
28 | String getRequestId()
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/store/state/StateEntry.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.state
20 |
21 | /**
22 | * Marker interface for a state store entry
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | interface StateEntry {
27 | K getKey()
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/tower/client/GetServiceInfoResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.client
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.ToString
23 |
24 | /**
25 | * Model Tower service info response
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | @ToString(includePackage = false, includeNames = true)
30 | @CompileStatic
31 | class GetServiceInfoResponse {
32 |
33 | @ToString(includePackage = false, includeNames = true)
34 | static class ServiceInfo {
35 | String version
36 | String apiVersion
37 | String commitId
38 | Boolean waveEnabled
39 | }
40 |
41 | ServiceInfo serviceInfo
42 | }
43 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/tower/client/GetUserInfoResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.client
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 | import io.seqera.wave.encoder.MoshiSerializable
25 | import io.seqera.wave.tower.User
26 | /**
27 | * Model a Tower user-info response
28 | * @author Paolo Di Tommaso
29 | */
30 | @EqualsAndHashCode
31 | @ToString(includePackage = false, includeNames = true)
32 | @CompileStatic
33 | class GetUserInfoResponse implements MoshiSerializable {
34 | User user
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/tower/client/ListCredentialsResponse.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.client
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 | import io.seqera.wave.encoder.MoshiSerializable
25 |
26 | @EqualsAndHashCode
27 | @ToString(includePackage = false, includeNames = true)
28 | @CompileStatic
29 | class ListCredentialsResponse implements MoshiSerializable {
30 |
31 | List credentials
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/tower/compute/ComputeEnv.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.compute
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 | import io.seqera.wave.encoder.MoshiSerializable
25 |
26 | /**
27 | * Model the response of compute environment from seqera platform
28 | *
29 | * @author Munish Chouhan
30 | */
31 | @CompileStatic
32 | @EqualsAndHashCode
33 | @ToString(includePackage = false, includeNames = true)
34 | class ComputeEnv implements MoshiSerializable {
35 | String id
36 | String platform
37 | String credentialsId
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/tower/compute/WorkflowLaunch.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.compute
20 |
21 | import groovy.transform.CompileStatic
22 | import groovy.transform.EqualsAndHashCode
23 | import groovy.transform.ToString
24 | import io.seqera.wave.encoder.MoshiSerializable
25 |
26 | /**
27 | * Model the response of workflow launch response from seqera platform
28 | *
29 | * @author Munish Chouhan
30 | */
31 | @CompileStatic
32 | @EqualsAndHashCode
33 | @ToString(includePackage = false, includeNames = true)
34 | class WorkflowLaunch implements MoshiSerializable {
35 | ComputeEnv computeEnv
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/util/FutureUtils.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.util
20 |
21 | import java.util.concurrent.CompletableFuture
22 |
23 | /**
24 | * Future class helpers
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | class FutureUtils {
29 |
30 | static CompletableFuture completeExceptionally(Throwable t) {
31 | final result = new CompletableFuture()
32 | result.completeExceptionally(t)
33 | return result
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/util/TypeHelper.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.util
20 |
21 | import java.lang.reflect.ParameterizedType
22 | import java.lang.reflect.Type
23 |
24 | import groovy.transform.CompileStatic
25 |
26 | /**
27 | * Helper class to handle Java types
28 | *
29 | * @author Paolo Di Tommaso
30 | */
31 | @CompileStatic
32 | class TypeHelper {
33 |
34 | static Type getGenericType(Object object, int index) {
35 | final params = (ParameterizedType) (object.getClass().getGenericSuperclass());
36 | return params.getActualTypeArguments()[index]
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/groovy/io/seqera/wave/util/Views.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.util
20 |
21 | import groovy.transform.CompileStatic
22 |
23 | /**
24 | * Implements Json views marker classes to be used with @JsonView annotation
25 | *
26 | * See https://www.baeldung.com/jackson-json-view-annotation
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @CompileStatic
31 | class Views {
32 |
33 | /** Marker class for public fields */
34 | static abstract class Public { }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/jib/launch.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | # Launch backend server
20 | [ "$WAVE_JVM_OPTS" ] && echo "Detected WAVE_JVM_OPTS=$WAVE_JVM_OPTS"
21 | exec java \
22 | -Dfile.encoding=UTF-8 \
23 | -Dcom.sun.security.enableAIAcaIssuers=true \
24 | --add-opens java.base/java.lang=ALL-UNNAMED \
25 | --add-opens java.base/java.math=ALL-UNNAMED \
26 | --add-opens java.base/java.net=ALL-UNNAMED \
27 | --add-opens java.base/java.text=ALL-UNNAMED \
28 | --add-opens java.base/java.util=ALL-UNNAMED \
29 | --add-opens java.base/java.util.concurrent=ALL-UNNAMED \
30 | --add-opens java.base/java.io=ALL-UNNAMED \
31 | --add-opens java.base/java.nio=ALL-UNNAMED \
32 | --enable-native-access=ALL-UNNAMED \
33 | ${WAVE_JVM_OPTS} \
34 | -cp /app/resources:/app/classes:/app/libs/* \
35 | io.seqera.wave.Application
36 |
--------------------------------------------------------------------------------
/src/main/resources/application-blobcache-dev.yml:
--------------------------------------------------------------------------------
1 | wave:
2 | blobCache:
3 | enabled: true
4 | baseUrl: "https://nextflow-ci.s3.eu-west-1.amazonaws.com/blobs"
5 | storage:
6 | bucket: "s3://nextflow-ci/blobs"
7 |
--------------------------------------------------------------------------------
/src/main/resources/application-buildlogs-aws-test.yml:
--------------------------------------------------------------------------------
1 | ---
2 | wave:
3 | build:
4 | logs:
5 | path: "s3://nextflow-ci/test/l1"
6 | locks:
7 | path: "s3://nextflow-ci"
8 | ...
9 |
--------------------------------------------------------------------------------
/src/main/resources/application-dev-k8s.yml:
--------------------------------------------------------------------------------
1 | #
2 | # Use this environment to configure use a local Kubernetes cluster to build wave containers
3 | #
4 | # - add "dev-k8s" to the list of environments defined in the 'micronautEnvs' property in the "gradle.property" file
5 | # - create the directory "${HOME}/.wave/build-workspace"
6 | # - change the Kubernetes context in the config below with the one matching your installation
7 | # - create a namespace in your local Kubernetes cluster named "wave-local"
8 | #
9 | wave:
10 | build:
11 | debug: true
12 | workspace: "${HOME}/.wave/build-workspace"
13 | k8s:
14 | dns:
15 | servers:
16 | - "1.1.1.1"
17 | - "8.8.8.8"
18 | configPath: "${HOME}/.kube/config"
19 | context: 'docker-desktop'
20 | namespace: 'wave-local'
21 | storage:
22 | mountPath: "${HOME}/.wave/build-workspace"
23 | ...
24 |
--------------------------------------------------------------------------------
/src/main/resources/application-dev.yml:
--------------------------------------------------------------------------------
1 | wave:
2 | debug: true
3 | scan:
4 | enabled: true
5 | failure:
6 | duration: '30s'
7 | build:
8 | workspace: 'build-workspace'
9 | logs:
10 | path: "${PWD}/build-workspace/logs"
11 | locks:
12 | path: "${PWD}/build-workspace/locks"
13 | metrics:
14 | enabled: true
15 | accounts:
16 | ### password checksum 'bar'
17 | foo: "fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9"
18 | jwt:
19 | refresh:
20 | interval: '10s'
21 | monitor:
22 | interval: '5s'
23 | cleanup:
24 | succeeded: '10s'
25 | failed: '45s'
26 | strategy: 'onsuccess'
27 | trace:
28 | local-persistence:
29 | threshold: 100
30 | surreal-persistence:
31 | threshold: 100
32 | proxy-service:
33 | threshold: 100
34 | ---
35 | endpoints:
36 | metrics:
37 | enabled: true
38 | ---
39 | # uses TOWER_xxx variable because the dev environment is expected to be
40 | # the same as of tower
41 | mail:
42 | from: "${TOWER_CONTACT_EMAIL:wave-app+dev@seqera.io}"
43 | ---
44 | logger:
45 | levels:
46 | io.seqera.wave.service.data: DEBUG
47 | io.seqera.wave.service.pairing: TRACE
48 | io.seqera.wave.service.job: DEBUG
49 | io.seqera.wave.service.k8s.K8sServiceImpl: TRACE
50 | io.seqera.wave.tower.client.connector: TRACE
51 | # io.seqera.wave.tower.client: 'TRACE'
52 | # io.seqera.wave.store.cache: 'TRACE'
53 | # io.seqera.wave.tower.auth: 'TRACE'
54 | # io.seqera.wave.core.RegistryProxyService: TRACE
55 | ...
56 |
--------------------------------------------------------------------------------
/src/main/resources/application-licman.yml:
--------------------------------------------------------------------------------
1 | ---
2 | license:
3 | server:
4 | url: "${LICENSE_SERVER_URL:`http://localhost:7070`}"
5 | ---
6 |
--------------------------------------------------------------------------------
/src/main/resources/application-mysql.yml:
--------------------------------------------------------------------------------
1 | ---
2 | datasources:
3 | default:
4 | dialect: MYSQL
5 |
--------------------------------------------------------------------------------
/src/main/resources/application-postgres.yml:
--------------------------------------------------------------------------------
1 | wave:
2 | db:
3 | uri: "jdbc:postgresql://localhost:5432/postgres"
4 | user: "postgres"
5 | password: ""
6 | datasources:
7 | default:
8 | db-type: postgres
9 | dialect: POSTGRES
10 | driver-class-name: org.postgresql.Driver
11 | url: "${wave.db.uri}"
12 | username: "${wave.db.user}"
13 | password: "${wave.db.password}"
14 |
15 |
--------------------------------------------------------------------------------
/src/main/resources/application-prometheus.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | metrics:
3 | enabled: true
4 | export :
5 | prometheus :
6 | enabled : true
7 | step : PT1M
8 | descriptions : true
9 | binders:
10 | web:
11 | server:
12 | percentiles: "0.95,0.99"
13 | client:
14 | percentiles: "0.95,0.99"
15 | netty:
16 | queues:
17 | enabled: true
18 | bytebuf-allocators:
19 | enabled: true
20 | channels:
21 | enabled: true
22 | jdbc:
23 | enabled: true
24 | endpoints:
25 | prometheus:
26 | sensitive: false
27 |
--------------------------------------------------------------------------------
/src/main/resources/application-rate-limit.yml:
--------------------------------------------------------------------------------
1 | ---
2 | rate-limit:
3 | build:
4 | anonymous: 10/1h
5 | authenticated: 10/1m
6 | pull:
7 | anonymous: 100/1h
8 | authenticated: 100/1m
9 | timeout-errors:
10 | maxRate: 20/2m
11 | httpRequest:
12 | timeout-duration : 500ms
13 | limit-refresh-period : 1s
14 | limit-for-period : 100
15 | status-code : 429
16 | ---
17 | micronaut:
18 | caches:
19 | rate-limiter:
20 | expire-after-access: 10m
21 | ...
22 |
--------------------------------------------------------------------------------
/src/main/resources/application-redis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | redis:
3 | uri: redis://${REDIS_HOST:redis}:${REDIS_PORT:6379}
4 | pool:
5 | enabled: true
6 | ...
7 |
--------------------------------------------------------------------------------
/src/main/resources/application-surrealdb-legacy.yml:
--------------------------------------------------------------------------------
1 | ---
2 | surreal:
3 | legacy:
4 | ns: "seqera"
5 | db: "wave"
6 | url: "http://surrealdb:8000"
7 | user: "root"
8 | password: "root"
9 | ...
10 |
--------------------------------------------------------------------------------
/src/main/resources/application-surrealdb.yml:
--------------------------------------------------------------------------------
1 | ---
2 | surreal:
3 | default:
4 | ns : "seqera"
5 | db : "wave"
6 | url: "http://surrealdb:8000"
7 | user: "root"
8 | password: "root"
9 | ...
10 |
--------------------------------------------------------------------------------
/src/main/resources/bootstrap-ec2.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | config-client:
3 | enabled: true
4 | aws:
5 | client:
6 | system-manager:
7 | parameterstore:
8 | enabled: true
9 | use-secure-parameters: true
10 |
--------------------------------------------------------------------------------
/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | config-client:
3 | enabled: false
4 | aws:
5 | region: "${AWS_REGION:eu-west-1}"
6 |
--------------------------------------------------------------------------------
/src/main/resources/io/seqera/wave/assets/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow: /
3 |
--------------------------------------------------------------------------------
/src/main/resources/io/seqera/wave/assets/seqera-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/src/main/resources/io/seqera/wave/assets/seqera-logo.png
--------------------------------------------------------------------------------
/src/main/resources/io/seqera/wave/assets/wave-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/src/main/resources/io/seqera/wave/assets/wave-logo.png
--------------------------------------------------------------------------------
/src/main/resources/io/seqera/wave/assets/wave.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/src/main/resources/io/seqera/wave/assets/wave.ico
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/auth/RegistryTokenStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.auth
20 |
21 | import spock.lang.Specification
22 |
23 | import io.micronaut.test.extensions.spock.annotation.MicronautTest
24 | import jakarta.inject.Inject
25 |
26 | /**
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @MicronautTest
31 | class RegistryTokenStoreTest extends Specification {
32 |
33 | @Inject RegistryTokenStore store
34 |
35 | def 'should return entry key' () {
36 | expect:
37 | store.key0('foo') == 'registry-token/v1:foo'
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/filter/TraceContextFilterTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.filter
20 |
21 | import spock.lang.Specification
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | class TraceContextFilterTest extends Specification {
28 |
29 | def 'should validate request id regex' () {
30 | expect:
31 | TraceContextFilter.getRequestId(PATH) == EXPECTED
32 | where:
33 | PATH | EXPECTED
34 | '/foo/bar' | null
35 | '/v2/wt/1234' | '1234'
36 | '/v2/wt/12ab/x/y/z' | '12ab'
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/account/AccountServiceTest.groovy:
--------------------------------------------------------------------------------
1 | package io.seqera.wave.service.account
2 |
3 | import spock.lang.Specification
4 |
5 | import io.micronaut.test.extensions.spock.annotation.MicronautTest
6 | import jakarta.inject.Inject
7 |
8 | /**
9 | *
10 | * @author Paolo Di Tommaso
11 | */
12 | @MicronautTest
13 | class AccountServiceTest extends Specification {
14 |
15 | @Inject
16 | AccountService accountService
17 |
18 |
19 | def 'should validate auth service' () {
20 | expect:
21 | !accountService.isAuthorised(null,null)
22 | !accountService.isAuthorised('foo','foo')
23 | and:
24 | // check the config "application-test.yml" for these accounts
25 | accountService.isAuthorised('foo','hello')
26 | accountService.isAuthorised('bar','world')
27 | }
28 |
29 | def 'should digest string' () {
30 | given:
31 | def service = new AccountServiceImpl()
32 | expect:
33 | service.digest('hello') == '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
34 | service.digest('world') == '486ea46224d1bb4fb680f34f7c9ad96a8f24ec88be73ea8e5a6c65260e9cb8a7'
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/cleanup/CleanupConfigTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.cleanup
20 |
21 | import spock.lang.Specification
22 |
23 | import java.time.Duration
24 |
25 | /**
26 | *
27 | * @author Paolo Di Tommaso
28 | */
29 | class CleanupConfigTest extends Specification {
30 |
31 | def 'should get random delay' () {
32 | when:
33 | def d = Duration.ofSeconds(10)
34 | def config = new CleanupConfig(cleanupStartupDelay: d)
35 | then:
36 | config.cleanupStartupDelay == d
37 | and:
38 | config.cleanupStartupDelayRandomized >= d.dividedBy(2)
39 | config.cleanupStartupDelayRandomized < (d + d.dividedBy(2))
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/data/future/impl/LocalFutureHashTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.data.future.impl
20 |
21 | import spock.lang.Specification
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | class LocalFutureHashTest extends Specification {
28 |
29 | def 'should set and get a value' () {
30 | given:
31 | def queue = new LocalFutureHash()
32 |
33 | expect:
34 | queue.take('xyz') == null
35 |
36 | when:
37 | queue.put('xyz', 'hello', null)
38 | then:
39 | queue.take('xyz') == 'hello'
40 | and:
41 | queue.take('xyz') == null
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/data/stream/TestMessage.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.data.stream
20 |
21 | import groovy.transform.Canonical
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | @Canonical
28 | class TestMessage {
29 | String x
30 | String y
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/data/stream/TestStream.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.data.stream
20 |
21 | import java.time.Duration
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | class TestStream extends AbstractMessageStream {
28 |
29 | TestStream(MessageStream target) {
30 | super(target)
31 | }
32 |
33 | @Override
34 | protected String name() {
35 | return 'test-stream'
36 | }
37 |
38 | @Override
39 | protected Duration pollInterval() {
40 | return Duration.ofSeconds(1)
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/request/ContainerRequestStoreImplTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.request
20 |
21 | import spock.lang.Specification
22 |
23 | import io.micronaut.test.extensions.spock.annotation.MicronautTest
24 | import jakarta.inject.Inject
25 |
26 | /**
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @MicronautTest
31 | class ContainerRequestStoreImplTest extends Specification {
32 |
33 | @Inject ContainerRequestStoreImpl store
34 |
35 | def 'should return entry key' () {
36 | expect:
37 | store.key0('foo') == 'wave-tokens/v1:foo'
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/service/scan/ScanStateStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.service.scan
20 |
21 | import spock.lang.Specification
22 |
23 | import io.micronaut.test.extensions.spock.annotation.MicronautTest
24 | import jakarta.inject.Inject
25 |
26 | /**
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @MicronautTest
31 | class ScanStateStoreTest extends Specification {
32 |
33 | @Inject ScanStateStore store
34 |
35 | def 'should return entry key' () {
36 | expect:
37 | store.key0('foo') == 'wave-scan/v1:foo'
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/storage/DockerDigestStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage
20 |
21 | import spock.lang.Specification
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | class DockerDigestStoreTest extends Specification {
28 |
29 | def 'should create docker store' () {
30 | when:
31 | def store = new DockerDigestStore('docker://quay.io/v2/etc','some/media','sha256:12345', 100)
32 | then:
33 | store.location == 'docker://quay.io/v2/etc'
34 | store.mediaType == 'some/media'
35 | store.digest == 'sha256:12345'
36 | store.size == 100
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/storage/HttpDigestStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage
20 |
21 | import spock.lang.Specification
22 |
23 | /**
24 | *
25 | * @author Paolo Di Tommaso
26 | */
27 | class HttpDigestStoreTest extends Specification {
28 |
29 | def 'should create http store' () {
30 | when:
31 | def store = new HttpDigestStore('http://quay.io/v2/etc','some/media','sha256:12345', 100)
32 | then:
33 | store.location == 'http://quay.io/v2/etc'
34 | store.mediaType == 'some/media'
35 | store.digest == 'sha256:12345'
36 | store.size == 100
37 |
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/storage/ManifestCacheStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage
20 |
21 | import spock.lang.Specification
22 |
23 | import io.micronaut.test.extensions.spock.annotation.MicronautTest
24 | import jakarta.inject.Inject
25 |
26 | /**
27 | *
28 | * @author Paolo Di Tommaso
29 | */
30 | @MicronautTest
31 | class ManifestCacheStoreTest extends Specification {
32 |
33 | @Inject
34 | ManifestCacheStore store
35 |
36 | def 'should return entry key' () {
37 | expect:
38 | store.key0('foo') == 'wave-blobs/v1:foo'
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/storage/ZippedDigestStoreTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.storage
20 |
21 | import spock.lang.Specification
22 | /**
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | class ZippedDigestStoreTest extends Specification {
27 |
28 | def 'should load a lazy digest' () {
29 | given:
30 | def CONTENT = 'Hello world!'
31 |
32 | when:
33 | def digest = ZippedDigestStore.fromUncompressed(CONTENT.bytes, 'text', 'sha256:122345567890', 3000)
34 | then:
35 | digest.bytes == CONTENT.bytes
36 | digest.digest == 'sha256:122345567890'
37 | digest.mediaType == 'text'
38 | digest.size == 3000
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/store/state/CountParamsTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.store.state
20 |
21 | import spock.lang.Specification
22 | /**
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | class CountParamsTest extends Specification {
27 |
28 | def 'should split key'() {
29 | when:
30 | def result = CountParams.of(KEY)
31 | then:
32 | result == EXPECTED
33 | where:
34 | KEY | EXPECTED
35 | 'one' | new CountParams("counters/v1", "one")
36 | 'one/two' | new CountParams("one", "two")
37 | 'one/two/three' | new CountParams("one/two", "three")
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/tower/auth/JwtConfigTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.tower.auth
20 |
21 | import spock.lang.Specification
22 |
23 | import java.time.Duration
24 | /**
25 | *
26 | * @author Paolo Di Tommaso
27 | */
28 | class JwtConfigTest extends Specification {
29 |
30 | def 'should get random delay' () {
31 | when:
32 | def d = Duration.ofSeconds(10)
33 | def config = new JwtConfig(monitorDelay: d)
34 | then:
35 | config.monitorDelay == d
36 | and:
37 | config.monitorDelayRandomized >= d.dividedBy(2)
38 | config.monitorDelayRandomized < (d + d.dividedBy(2))
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/groovy/io/seqera/wave/util/BuildInfoTest.groovy:
--------------------------------------------------------------------------------
1 | /*
2 | * Wave, containers provisioning service
3 | * Copyright (c) 2023-2024, Seqera Labs
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU Affero General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU Affero General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU Affero General Public License
16 | * along with this program. If not, see .
17 | */
18 |
19 | package io.seqera.wave.util
20 |
21 | import spock.lang.Specification
22 | /**
23 | *
24 | * @author Paolo Di Tommaso
25 | */
26 | class BuildInfoTest extends Specification {
27 |
28 | def 'should load version and commit id' () {
29 | expect:
30 | BuildInfo.getName() == 'wave'
31 | BuildInfo.getVersion()
32 | BuildInfo.getCommitId()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/resources/application-rate-limit.yml:
--------------------------------------------------------------------------------
1 | ---
2 | rate-limit:
3 | build:
4 | anonymous: 2/1m
5 | authenticated: 2/1m
6 | pull:
7 | anonymous: 2/1m
8 | authenticated: 2/1m
9 | timeout-errors:
10 | maxRate: 2/1m
11 |
--------------------------------------------------------------------------------
/src/test/resources/application-test-deny-paths.yml:
--------------------------------------------------------------------------------
1 | ---
2 | wave:
3 | denyPaths:
4 | - /container-token/token1
5 | ...
6 |
--------------------------------------------------------------------------------
/src/test/resources/foo/dummy.gzip:
--------------------------------------------------------------------------------
1 | Hi
--------------------------------------------------------------------------------
/src/test/resources/foo/layer.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": [
3 | "/opt/fusion/entry.sh"
4 | ],
5 | "workingDir": null,
6 | "cmd": null,
7 | "env": [
8 | "FOO=bar"
9 | ],
10 | "layers": [
11 | {
12 | "location": "replaced by the test",
13 | "gzipDigest": "sha256:3639efcd08abb273b1619e82e78c29a7df02c1051b1820e99fc395dcaa3326b8",
14 | "gzipSize": 2,
15 | "tarDigest": "sha256:fb27fedd4167ca99809b566b799e62ea930cee9f70ec35dc4bcb623dbb357788"
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/src/test/resources/logback-test.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | false
25 |
26 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/test/resources/pack/layers/layer.json:
--------------------------------------------------------------------------------
1 | {
2 | "entrypoint": [
3 | "/opt/fusion/entry.sh"
4 | ],
5 | "workingDir": null,
6 | "cmd": null,
7 | "env": [
8 | "FOO=bar"
9 | ],
10 | "append": {
11 | "location": "layer.tar.gzip",
12 | "gzipDigest": "sha256:fe73ccd62aa94aefddad4544b6436c718df9b7aff8cfcc6eb8cf9a2d833869ce",
13 | "gzipSize": 13233364,
14 | "tarDigest": "sha256:9da8322478e34933f34ab4e6ac22097dc7a52bd3c074b0e50948e8fcb3a56897"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/test/resources/pack/layers/layer.tar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/src/test/resources/pack/layers/layer.tar
--------------------------------------------------------------------------------
/src/test/resources/pack/layers/layer.tar.gzip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/seqeralabs/wave/3e729804b83629bc70fb63c980d50d5efbc5ab7b/src/test/resources/pack/layers/layer.tar.gzip
--------------------------------------------------------------------------------
/src/test/resources/registry.password:
--------------------------------------------------------------------------------
1 | # user test, password test generated with `htpasswd -Bc registry.password test`
2 | test:$2y$05$/NvxvGb9Q.UqL2e6Itko9.0udleyunDegp/HklqQ...wImLupWhEK
3 |
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Wave, containers provisioning service
3 | # Copyright (c) 2023-2024, Seqera Labs
4 | #
5 | # This program is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU Affero General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # This program is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU Affero General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Affero General Public License
16 | # along with this program. If not, see .
17 | #
18 |
19 | ./gradlew test --tests 'ProxyClientTest'
20 |
--------------------------------------------------------------------------------
/typespec/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginxinc/nginx-unprivileged:alpine
2 |
3 | # Copy index.html and openapi.yaml to the Nginx html directory
4 | COPY index.html /usr/share/nginx/html/openapi/index.html
5 | COPY tsp-output/@typespec/openapi3/openapi.yaml /usr/share/nginx/html/openapi/openapi.yaml
6 |
7 | # Expose port 8080
8 | EXPOSE 8080
9 |
10 | CMD ["nginx", "-g", "daemon off;"]
11 |
--------------------------------------------------------------------------------
/typespec/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Wave API Documentation
7 |
8 |
9 |
10 |
11 |
12 |
13 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/typespec/main.tsp:
--------------------------------------------------------------------------------
1 | import "@typespec/http";
2 | import "@typespec/rest";
3 | import "@typespec/openapi3";
4 | import "@typespec/versioning";
5 | import "./routes.tsp";
6 |
--------------------------------------------------------------------------------
/typespec/models/BuildStatusResponse.tsp:
--------------------------------------------------------------------------------
1 | import "./Status.tsp";
2 |
3 | @doc("Response payload for build status.")
4 | @example(#{
5 | id:"6c084f2e43f86a78_1",
6 | status:Status.COMPLETED,
7 | startTime:"2024-04-09T20:31:35.355423Z",
8 | duration: "123.914989000",
9 | succeeded: true
10 | }
11 | )
12 | model BuildStatusResponse {
13 | duration: string;
14 | id: string;
15 | startTime: string;
16 | status: Status;
17 | succeeded: boolean;
18 | }
19 |
--------------------------------------------------------------------------------
/typespec/models/CondaOpts.tsp:
--------------------------------------------------------------------------------
1 | @doc("Options for Conda environments.")
2 | @example(#{
3 | basePackages: "python=3.8",
4 | commands: #["pip install bwa", "pip install salmon"],
5 | mambaImage: "mambaorg/micromamba:0.15.3"
6 | })
7 | model CondaOpts {
8 | @doc("Names of base packages.")
9 | basePackages: string;
10 | @doc("Command to be included in the container.")
11 | commands: string[];
12 | @doc("Name of the docker image used to build Conda containers.")
13 | mambaImage: string;
14 | }
15 |
--------------------------------------------------------------------------------
/typespec/models/CondaPackages.tsp:
--------------------------------------------------------------------------------
1 | import "./CondaOpts.tsp";
2 |
3 | @doc("Package configurations for container builds.")
4 | model CondaPackages {
5 | @doc("Conda channels to search for packages.")
6 | channels: string[];
7 | condaOpts?: CondaOpts;
8 | @doc("Conda packages to install.")
9 | entries: string[];
10 | @doc("The package environment file encoded as a base64 string.")
11 | environment?: string;
12 | @doc("This represents the type of package builder. Use `CONDA`.")
13 | type: "CONDA";
14 | }
15 |
--------------------------------------------------------------------------------
/typespec/models/ContainerConfig.tsp:
--------------------------------------------------------------------------------
1 | import "./ContainerLayer.tsp";
2 |
3 | @doc("Configuration details for a container.")
4 | @example(#{
5 | cmd: #["echo", "hello"],
6 | entrypoint: #["/bin/sh"],
7 | env: #["FOO=bar"],
8 | layers: #[
9 | #{
10 | gzipDigest: "sha256:1234567890abcdef",
11 | gzipSize: "1234",
12 | location: "https://seqera.io/layer.tar.gz",
13 | skipHashing: false,
14 | tarDigest: "sha256:abcdef1234567890"
15 | }
16 | ],
17 | workingDir: "/app"
18 | })
19 | model ContainerConfig {
20 | @doc("The launch command to be used by the Wave container, e.g., `['echo', 'Hello world']` (optional).")
21 | cmd: string[];
22 | @doc("The container entrypoint command, e.g., `['/bin/bash']`.")
23 | entrypoint: string[];
24 | @doc("The environment variables to be defined in the Wave container, e.g., `['FOO=one','BAR=two']` (optional).")
25 | env: string[];
26 | layers: ContainerLayer[];
27 | @doc("The work directory to be used in the Wave container, e.g., `/some/work/dir` (optional).")
28 | workingDir: string;
29 | }
30 |
--------------------------------------------------------------------------------
/typespec/models/ContainerInspectConfig.tsp:
--------------------------------------------------------------------------------
1 | import "./RootFS.tsp";
2 |
3 | @doc("Configuration details of a container.")
4 | @example(#{
5 | architecture: "linux/amd64",
6 | config: #{
7 | attachStdin: false,
8 | attachStdout: true,
9 | attachStderr: true,
10 | tty: false,
11 | env: #["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
12 | cmd: #["sh"],
13 | image: "alpine:latest"
14 | },
15 | container: "docker.io/alpine:latest",
16 | created: "2021-06-10T15:00:00.000000000Z",
17 | rootfs: #{
18 | diff_ids: #["sha256:1234567890abcdef"],
19 | type: "layers"
20 | }
21 | })
22 | model ContainerInspectConfig {
23 | architecture: string;
24 | config: {
25 | attachStdin: boolean;
26 | attachStdout: boolean;
27 | attachStderr: boolean;
28 | tty: boolean;
29 | env: string[];
30 | cmd: string[];
31 | image: string;
32 | };
33 | container: string;
34 | created: string;
35 | rootfs: RootFS;
36 | }
37 |
--------------------------------------------------------------------------------
/typespec/models/ContainerInspectRequest.tsp:
--------------------------------------------------------------------------------
1 | @doc("Request payload for inspecting a container.")
2 | @example(#{
3 | containerImage: "docker.io/alpine:latest",
4 | towerAccessToken: "1234567890abcdef",
5 | towerEndpoint: "https://api.cloud.seqera.io",
6 | towerWorkspaceId: 1234567890
7 | })
8 | model ContainerInspectRequest {
9 | @doc("Name of the container to be inpected, e.g., `docker.io/library/ubuntu:latest`")
10 | containerImage: string;
11 | @doc("Access token of the user account granting the access to the Seqera Platform service specified via `towerEndpoint` (optional). ")
12 | towerAccessToken: string;
13 | @doc("Seqera Platform service endpoint from where container registry credentials are retrieved (optional). Default `https://api.cloud.seqera.io`. ")
14 | towerEndpoint: string;
15 | @doc("ID of the Seqera Platform workspace from where the container registry credentials are retrieved (optional). When omitted the personal workspace is used.")
16 | towerWorkspaceId: int64;
17 | }
18 |
--------------------------------------------------------------------------------
/typespec/models/ContainerLayer.tsp:
--------------------------------------------------------------------------------
1 | @doc("Represents a layer in a container image.")
2 | @example(#{
3 | gzipDigest: "sha256:1234567890abcdef",
4 | gzipSize: "123456",
5 | location: "https://example.com/image.tar.gz",
6 | skipHashing: false,
7 | tarDigest: "sha256:abcdef1234567890"
8 | })
9 | model ContainerLayer {
10 | @doc("The SHA256 checksum of the provided layer tar gzip file, e.g., `sha256:a7c724b02...`.")
11 | gzipDigest: string;
12 | @doc("The size in bytes of the the provided layer tar gzip file.")
13 | gzipSize: string;
14 | @doc("Specifies a container image layer stored as a tar.gz file (optional). Either a HTTP URL to the file or a base64 encoded string prefixed with `data:`.")
15 | location: string;
16 | @doc("If true, the layer tar file will not be hashed.")
17 | skipHashing: boolean;
18 | @doc("The SHA256checksum of the provided tar file, e.g., `sha256:a7c724b02...`.")
19 | tarDigest: string;
20 | }
21 |
--------------------------------------------------------------------------------
/typespec/models/ContainerMirrorResponse.tsp:
--------------------------------------------------------------------------------
1 | import "./ContainerPlatform.tsp";
2 | import "./Status.tsp";
3 |
4 | @doc("Response payload for container mirroring.")
5 | @example(#{
6 | mirrorId: "6c084f2e43f86a78_1",
7 | digest: "sha256:1234567890abcdef",
8 | sourceImage: "docker.io/alpine:latest",
9 | targetImage: "docker.io/alpine:latest",
10 | platform: #{
11 | os: "LINUX",
12 | arch: "AMD64",
13 | variant: "v1"
14 | },
15 | creationTime: "2024-04-09T20:31:35.355423Z",
16 | status: Status.COMPLETED,
17 | duration: "123.914989000",
18 | exitCode: 0,
19 | logs: "Successfully mirrored image."
20 | })
21 | model ContainerMirrorResponse {
22 | mirrorId: string;
23 | digest: string;
24 | sourceImage: string;
25 | targetImage: string;
26 | platform: ContainerPlatform;
27 | creationTime: string;
28 | status: Status;
29 | duration: string;
30 | exitCode: int32;
31 | logs: string;
32 | }
33 |
--------------------------------------------------------------------------------
/typespec/models/ContainerPlatform.tsp:
--------------------------------------------------------------------------------
1 | @doc("Represents os platform of a container.")
2 | @example(#{
3 | os: "linux",
4 | arch: "amd64",
5 | variant: "v1"
6 | })
7 | model ContainerPlatform {
8 | os: string;
9 | arch: string;
10 | variant?: string;
11 | }
12 |
13 | enum Architecture {
14 | ARM64,
15 | AARCH64,
16 | AMD64,
17 | X86_64,
18 | X86_64_ALT,
19 | ARM
20 | }
21 |
22 | enum OS {
23 | LINUX,
24 | WINDOWS,
25 | MACOS
26 | }
27 |
--------------------------------------------------------------------------------
/typespec/models/ContainerResponse.tsp:
--------------------------------------------------------------------------------
1 | import "./ContainerStatus.tsp";
2 |
3 | @doc("Response payload for container token creation.")
4 | @example(#{
5 | containerToken:"732b73aa17c8",
6 | targetImage:"wave.seqera.io/wt/732b73aa17c8/build/dev:salmon_bwa--5e49881e6ad74121",
7 | expiration:"2024-04-09T21:19:01.715321Z",
8 | buildId:"5e49881e6ad74121_1",
9 | cached:false,
10 | freeze:false,
11 | mirror:false,
12 | requestId:"5e49881e6ad74121",
13 | scanId:"5e49881e6ad74121",
14 | containerImage:"docker.io/build/dev:salmon_bwa--5e49881e6ad74121",
15 | status:ContainerStatus.PENDING
16 | })
17 | model ContainerResponse {
18 | @doc("Unique identifier for the build.")
19 | buildId: string;
20 | @doc("Indicates if the build is cached.")
21 | cached: boolean;
22 | @doc("Container image to be used.")
23 | containerImage: string;
24 | @doc("Token to access the container.")
25 | containerToken: string;
26 | @doc("The expiration timestamp of the Wave container using ISO-8601 format.")
27 | expiration: string;
28 | @doc("Indicates if the build is pushed to user container registry.")
29 | freeze: boolean;
30 | @doc("Indicates if its a mirror request.")
31 | mirror: boolean;
32 | @doc("Unique identifier for the request.")
33 | requestId: string;
34 | @doc("Unique identifier for the scan.")
35 | scanId: string;
36 | @doc("Status of the container build.")
37 | status: ContainerStatus;
38 | @doc("The Wave container image name")
39 | targetImage: string;
40 | }
41 |
--------------------------------------------------------------------------------
/typespec/models/ContainerStatus.tsp:
--------------------------------------------------------------------------------
1 | enum ContainerStatus {
2 | PENDING,
3 | BUILDING,
4 | SCANNING,
5 | DONE
6 | }
7 |
--------------------------------------------------------------------------------
/typespec/models/ContainerStatusResponse.tsp:
--------------------------------------------------------------------------------
1 | import "./ContainerStatus.tsp";
2 |
3 | @doc("Response payload for container status.")
4 | @example(#{
5 | id:"6c084f2e43f86a78",
6 | buildId:"6c084f2e43f86a78_1",
7 | status:ContainerStatus.DONE,
8 | creationTime:"2024-04-09T20:31:35.355423Z",
9 | detailsUri:"https://wave.seqera.io/view/builds/6c084f2e43f86a78_1",
10 | duration:"123.914989000",
11 | succeeded:true,
12 | scanId:"6c084f2e43f86a78_1",
13 | })
14 | model ContainerStatusResponse {
15 | id: string;
16 | status: ContainerStatus;
17 | buildId: string;
18 | mirrorId?: string;
19 | scanId: string;
20 | vulnerabilities?: Record;
21 | succeeded: boolean;
22 | reason?: string;
23 | detailsUri: string;
24 | creationTime: string;
25 | duration: string;
26 | }
27 |
28 | model vulnerability {
29 | severity: string;
30 | count: int32
31 | }
32 |
--------------------------------------------------------------------------------
/typespec/models/Manifest.tsp:
--------------------------------------------------------------------------------
1 | import "./ManifestLayer.tsp";
2 |
3 | @doc("Manifest details of a container.")
4 | @example(#{
5 | config: #{
6 | digest: "sha256:6c084f2e43f86a78",
7 | mediaType: "application/vnd.docker.container.image.v1+json",
8 | size: 1234
9 | },
10 | layers: #[
11 | #{
12 | digest: "sha256:6c084f2e43f86a78",
13 | mediaType: "application/vnd.docker.container.image.v1+json",
14 | size: 1234
15 | }
16 | ],
17 | mediaType: "application/vnd.docker.container.image.v1+json",
18 | schemaVersion: 2
19 | })
20 | model Manifest {
21 | config: {
22 | digest: string;
23 | mediaType: string;
24 | size: int64;
25 | };
26 | layers: ManifestLayer[];
27 | mediaType: string;
28 | schemaVersion: int32;
29 | }
30 |
--------------------------------------------------------------------------------
/typespec/models/ManifestLayer.tsp:
--------------------------------------------------------------------------------
1 | @doc("Manifest layer details of a container.")
2 | @example(#{
3 | digest: "sha256:6c084f2e43f86a78",
4 | mediaType: "application/vnd.docker.container.image.v1+json",
5 | size: 1234
6 | })
7 | model ManifestLayer {
8 | digest: string;
9 | mediaType: string;
10 | size: int64;
11 | }
12 |
--------------------------------------------------------------------------------
/typespec/models/RootFS.tsp:
--------------------------------------------------------------------------------
1 | @doc("Details about the root filesystem of a container.")
2 | @example(#{
3 | diff_ids: #[
4 | "sha256:6c084f2e43f86a78",
5 | "sha256:6c084f2e43f86a78"
6 | ],
7 | type: "layers"
8 | })
9 | model RootFS {
10 | diff_ids: string[];
11 | type: string;
12 | }
13 |
--------------------------------------------------------------------------------
/typespec/models/ScanLevel.tsp:
--------------------------------------------------------------------------------
1 | enum ScanLevel {
2 | LOW,
3 | MEDIUM,
4 | HIGH,
5 | CRITICAL
6 | }
7 |
--------------------------------------------------------------------------------
/typespec/models/ScanMode.tsp:
--------------------------------------------------------------------------------
1 | enum ScanMode{
2 | none,
3 | async,
4 | required
5 | }
6 |
--------------------------------------------------------------------------------
/typespec/models/Status.tsp:
--------------------------------------------------------------------------------
1 | enum Status {
2 | PENDING,
3 | COMPLETED
4 | }
5 |
--------------------------------------------------------------------------------
/typespec/models/User.tsp:
--------------------------------------------------------------------------------
1 | @doc("Wave USer details")
2 | @example(#{
3 | id: 1,
4 | userName: "test",
5 | email: "test@seqera.io"
6 | })
7 | model User {
8 | id: int64;
9 | userName: string;
10 | email: string;
11 | }
12 |
--------------------------------------------------------------------------------
/typespec/models/ValidateRegistryCredsRequest.tsp:
--------------------------------------------------------------------------------
1 | @doc("request payload of validate credentials request")
2 | @example(#{
3 | password: "password",
4 | registry: "docker.io/wave",
5 | userName: "username"
6 | })
7 | model ValidateRegistryCredsRequest {
8 | password: string;
9 | registry: string;
10 | userName: string;
11 | }
12 |
--------------------------------------------------------------------------------
/typespec/models/Vulnerability.tsp:
--------------------------------------------------------------------------------
1 | @doc("Scan Vulnerability details")
2 | @example(#{
3 | fixedVersion: "1.0.0",
4 | id: "CVE-2021-1234",
5 | installedVersion: "0.9.0",
6 | pkgName: "test",
7 | primaryUrl: "https://test.com",
8 | severity: "high",
9 | title: "test"
10 | })
11 | model Vulnerability {
12 | fixedVersion: string;
13 | id: string;
14 | installedVersion: string;
15 | pkgName: string;
16 | primaryUrl: string;
17 | severity: string;
18 | title: string;
19 | }
20 |
--------------------------------------------------------------------------------
/typespec/models/WaveBuildRecord.tsp:
--------------------------------------------------------------------------------
1 | @doc("Wave container build details")
2 | model WaveBuildRecord {
3 | buildId: string;
4 | condaFile: string;
5 | digest: string;
6 | dockerFile: string;
7 | duration: int64;
8 | exitStatus: int32;
9 | format: "docker" | "sif";
10 | offsetId: string;
11 | platform: string;
12 | requestIp: string;
13 | scanId: string;
14 | startTime: string;
15 | succeeded: boolean;
16 | targetImage: string;
17 | userEmail: string;
18 | userId: int64;
19 | userName: string;
20 | }
21 |
--------------------------------------------------------------------------------
/typespec/models/WaveContainerRecord.tsp:
--------------------------------------------------------------------------------
1 | import "./User.tsp";
2 |
3 | @doc("Wave container details")
4 | model WaveContainerRecord {
5 | user: User;
6 | workspaceId: int64;
7 | containerImage?: string;
8 | containerFile?: string;
9 | containerConfig: ContainerConfig;
10 | condaFile?: string;
11 | platform?: string;
12 | towerEndpoint?: string;
13 | buildRepository?: string;
14 | cacheRepository?: string;
15 | fingerprint?: string;
16 | timestamp: string;
17 | zoneId?: string;
18 | ipAddress?: string;
19 | sourceImage?: string;
20 | sourceDigest?: string;
21 | waveImage?: string;
22 | waveDigest?: string;
23 | expiration: string;
24 | buildId?: string;
25 | buildNew?: boolean;
26 | freeze?: boolean;
27 | fusionVersion?: string;
28 | }
29 |
--------------------------------------------------------------------------------
/typespec/models/WaveScanRecord.tsp:
--------------------------------------------------------------------------------
1 | import "./Vulnerability.tsp";
2 |
3 | @doc("Response Payload for wave scan")
4 | model WaveScanRecord {
5 | buildId: string;
6 | duration: int64;
7 | containerImage: string;
8 | id: string;
9 | startTime: string;
10 | status: string;
11 | vulnerabilities: Vulnerability[];
12 | }
13 |
--------------------------------------------------------------------------------
/typespec/models/models.tsp:
--------------------------------------------------------------------------------
1 | import "./ContainerRequest.tsp";
2 | import "./ContainerResponse.tsp";
3 | import "./BuildStatusResponse.tsp";
4 | import "./ContainerInspectRequest.tsp";
5 | import "./ContainerInspectResponse.tsp";
6 | import "./WaveScanRecord.tsp";
7 | import "./WaveBuildRecord.tsp";
8 | import "./ValidateRegistryCredsRequest.tsp";
9 | import "./WaveContainerRecord.tsp";
10 | import "./ContainerMirrorResponse.tsp";
11 | import "./ContainerStatusResponse.tsp";
12 |
--------------------------------------------------------------------------------
/typespec/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wave",
3 | "version": "1.16.7",
4 | "type": "module",
5 | "dependencies": {
6 | "@typespec/compiler": "0.64.0",
7 | "@typespec/http": "0.64.0",
8 | "@typespec/openapi3": "0.64.0",
9 | "@typespec/rest": "0.64.0"
10 | },
11 | "private": true
12 | }
13 |
--------------------------------------------------------------------------------
/typespec/tag-and-push-openapi.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Wave, containers provisioning service
4 | # Copyright (c) 2023-2024, Seqera Labs
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU Affero General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 | #
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU Affero General Public License for more details.
15 | #
16 | # You should have received a copy of the GNU Affero General Public License
17 | # along with this program. If not, see .
18 | #
19 |
20 | # Tag and and push the the GitHub repo and Docker images
21 |
22 | set -e
23 | set -x
24 |
25 | SED=sed
26 | [[ $(uname) == Darwin ]] && SED=gsed
27 |
28 | RELEASE=${RELEASE:-$(git show -s --format='%s' | $SED -rn 's/.*\[(release)\].*/\1/p')}
29 |
30 | if [[ $RELEASE ]]; then
31 | TAG=v$(cat VERSION)
32 | version=$(cat VERSION)
33 |
34 | cd typespec
35 | sed -i "s/version: 0.0.0/version: $version/" "tsp-output/@typespec/openapi3/openapi.yaml"
36 |
37 | docker build -t 195996028523.dkr.ecr.eu-west-1.amazonaws.com/wave/openapi:$version .
38 | docker push 195996028523.dkr.ecr.eu-west-1.amazonaws.com/wave/openapi:$version
39 | fi
40 |
--------------------------------------------------------------------------------
/typespec/tspconfig.yaml:
--------------------------------------------------------------------------------
1 | emit:
2 | - "@typespec/openapi3"
3 | options:
4 | "@typespec/openapi3":
5 | output-file: openapi.yaml
6 |
--------------------------------------------------------------------------------