Good news!, if you would like persistent data in your wasmedge application, simply follow the usage examples below.
The wasmedge-mysql API will accept valid secure HTTP requests. Whilst the primary use case is to allow Javascript developers to have persistence in their WasmEdge apps, there is nothing stopping you from storing and loading data (even for testing) using any software which is capable of making secure HTTP requests (i.e. Python, Curl, Ruby, PHP). Below, we only provide explicit code examples of using Curl and Javascript.
Store raw bytes and receive a UUID to access that data in the future
curl --location --request POST 'https://rpc.ssvm.secondstate.io:8888/api/store \
--header 'Content-Type: application/octet-stream' \
--data-binary '@/home/my_user/my_image_file_on_disk'
var data = "<file contents here>";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function() {
if(this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://rpc.ssvm.secondstate.io:8888/api/store");
xhr.setRequestHeader("Content-Type", "application/octet-stream");
xhr.send(data);
As mentioned above, this MySQL service is already set up and ready for your requests. If you would like to set up your own service (on your own hardware) please proceed to the next section called "Runing your own wasmedge-mysql".
Ubuntu 20.04 and above
sudo apt-get update
Install MySQL using package manager
sudo apt-get install -y mysql-server
Just FYI: In our case we are using an existing MySQL database installation. From here we will be creating a second_server_data
directory and starting the existing MySQL software using different port and so forth.
Create new data directory
sudo mkdir -p /opt/second_server_data/
Change permissions and ownership
sudo chmod --reference /var/lib/mysql /opt/second_server_data/
sudo chown --reference /var/lib/mysql /opt/second_server_data/
Edit apparmor configuration
sudo vi /etc/apparmor.d/usr.sbin.mysqld
Add the following block anywhere between the two parenthesis
# Allow second server
/opt/second_server_data/ r,
/opt/second_server_data/** rwk,
/var/run/mysqld/second_server.pid rw,
/var/run/mysqld/second_server.sock rw,
/var/run/mysqld/second_server.sock.lock rw,
/run/mysqld/second_server.pid rw,
/run/mysqld/second_server.sock rw,
/run/mysqld/second_server.sock.lock rw,
Restart apparmor
sudo service apparmor restart
sudo mysqld --initialize --user=mysql --datadir=/opt/second_server_data
To find the new root password simply tail
or vi
the /var/log/mysql/error.log
file
tail /var/log/mysql/error.log
You will notice a line such as the one below (which tells you the new password)
A temporary password is generated for root@localhost: abcdnewpassword
sudo mysql_secure_installation --basedir=/opt/second_server_data
sudo mysqld_safe --no-defaults --datadir=/opt/second_server_data --port=3315 --mysqlx=0 --socket=/var/run/mysqld/second_server.sock &
Logging in, can be done via socket or via TCP
mysql --socket=/var/run/mysqld/second_server.sock -u root -p
mysql -h 127.0.0.1 -P 3315 -u root -p
Create new root password
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';
FLUSH PRIVILEGES;
CREATE DATABASE wasmedge_db;
use wasmedge_db;
CREATE TABLE wasmedge_data (
wasmedge_int INT(6) NOT NULL AUTO_INCREMENT,
wasmedge_id BINARY(16) NOT NULL,
wasmedge_blob LONGBLOB NOT NULL,
PRIMARY KEY (wasmedge_int)
);
CREATE USER 'wasmedge_user'@'localhost' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON wasmedge_db . * TO 'wasmedge_user'@'localhost';
FLUSH PRIVILEGES;
ALTER USER 'wasmedge_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';
FLUSH PRIVILEGES;
git clone https://github.com/second-state/wasmedge-mysql.git
cd wasmedge-mysql
Open a new file called .env
.
vi `.env`
Place the following configuration in that file and save.
server_name=rpc.ssvm.secondstate.io
host=0.0.0.0
port=8888
db_host=localhost
db_port=3315
db_user=wasmedge_user
db_password=your_password_here
db_name=wasmedge_db
Automatically install the npm packages that ship with this build's package.json file.
npm install
node index.js
forever start index.js
Accessing the database remotely will always require the caller to have a mysql client. Further, it will require that the caller stores the password. Both of these facts make native remote access not practicable in a shared environment. Instead, we are going to implement a simple API which will accept secure HTTP requests and perform MySQL read/write transactions on behalf of the caller.
You could create a new external user like this ...
CREATE USER 'wasmedge_remote_user'@'0.0.0.0' IDENTIFIED BY 'your_password_here';
GRANT ALL PRIVILEGES ON wasmedge_db . * TO 'wasmedge_remote_user'@'0.0.0.0';
FLUSH PRIVILEGES;
ALTER USER 'wasmedge_remote_user'@'0.0.0.0' IDENTIFIED WITH mysql_native_password BY 'your_password_here';
FLUSH PRIVILEGES;
You could test remote access like this ...
Download the MySQL client from dev.mysql.com.
Run the following command on a remote machine
mysql -P 3315 -u wasmedge_remote_user -h 27.33.80.26 -p
However, the above direct remote access solution means that all users are sharing a common username and password.
There are many ways to expose MySQL over HTTP using 3rd-party software like aceql. However these also require that you share/give passwords out to end users.
One way to store data would be to allow the caller to store anything as a byte array i.e. a blob.
The following convention would need to be followed:
- a user can make a secure HTTP request to store a blob i.e. anything as a byte array
- the user is responsible encoding/decoding their data type to byte array and back again (depending on their application)
- this allows us to store images natively etc (as apposed to only allowing JSON or String)
- the API will always return a valid UUID when data is stored
- the user will load their data using the UUID which the database provided
Here are some examples of the internal SQL operations
Storing a blob
INSERT INTO wasmedge_data(wasmedge_id, wasmedge_blob) VALUES(UUID_TO_BIN(UUID()), the_byte_array);
Returns 994d926e-2a3e-11ec-a87d-08719041559b
Loading a blob
SELECT wasmedge_blob FROM wasmedge_data where BIN_TO_UUID(wasmedge_id) = '994d926e-2a3e-11ec-a87d-08719041559b';
Please use the following command to shutdown this database instance
sudo mysqladmin -h 127.0.0.1 -P 3315 -u root -p shutdown