xdn/
├─ bin/ // scripts and binaries
├─ conf/ // configuration
├─ docs/
├─ eval/
├─ lib/ // evaluation scripts and results
├─ services/ // example stateful services
├─ src/
│ ├─ edu.umass.cs
│ │ ├─ reconfigurator/
│ │ │ ├─ ReconfigurableNode.java // the main() method for a Node
│ │ │ │ ...
├─ xdn-cli/ // xdn cli for developers / service owner
├─ xdn-dns/ // nameserver for xdn
├─ tests/
├─ build.xml
├─ LICENSE.txt
├─ README.md
We developed and tested XDN on rs630 machines in the CloudLab@UMassß, generally with the following system requirements:
- Linux 5.15+ with x86-64 architecture, or MacOS with arm64 architecture.
- libfuse3, or rsync.
- Java 21+
- docker 26+, accessible without
sudo
- Pull XDN source code:
git pull https://github.com/fadhilkurnia/xdn.git cd xdn - Compile XDN source code:
./bin/build_xdn_jar.sh - Compile XDN cli tool
xdnfor app developer:Make sure to add XDN's./bin/build_xdn_cli.shbindirectory into your$PATHso you can accessxdnfrom anywhere in your machine.
We have prepared a ready-to-use XDN provider at xdnapp.com.
To deploy a stateful service with this existing provider, simply follow the steps below.
-
Configure our
xdncli to use the provider, by setting the env variable.export XDN_CONTROL_PLANE=cp.xdnapp.com -
Deploy your stateful service.
xdn launch bookcatalog --image=fadhilkurnia/xdn-bookcatalog --state=/app/data/ --deterministic=true
Which will result in the following output, if success:
Launching tpcc-web service with the following configuration: docker image : fadhilkurnia/xdn-bookcatalog http port : 80 consistency : linearizability deterministic : true state dir : /app/data/ The service is successfully launched 🎉🚀 Access your service at the following permanent URL: > http://bookcatalog.xdnapp.com/ Retrieve the service's replica locations with this command: xdn service info bookcatalog Destroy the replicated service with this command: xdn service destroy bookcatalogNote: change
bookcatalogwith another name if there is already existing service with that name. -
Access your stateful service with the provided url in your browser. Alternatively, you can get the deployment info using the command below.
xdn service info bookcatalog
-
Once done, remove your service.
xdn service destroy bookcatalog
-
Start the control plane (i.e., Reconfigurator/RC) and the edge servers (i.e., ActiveReplica/AR), using the default configuration.
./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.local.properties start all
Which will start these 4 local servers:
- 1 Reconfigurator at localhost:3000.
- 3 ActiveReplicas at localhost:2000, localhost:2001, and localhost:2002.
-
Set
localhostas your control plane host.export XDN_CONTROL_PLANE=localhost -
With
xdncommand line, launch a containerized stateful service withbookcatalogas the name:xdn launch bookcatalog --image=fadhilkurnia/xdn-bookcatalog --state=/app/data/ --deterministic=true
Which will result in the following output, if success:
Launching tpcc-web service with the following configuration: docker image : bookcatalog http port : 80 consistency : linearizability deterministic : true state dir : /app/data/ The service is successfully launched 🎉🚀 Retrieve the service's replica locations with this command: xdn service info bookcatalog Destroy the replicated service with this command: xdn service destroy bookcatalogWe can also verify that the replicated services run in the background using
docker ps. -
Access the replicated services in the active replicas with curl. Note that we need to specify the service name (
bookcatalog) in the header withXDNas the key.# access from the first replica: curl -v http://localhost:2300/ -H "XDN: bookcatalog" # access from the second replica: curl -v http://localhost:2301/ -H "XDN: bookcatalog" # access from the third replica: curl -v http://localhost:2302/ -H "XDN: bookcatalog" -
(Optional) Update the local host file (
/etc/hosts), so we can access the web service viaxdn.iodomain:# /etc/hosts file 127.0.0.1 bookcatalog.ar0.xdn.io 127.0.0.1 bookcatalog.ar1.xdn.io 127.0.0.1 bookcatalog.ar2.xdn.ioThen you can access the replicated web service with those host, without XDN custom header:
curl -v http://bookcatalog.xdn.io:2300/ curl -v http://bookcatalog.xdn.io:2301/ curl -v http://bookcatalog.xdn.io:2301/
To stop xdn, we need to stop the Reconfigurator and ActiveReplicas and clean all the state:
sudo ./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.local.properties forceclear all sudo rm -rf /tmp/gigapaxos sudo rm -rf /tmp/xdn
Assuming we have 4 machines with the following IP address:
10.10.1.1for the first active replica.10.10.1.2for the second active replica.10.10.1.3for the third active replica.10.10.1.5for the reconfiguration.
as what we have specified in the ./conf/gigapaxos.cloudlab.properties.
If the machines have different IP address, you need to modify the config file.
-
Do all the instructions in the Getting Started, for each of the machine.
-
Start the server in each machine.
# at machine 10.10.1.1:
./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.cloudlab.properties start AR1
# at machine 10.10.1.2:
./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.cloudlab.properties start AR2
# at machine 10.10.1.3:
./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.cloudlab.properties start AR3
# at machine 10.10.1.5:
./bin/gpServer.sh -DgigapaxosConfig=conf/gigapaxos.cloudlab.properties start RC1
Assuming we have 5 machines with the following role and IP address:
10.10.1.1for the first active replica.10.10.1.2for the second active replica.10.10.1.3for the third active replica.10.10.1.4for the reconfiguration.10.10.1.5for the driver machine where we run all the command.
We are using the xdnd binary for most of the command here.
- Initialize the driver machine:
./bin/xdnd init-driver. - Initialize all the remote machines:
./bin/xdnd dist-init -config=gigapaxos.properties -ssh-key=/ssh/key -username=user - Optionally, initialize observability in all machines:
./bin/xdnd dist-init-observability -config=gigapaxos.properties -ssh-key=/ssh/key -username=user - Start xdn instances in all machines:
./bin/xdnd start-all -config=gigapaxos.properties -ssh-key=/ssh/key -username=user