Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
950a55f
wip set up Apache Pekko migration
Oct 9, 2025
88abcc7
fix scalafmt
Oct 9, 2025
f830ed5
Merge branch 'master' into pekko-migration
Oct 10, 2025
583c265
fix logging configuration
Oct 10, 2025
1771c13
fix dependencies
Oct 10, 2025
70cbfef
more updates
Oct 10, 2025
9752bbc
fix config overrides
Oct 10, 2025
bd929aa
fix s3 config
Oct 11, 2025
32ba187
upgrade scalatest to handle pekko incompatibility
Oct 11, 2025
e7d487b
attempt exclude grpc netty shaded
Oct 11, 2025
de27040
fix networking'
Oct 11, 2025
0709c3b
revert change
Oct 14, 2025
cc7844b
upgrade etcd java to latest version
Oct 14, 2025
af1670d
attempt to constrain all grpc dependencies to consistent version
Oct 14, 2025
c147190
merge in etcd java upgrade and pin grpc versions
Oct 14, 2025
8fd16f0
Merge branch 'master' into pekko-migration
Oct 15, 2025
5c50d70
upgrade kafka client
Oct 15, 2025
acfa1b5
add controller debug
Oct 15, 2025
8ce47ba
more debug
Oct 15, 2025
8c5e209
fix controller / scheduler init
Oct 15, 2025
3f96cba
fix scheduler deploy config
Oct 15, 2025
62a21e3
add scheduler debug
Oct 15, 2025
dab269d
fix scheduler config
Oct 15, 2025
67fdb18
upgrade embedded kafka for standalone
Oct 15, 2025
34435a3
more kafka and test updates
Oct 15, 2025
800ba1e
upgrade kafka
Oct 15, 2025
0253178
upgrade kafka
Oct 16, 2025
df48e28
upgrade grpc and netty
Oct 16, 2025
4f6e208
remove all remaining akka references
Oct 16, 2025
963dda7
fix test race condition
Oct 17, 2025
b0f838b
fix flaky scheduler tests
Oct 17, 2025
f73545d
more vulns
Oct 17, 2025
c8b5a00
update ansible
Oct 17, 2025
7aae91e
update readme
Oct 17, 2025
2c34062
fix unit test
Oct 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/2-system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ on:
env:
# openwhisk env
TEST_SUITE: System
ANSIBLE_CMD: "ansible-playbook -i environments/local -e docker_image_prefix=testing -e container_pool_akka_client=false"
ANSIBLE_CMD: "ansible-playbook -i environments/local -e docker_image_prefix=testing -e container_pool_pekko_client=false"
GRADLE_PROJS_SKIP: ""

