Skip to content

Commit

Permalink
Merge branch 'master' into add-executors-metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
munishchouhan authored Dec 2, 2024
2 parents 901a805 + 1e2ed20 commit 21ba7bd
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 32 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/seqera_docs_changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Push changelog to Seqera Docs
on:
release:
types: [published]
workflow_dispatch:
inputs:
release_name:
description: 'Release version (e.g. 1.0.0)'
required: true
release_body:
description: 'Release changelog content'
required: true

jobs:
update-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Clone seqeralabs/docs
run: |
git clone https://github.com/seqeralabs/docs.git seqeralabs-docs
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Create changelog file
run: |
mkdir -p seqeralabs-docs/changelog/wave
cat << EOF > seqeralabs-docs/changelog/wave/${{ github.event.release.name || inputs.release_name }}.mdx
---
title: Wave ${{ github.event.release.name || inputs.release_name }}
date: $(date +%Y-%m-%d)
tags: [wave]
---
${{ github.event.release.body || inputs.release_body }}
EOF
- uses: actions/create-github-app-token@v1
id: generate-token
with:
app-id: ${{ secrets.DOCS_BOT_APP_ID }}
private-key: ${{ secrets.DOCS_BOT_APP_PRIVATE_KEY }}
owner: seqeralabs
repositories: docs

- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
token: ${{ steps.generate-token.outputs.token }}
branch-token: ${{ steps.generate-token.outputs.token }}
path: seqeralabs-docs
commit-message: "Changelog: Wave ${{ github.event.release.name || inputs.release_name }}"
title: "Changelog: Wave ${{ github.event.release.name || inputs.release_name }}"
body: |
This PR adds the changelog for Wave ${{ github.event.release.name || inputs.release_name }} to the Seqera documentation.
This is an automated PR created from the Wave repository.
branch: changelog-wave-${{ github.event.release.name || inputs.release_name }}
base: master
delete-branch: true
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ deployment-url.txt
tsp-output/
node_modules/
package-lock.json