## secrets
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ Learn more at [http://openwhisk.apache.org](http://openwhisk.apache.org).
* [OpenWhisk Community and Support](#openwhisk-community-and-support)
* [Project Repository Structure](#project-repository-structure)

### Notice of Breaking Upgrade 10/17/2025

Apache Openwhisk has migrated to the Apache Pekko framework. The master branch as of 10/17/2025 uses Apache Pekko. This change results in a breaking change such that you must re-deploy new clusters and cutover traffic to the new cluster. All other changes should be transient to you other than instead of using Akka configuration overrides in your deployments, you would now need to update those to use the Pekko equivalent. A 3.x release branch will eventually follow this
change.

### Quick Start

The easiest way to start using OpenWhisk is to install the "Standalone" OpenWhisk stack.
Expand Down
4 changes: 2 additions & 2 deletions ansible/controller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
# configuration settings. (Plugins are found in the
# 'roles/controller/tasks' directory for now.)
controller_plugins:
# Join an akka cluster rather than running standalone akka
- "join_akka_cluster"
# Join an pekko cluster rather than running standalone pekko
- "join_pekko_cluster"

roles:
- controller
2 changes: 1 addition & 1 deletion ansible/environments/local/group_vars/all
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ kafka_topics_invoker_retentionMS: 300000

env_hosts_dir: "{{ playbook_dir }}/environments/local"

container_pool_akka_client: true
container_pool_pekko_client: true
runtimes_enable_concurrency: true
limit_action_concurrency_max: 500
namespace_default_limit_action_concurrency_max: 500
6 changes: 3 additions & 3 deletions ansible/group_vars/all
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ controller:
timeoutFactor: "{{ controller_timeout_factor | default(2) }}"
timeoutAddon: "{{ controller_timeout_addon | default('1 m') }}"
instances: "{{ groups['controllers'] | length }}"
akka:
pekko:
provider: cluster
cluster:
basePort: 8000
Expand Down Expand Up @@ -517,10 +517,10 @@ scheduler:
instances: "{{ groups['schedulers'] | length }}"
username: "{{ scheduler_username | default('scheduler.user') }}"
password: "{{ scheduler_password | default('scheduler.pass') }}"
akka:
pekko:
provider: cluster
cluster:
basePort: 25520
basePort: 17355
host: "{{ groups['schedulers'] | map('extract', hostvars, 'ansible_host') | list }}"
bindPort: 3551
# at this moment all schedulers are seed nodes
Expand Down
48 changes: 36 additions & 12 deletions ansible/roles/controller/tasks/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -443,18 +443,42 @@
>> /logs/{{ controller_name }}_logs.log 2>&1"

- name: wait until the Controller in this host is up and running
uri:
url:
"{{controller.protocol}}://{{ansible_host}}:{{controller_port}}/ping"
validate_certs: "no"
client_key:
"{{ controller.confdir }}/{{ controller_name }}/{{ controller.ssl.key }}"
client_cert:
"{{ controller.confdir }}/{{ controller_name }}/{{ controller.ssl.cert }}"
register: result
until: result.status == 200
retries: 12
delay: 10
block:
- name: ping controller health endpoint
uri:
url: "{{ controller.protocol }}://{{ ansible_host }}:{{ controller_port }}/ping"
validate_certs: no
client_key: "{{ controller.confdir }}/{{ controller_name }}/{{ controller.ssl.key }}"
client_cert: "{{ controller.confdir }}/{{ controller_name }}/{{ controller.ssl.cert }}"
return_content: yes
user: "{{ controller.username }}"
password: "{{ controller.password }}"
force_basic_auth: yes
register: result
until: result.status == 200
retries: 12
delay: 10
failed_when: result.status is defined and result.status not in [200]
rescue:
- name: dump controller docker logs
shell: |
docker logs {{ controller_name }} >/tmp/controller-docker.log 2>&1 || true
cat /tmp/controller-docker.log
register: controller_logs
failed_when: false
- name: output controller logs for debugging
debug:
var: controller_logs.stdout_lines
- name: dump controller file logs
shell: |
cat /var/tmp/wsklogs/{{ controller_name }}/{{ controller_name }}_logs.log
register: controller_file_logs
failed_when: false
- name: output controller file logs for debugging
debug:
var: controller_file_logs.stdout_lines
- fail:
msg: "Controller failed to start; logs emitted above"

- name: warm up activation path
uri:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,37 @@
---
#
# Controller 'plugin' that will add the items necessary to the controller
# environment to cause the controller to join a specified akka cluster
# environment to cause the controller to join a specified pekko cluster
#

- name: add akka port to ports_to_expose
- name: add pekko port to ports_to_expose
set_fact:
ports_to_expose: >-
{{ ports_to_expose }} +
[ "{{ (controller.akka.cluster.basePort + (controller_index | int)) }}:"
+ "{{ controller.akka.cluster.bindPort }}" ]
[ "{{ (controller.pekko.cluster.basePort + (controller_index | int)) }}:"
+ "{{ controller.pekko.cluster.bindPort }}" ]

- name: add seed nodes to controller environment
set_fact:
env: >-
{{ env | combine({
'CONFIG_akka_cluster_seedNodes_' ~ seedNode.0:
'akka://controller-actor-system@'~seedNode.1~':'~(controller.akka.cluster.basePort+seedNode.0)
'CONFIG_pekko_cluster_seedNodes_' ~ seedNode.0:
'pekko://controller-actor-system@'~seedNode.1~':'~(controller.pekko.cluster.basePort+seedNode.0)
}) }}
with_indexed_items: "{{ controller.akka.cluster.seedNodes }}"
with_indexed_items: "{{ controller.pekko.cluster.seedNodes }}"
loop_control:
loop_var: seedNode

- name: Add akka environment to controller environment
- name: Add pekko environment to controller environment
vars:
akka_env:
"CONFIG_akka_actor_provider": "{{ controller.akka.provider }}"
"CONFIG_akka_remote_artery_canonical_hostname":
"{{ controller.akka.cluster.host[(controller_index | int)] }}"
"CONFIG_akka_remote_artery_canonical_port":
"{{ controller.akka.cluster.basePort + (controller_index | int) }}"
"CONFIG_akka_remote_artery_bind_port":
"{{ controller.akka.cluster.bindPort }}"
pekko_env:
"CONFIG_pekko_actor_provider": "{{ controller.pekko.provider }}"
"CONFIG_pekko_remote_artery_canonical_hostname":
"{{ controller.pekko.cluster.host[(controller_index | int)] }}"
"CONFIG_pekko_remote_artery_canonical_port":
"{{ controller.pekko.cluster.basePort + (controller_index | int) }}"
"CONFIG_pekko_remote_artery_bind_hostname": "0.0.0.0"
"CONFIG_pekko_remote_artery_bind_port":
"{{ controller.pekko.cluster.bindPort }}"
set_fact:
env: "{{ env | combine(akka_env) }}"
env: "{{ env | combine(pekko_env) }}"
38 changes: 28 additions & 10 deletions ansible/roles/invoker/tasks/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@
"CONFIG_whisk_namespaceDefaultLimit_concurrencyLimit_max": "{{ namespace_default_limit_action_concurrency_max | default() }}"
"CONFIG_whisk_activation_payload_max": "{{ limit_activation_payload | default() }}"
"CONFIG_whisk_transactions_header": "{{ transactions.header }}"
"CONFIG_whisk_containerPool_akkaClient": "{{ container_pool_akka_client | default('false') | lower }}"
"CONFIG_whisk_containerPool_pekkoClient": "{{ container_pool_pekko_client | default('false') | lower }}"
"CONFIG_whisk_containerFactory_containerArgs_extraEnvVars_0": "__OW_ALLOW_CONCURRENT={{ runtimes_enable_concurrency | default('false') }}"
"CONFIG_whisk_invoker_protocol": "{{ invoker.protocol }}"
"CONFIG_whisk_invoker_https_keystorePath": "/conf/{{ invoker.ssl.keystore.name }}"
Expand Down Expand Up @@ -447,13 +447,31 @@
when: not lean

- name: wait until Invoker is up and running
uri:
url: "{{ invoker.protocol }}://{{ ansible_host }}:{{ invoker.port + (invoker_index | int) }}/ping"
validate_certs: "no"
client_key: "{{ invoker.confdir }}/{{ invoker_name }}/{{ invoker.ssl.key }}"
client_cert: "{{ invoker.confdir }}/{{ invoker_name }}/{{ invoker.ssl.cert }}"
register: result
until: result.status == 200
retries: 12
delay: 5
block:
- uri:
url: "{{ invoker.protocol }}://{{ ansible_host }}:{{ invoker.port + (invoker_index | int) }}/ping"
validate_certs: "no"
client_key: "{{ invoker.confdir }}/{{ invoker_name }}/{{ invoker.ssl.key }}"
client_cert: "{{ invoker.confdir }}/{{ invoker_name }}/{{ invoker.ssl.cert }}"
register: result
until: result.status == 200
retries: 12
delay: 5
rescue:
- name: dump invoker docker logs for debugging
shell: "docker logs {{ invoker_name }}"
register: invoker_logs
failed_when: false
- name: output invoker docker logs for debugging
debug:
var: invoker_logs.stdout_lines
- name: dump invoker file logs from /var/tmp/wsklogs
shell: "cat /var/tmp/wsklogs/{{ invoker_name }}/{{ invoker_name }}_logs.log"
register: invoker_file_logs
failed_when: false
- name: output invoker file logs for debugging
debug:
var: invoker_file_logs.stdout_lines
- fail:
msg: "Invoker failed to start; logs emitted above"
when: not lean
40 changes: 31 additions & 9 deletions ansible/roles/schedulers/tasks/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@

"WHISK_SCHEDULER_ENDPOINTS_HOST": "{{ ansible_host }}"
"WHISK_SCHEDULER_ENDPOINTS_RPCPORT": "{{ scheduler.grpc.basePort + (scheduler_index | int)}}"
"WHISK_SCHEDULER_ENDPOINTS_AKKAPORT": "{{ scheduler.akka.cluster.basePort + (scheduler_index | int) }}"
"WHISK_SCHEDULER_ENDPOINTS_PEKKOPORT": "{{ scheduler.pekko.cluster.basePort + (scheduler_index | int) }}"
"CONFIG_whisk_scheduler_protocol": "{{ scheduler.protocol }}"
"CONFIG_whisk_scheduler_maxPeek": "{{ scheduler.maxPeek }}"
"CONFIG_whisk_scheduler_dataManagementService_retryInterval": "{{ scheduler.dataManagementService.retryInterval }}"
Expand Down Expand Up @@ -348,14 +348,36 @@
>> /logs/{{ scheduler_name }}_logs.log 2>&1"

- name: wait until the Scheduler in this host is up and running
uri:
url:
"{{scheduler.protocol}}://{{ansible_host}}:{{scheduler_port}}/ping"
validate_certs: "no"
register: result
until: result.status == 200
retries: 12
delay: 5
block:
- name: ping scheduler health endpoint
uri:
url:
"{{scheduler.protocol}}://{{ansible_host}}:{{scheduler_port}}/ping"
validate_certs: "no"
register: result
until: result.status == 200
retries: 12
delay: 5
rescue:
- name: dump scheduler docker logs
shell: |
docker logs {{ scheduler_name }} >/tmp/scheduler-docker.log 2>&1 || true
cat /tmp/scheduler-docker.log
register: scheduler_logs
failed_when: false
- name: output scheduler logs for debugging
debug:
var: scheduler_logs.stdout_lines
- name: dump scheduler file logs
shell: |
cat /var/tmp/wsklogs/{{ scheduler_name }}/{{ scheduler_name }}_logs.log
register: scheduler_file_logs
failed_when: false
- name: output scheduler file logs for debugging
debug:
var: scheduler_file_logs.stdout_lines
- fail:
msg: "Scheduler failed to start; logs emitted above"

- name: create scheduler jmx.yml
template:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,37 @@
---
#
# Scheduler 'plugin' that will add the items necessary to the scheduler
# environment to cause the scheduler to join a specified akka cluster
# environment to cause the scheduler to join a specified pekko cluster
#

- name: add akka port to ports_to_expose
- name: add pekko port to ports_to_expose
set_fact:
ports_to_expose: >-
{{ ports_to_expose }} +
[ "{{ (scheduler.akka.cluster.basePort + (scheduler_index | int)) }}:"
+ "{{ scheduler.akka.cluster.bindPort }}" ]
[ "{{ (scheduler.pekko.cluster.basePort + (scheduler_index | int)) }}:"
+ "{{ scheduler.pekko.cluster.bindPort }}" ]

- name: add seed nodes to scheduler environment
set_fact:
env: >-
{{ env | combine({
'CONFIG_akka_cluster_seedNodes_' ~ seedNode.0:
'akka://scheduler-actor-system@'~seedNode.1~':'~(scheduler.akka.cluster.basePort+seedNode.0)
'CONFIG_pekko_cluster_seedNodes_' ~ seedNode.0:
'pekko://scheduler-actor-system@'~seedNode.1~':'~(scheduler.pekko.cluster.basePort+seedNode.0)
}) }}
with_indexed_items: "{{ scheduler.akka.cluster.seedNodes }}"
with_indexed_items: "{{ scheduler.pekko.cluster.seedNodes }}"
loop_control:
loop_var: seedNode

- name: Add akka environment to scheduler environment
- name: Add pekko environment to scheduler environment
vars:
akka_env:
"CONFIG_akka_actor_provider": "{{ scheduler.akka.provider }}"
"CONFIG_akka_remote_artery_canonical_hostname":
"{{ scheduler.akka.cluster.host[(scheduler_index | int)] }}"
"CONFIG_akka_remote_artery_canonical_port":
"{{ scheduler.akka.cluster.basePort + (scheduler_index | int) }}"
"CONFIG_akka_remote_artery_bind_port":
"{{ scheduler.akka.cluster.bindPort }}"
pekko_env:
"CONFIG_pekko_actor_provider": "{{ scheduler.pekko.provider }}"
"CONFIG_pekko_remote_artery_canonical_hostname":
"{{ scheduler.pekko.cluster.host[(scheduler_index | int)] }}"
"CONFIG_pekko_remote_artery_canonical_port":
"{{ scheduler.pekko.cluster.basePort + (scheduler_index | int) }}"
"CONFIG_pekko_remote_artery_bind_hostname": "0.0.0.0"
"CONFIG_pekko_remote_artery_bind_port":
"{{ scheduler.pekko.cluster.bindPort }}"
set_fact:
env: "{{ env | combine(akka_env) }}"
env: "{{ env | combine(pekko_env) }}"
4 changes: 2 additions & 2 deletions ansible/scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
# configuration settings. (Plugins are found in the
# 'roles/controller/tasks' directory for now.)
scheduler_plugins:
# Join an akka cluster rather than running standalone akka
- "join_akka_cluster"
# Join an pekko cluster rather than running standalone pekko
- "join_pekko_cluster"

serial: '1'
roles:
Expand Down
35 changes: 18 additions & 17 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,27 @@ subprojects {
version '1.0.1-SNAPSHOT'

pluginManager.withPlugin('scala') {
// Constraint all transitive akka-* dependencies to the one we want to use to avoid issues.
// List generated via
// ./gradlew :test:dependencies | grep -o 'akka-.*_' | cut -c 6- | rev | cut -c 2- | rev | sort -u
// Constraint all transitive pekko-* dependencies to the one we want to use to avoid issues.
def cons = project.getDependencies().getConstraints()
def akka = ['akka-actor', 'akka-cluster', 'akka-cluster-metrics', 'akka-cluster-tools', 'akka-coordination',
'akka-discovery', 'discovery-kubernetes-api', 'discovery-marathon-api', 'akka-distributed-data','grpc-runtime','akka-protobuf', 'akka-remote', 'akka-slf4j',
'akka-stream', 'akka-stream-testkit', 'akka-testkit', 'akka-persistence', 'akka-cluster-sharding','akka-protobuf-v3','akka-pki','akka-parsing','akka-management-cluster-bootstrap','akka-management',
'akka-kryo-serialization']
def akkaHttp = ['akka-http', 'akka-http-core', 'akka-http-spray-json', 'akka-http-testkit', 'akka-http-xml',
'akka-parsing', 'akka-http2-support']
def akkaKafka = ['akka-stream-kafka-testkit','akka-stream-kafka','akka-stream-alpakka-s3','akka-stream-alpakka-file']

akka.forEach {
cons.add('implementation', "com.typesafe.akka:${it}_${gradle.scala.depVersion}:${gradle.akka.version}")
def pekko = ['pekko-actor', 'pekko-actor-typed', 'pekko-cluster', 'pekko-cluster-metrics', 'pekko-cluster-tools', 'pekko-coordination',
'pekko-discovery', 'discovery-kubernetes-api', 'discovery-marathon-api', 'pekko-distributed-data','grpc-runtime','pekko-protobuf', 'pekko-remote', 'pekko-slf4j',
'pekko-stream', 'pekko-stream-testkit', 'pekko-testkit', 'pekko-persistence', 'pekko-cluster-sharding','pekko-protobuf-v3','pekko-pki','pekko-serialization-jackson']
def pekkoHttp = ['pekko-http', 'pekko-http-core', 'pekko-http-spray-json', 'pekko-http-testkit', 'pekko-http-xml',
'pekko-http2-support']
def pekkoKafka = ['pekko-stream-kafka-testkit','pekko-connectors-kafka','pekko-connectors-s3','pekko-connectors-file']
def pekkoManagement = ['pekko-management-cluster-bootstrap','pekko-management','pekko-discovery-kubernetes-api','pekko-discovery-marathon-api']

pekko.forEach {
cons.add('implementation', "org.apache.pekko:${it}_${gradle.scala.depVersion}:${gradle.pekko.version}")
}
akkaHttp.forEach {
cons.add('implementation', "com.typesafe.akka:${it}_${gradle.scala.depVersion}:${gradle.akka_http.version}")
pekkoHttp.forEach {
cons.add('implementation', "org.apache.pekko:${it}_${gradle.scala.depVersion}:${gradle.pekko_http.version}")
}
akkaKafka.forEach{
cons.add('implementation', "com.typesafe.akka:${it}_${gradle.scala.depVersion}:${gradle.akka_kafka.version}")
pekkoKafka.forEach{
cons.add('implementation', "org.apache.pekko:${it}_${gradle.scala.depVersion}:${gradle.pekko_kafka.version}")
}
pekkoManagement.forEach{
cons.add('implementation', "org.apache.pekko:${it}_${gradle.scala.depVersion}:${gradle.pekko_management.version}")
}
}

Expand Down
Loading
Loading