# Seqera Docs clone
seqeralabs-docs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ java {

dependencies {
implementation 'org.slf4j:slf4j-api:2.0.16'
implementation 'org.slf4j:jul-to-slf4j:2.0.16'
implementation 'org.slf4j:slf4j-jdk-platform-logging:2.0.16'

testImplementation 'ch.qos.logback:logback-core:1.5.12'
testImplementation 'ch.qos.logback:logback-classic:1.5.12'
Expand Down
11 changes: 10 additions & 1 deletion src/main/groovy/io/seqera/wave/ErrorHandler.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpResponseFactory
import io.micronaut.http.HttpStatus
import io.micronaut.http.exceptions.HttpStatusException
import io.micronaut.security.authentication.AuthorizationException
import io.seqera.wave.exception.BuildTimeoutException
import io.seqera.wave.exception.DockerRegistryException
Expand Down Expand Up @@ -55,8 +56,9 @@ class ErrorHandler {
def <T> HttpResponse<T> handle(HttpRequest httpRequest, Throwable t, Mapper<T> responseFactory) {
final errId = LongRndKey.rndHex()
final request = httpRequest?.toString()
final knownException = t instanceof WaveException || t instanceof HttpStatusException
def msg = t.message
if( t instanceof WaveException && msg ) {
if( knownException && msg ) {
// the the error cause
if( t.cause ) msg += " - Cause: ${t.cause.message ?: t.cause}".toString()
// render the message for logging
Expand All @@ -81,6 +83,13 @@ class ErrorHandler {
log.error(render, t)
}

if( t instanceof HttpStatusException ) {
final body = (t.body.isPresent() ? t.body.get() : t.message) as T
return HttpResponse
.status(t.status)
.body(body)
}

if( t instanceof RegistryForwardException ) {
// report this error as it has been returned by the target registry
return HttpResponse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class ContainerCoordinates implements ContainerPath {
static ContainerCoordinates parse(String path) {
if( !path )
throw new IllegalArgumentException("Container image name is not provided")

if( path.contains(' ') )
throw new IllegalArgumentException("Invalid container name - offending image: '$path'")
final scheme = StringUtils.getUrlProtocol(path)
if( scheme ) {
if( scheme!='oras') throw new IllegalArgumentException("Invalid container scheme: '$scheme' - offending image: '$path'")
Expand Down
10 changes: 10 additions & 0 deletions src/main/groovy/io/seqera/wave/service/job/JobManager.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ class JobManager {
queue.addConsumer((job)-> processJob(job))
}

/**
* Process a job entry aorrding the state modelled by the {@link JobSpec} object.
*
* @param jobSpec
* A {@link JobSpec} object representing the job to be processed
* @return
* {@code true} to signal the process has been processed successfully and it should
* be removed from the underlying queue, or {@code false} if the job execution has
* not yet completed.
*/
protected boolean processJob(JobSpec jobSpec) {
try {
return processJob0(jobSpec)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,14 @@ class ValidationServiceImpl implements ValidationService {
// check does not start with a protocol prefix
final prot = StringUtils.getUrlProtocol(name)
if( prot ) {
return "Invalid container repository name — offending value: $name"
return "Invalid container repository name — offending value: '$name'"
}

try {
ContainerCoordinates.parse(name)
}
catch (IllegalArgumentException e) {
return "Invalid container image name — offending value: $name"
return "Invalid container image name — offending value: '$name'"
}
return null
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/groovy/io/seqera/wave/util/Retryable.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import java.util.function.Consumer
import java.util.function.Predicate

import dev.failsafe.Failsafe
import dev.failsafe.FailsafeException
import dev.failsafe.RetryPolicy
import dev.failsafe.RetryPolicyBuilder
import dev.failsafe.event.EventListener
Expand Down Expand Up @@ -137,7 +138,11 @@ class Retryable<R> {

R apply(CheckedSupplier<R> action) {
final policy = retryPolicy()
return Failsafe.with(policy).get(action)
try {
return Failsafe.with(policy).get(action)
} catch (FailsafeException e) {
throw e.cause
}
}

static <T> Retryable<T> of(Config config) {
Expand Down
18 changes: 1 addition & 17 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,11 @@ micronaut:
enabled: true
# http client configuration
# https://docs.micronaut.io/latest/guide/configurationreference.html#io.micronaut.http.client.DefaultHttpClientConfiguration
executors:
stream-executor:
type: FIXED
number-of-threads: 16
netty:
event-loops:
stream-pool:
executor: 'stream-executor'
http:
services:
stream-client:
read-timeout: '30s'
read-idle-timeout: '120s'
event-loop-group: 'stream-pool'
security:
enabled: true
intercept-url-map:
Expand Down Expand Up @@ -96,12 +87,5 @@ jackson:
logger:
levels:
io.seqera: "DEBUG"
io.micronaut.retry.intercept.RecoveryInterceptor: "OFF"
# ^^^^^^^^^^^^^^^^^^^^^
# Disable logs of `RecoveryInterceptor`, as they have been found to be noisy.
# Declarative `io.micronaut.http.client.annotation.@Client`s are annotated with `io.micronaut.retry.annotation@Recoverable`
# and throw an exception on every error response by default. `RecoveryInterceptor` ends up logging those exceptions
# even if they are handled and no actual recovery/fallback logic gets to take place.
# TODO remove once the project is updated to Micronaut 4.x, as @Client won't be annotated with @Recoverable anymore
# See https://github.com/micronaut-projects/micronaut-core/issues/3719; https://github.com/micronaut-projects/micronaut-core/pull/8235
com.github.benmanes.caffeine.cache.LocalAsyncCache: "ERROR"
...
Original file line number Diff line number Diff line change
Expand Up @@ -453,13 +453,13 @@ class ContainerControllerTest extends Specification {
controller.validateContainerRequest(new SubmitContainerTokenRequest(containerImage: 'http://docker.io/foo:latest'))
then:
err = thrown(BadRequestException)
err.message == 'Invalid container repository name — offending value: http://docker.io/foo:latest'
err.message == "Invalid container repository name — offending value: 'http://docker.io/foo:latest'"

when:
controller.validateContainerRequest(new SubmitContainerTokenRequest(containerImage: 'http:docker.io/foo:latest'))
then:
err = thrown(BadRequestException)
err.message == 'Invalid container image name — offending value: http:docker.io/foo:latest'
err.message == "Invalid container image name — offending value: 'http:docker.io/foo:latest'"

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,12 @@ class ValidationServiceTest extends Specification {
'quay.io:80/foo:latest' | null
'localhost:8000/foo:latest' | null
and:
'docker:quay.io/foo:latest' | 'Invalid container image name — offending value: docker:quay.io/foo:latest'
'http://quay.io/foo:latest' | 'Invalid container repository name — offending value: http://quay.io/foo:latest'
'http://quay.io/foo:latest' | 'Invalid container repository name — offending value: http://quay.io/foo:latest'
'docker:quay.io/foo:latest' | "Invalid container image name — offending value: 'docker:quay.io/foo:latest'"
'http://quay.io/foo:latest' | "Invalid container repository name — offending value: 'http://quay.io/foo:latest'"
'http://quay.io/foo:latest' | "Invalid container repository name — offending value: 'http://quay.io/foo:latest'"
'ubuntu: latest' | "Invalid container image name — offending value: 'ubuntu: latest'"
'ubuntu:latest ' | "Invalid container image name — offending value: 'ubuntu:latest '"
' ' | "Invalid container image name — offending value: ' '"
}

@Unroll
Expand Down
6 changes: 2 additions & 4 deletions src/test/groovy/io/seqera/wave/util/RetryableTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import spock.lang.Specification

import java.time.Duration

import dev.failsafe.FailsafeException
import groovy.util.logging.Slf4j

/**
*
* @author Paolo Di Tommaso <[email protected]>
Expand Down Expand Up @@ -65,8 +63,8 @@ class RetryableTest extends Specification {
when:
retryable.apply(()-> {throw new IOException("Oops failed!")})
then:
def e = thrown(FailsafeException)
e.cause instanceof IOException
def e = thrown(IOException)
e.message == 'Oops failed!'
}

def 'should validate config' () {
Expand Down

0 comments on commit 21ba7bd

Please sign in to comment.