From c85e145c46a2d65cb322fdb161c0700f9d479abb Mon Sep 17 00:00:00 2001 From: Falk Werner Date: Sat, 11 Apr 2020 10:56:17 +0200 Subject: [PATCH] use webfuse-js --- .gitignore | 3 + Dockerfile | 21 ++- www/index.html | 18 -- www/js/package.json | 11 -- www/js/webfuse/bad_state.js | 15 -- www/js/webfuse/client.js | 223 ------------------------- www/js/webfuse/file_mode.js | 10 -- www/js/webfuse/provider.js | 30 ---- www/package.json | 34 ++++ www/{js => src}/.eslintrc.js | 0 www/{js => src}/connection_view.js | 0 www/{js => src}/filesystem_provider.js | 4 +- www/src/index.html | 20 +++ www/{js/startup.js => src/index.js} | 2 +- www/{ => src}/style/main.css | 0 www/webpack.config.js | 29 ++++ 16 files changed, 107 insertions(+), 313 deletions(-) create mode 100644 .gitignore delete mode 100644 www/index.html delete mode 100644 www/js/package.json delete mode 100644 www/js/webfuse/bad_state.js delete mode 100644 www/js/webfuse/client.js delete mode 100644 www/js/webfuse/file_mode.js delete mode 100644 www/js/webfuse/provider.js create mode 100644 www/package.json rename www/{js => src}/.eslintrc.js (100%) rename www/{js => src}/connection_view.js (100%) rename www/{js => src}/filesystem_provider.js (95%) create mode 100644 www/src/index.html rename www/{js/startup.js => src/index.js} (94%) rename www/{ => src}/style/main.css (100%) create mode 100644 www/webpack.config.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..810c656 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/www/node_modules +/www/package-lock.json +/www/dist \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index dce2c25..fbf4fe2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,8 +19,6 @@ RUN set -x \ libconfig-dev \ libpam0g-dev -COPY www /var/www - ARG PARALLELMFLAGS=-j2 ARG DUMB_INIT_VERSION=1.2.2 @@ -124,6 +122,25 @@ RUN set -x \ COPY webfused.conf /etc +ARG NPM_VERSION=">=6.14.0 <7.0.0" +ARG NODEJS_VERSION=12 +RUN set -x \ + && apt update \ + && apt upgrade -y \ + && apt install --yes --no-install-recommends \ + nodejs \ + npm \ + && npm install -g npm@"${NPM_VERSION}" \ + && npm install -g n \ + && n "${NODEJS_VERSION}" + +COPY www /usr/local/src/www +RUN set -x \ + && cd /usr/local/src/www \ + && npm run build \ + && mkdir -p /var/www \ + && cp -r ./dist/. /var/www/ + ARG USERID=1000 RUN set -x \ && useradd -u "$USERID" -ms /bin/bash user diff --git a/www/index.html b/www/index.html deleted file mode 100644 index 0cb0918..0000000 --- a/www/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - WebFuse Example - - - - - - -
-
-
Connection
-
-
-
- - - \ No newline at end of file diff --git a/www/js/package.json b/www/js/package.json deleted file mode 100644 index 6c553ef..0000000 --- a/www/js/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "webfuse-provider", - "version": "0.2.0", - "description": "Provider for websocket filesystem (webfuse)", - "main": "startup.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Falk Werner", - "license": "LGPL-3.0" -} diff --git a/www/js/webfuse/bad_state.js b/www/js/webfuse/bad_state.js deleted file mode 100644 index fdb05d9..0000000 --- a/www/js/webfuse/bad_state.js +++ /dev/null @@ -1,15 +0,0 @@ -export class BadState extends Error { - static get BAD() { return 1; } - - static get NOT_IMPLEMENTED() { return 2; } - static get TIMEOUT() { return 3; } - static get FORMAT() { return 4; } - - static get NO_ENTRY() { return 101; } - static get NO_ACCESS() { return 102; } - - constructor(code) { - super("Bad State"); - this.code = code; - } -} \ No newline at end of file diff --git a/www/js/webfuse/client.js b/www/js/webfuse/client.js deleted file mode 100644 index b046b3f..0000000 --- a/www/js/webfuse/client.js +++ /dev/null @@ -1,223 +0,0 @@ -import { BadState } from "./bad_state.js"; - -export class Client { - static get _PROTOCOL() { return "webfuse-adapter-server"; } - - constructor(provider) { - this._provider = { }; - this._pendingRequests = {}; - this._id = 0; - this._ws = null; - this.onopen = () => { }; - this.onclose = () => { }; - this.onerror = () => { }; - } - - connectTo(url) { - this.disconnect(); - - this._ws = new WebSocket(url, Client._PROTOCOL); - this._ws.onopen = this.onopen; - this._ws.onclose = this.onclose; - this._ws.onerror = this.onerror; - - this._ws.onmessage = (message) => { - this._onmessage(message); - }; - } - - _invokeRequest(method, params) { - this._id += 1; - const id = this._id; - const request = {method, params, id}; - - return new Promise((resolve, reject) => { - this._pendingRequests[id] = {resolve, reject}; - this._ws.send(JSON.stringify(request)); - }); - } - - authenticate(type, credentials) { - return this._invokeRequest("authenticate", [type, credentials]); - } - - addProvider(name, provider) { - this._provider[name] = provider; - const request = { - "method": "add_filesystem", - "params": [name], - "id": 23 - }; - - this._ws.send(JSON.stringify(request)); - } - - disconnect() { - if (this._ws) { - this._ws.close(); - this._ws = null; - } - } - - isConnected() { - return ((this._ws) && (this._ws.readyState === WebSocket.OPEN)); - } - - _isRequest(request) { - const method = request.method; - - return (("string" === typeof(method)) && ("params" in request)); - } - - _isResponse(response) { - const id = response.id; - - return (("number" === typeof(id)) && (("result" in response) || ("error" in response))); - } - - _removePendingRequest(id) { - let result = null; - - if (id in this._pendingRequests) { - result = this._pendingRequests[id]; - Reflect.deleteProperty(this._pendingRequests, id); - } - - return result; - } - - _onmessage(message) { - try { - const data = JSON.parse(message.data); - - if (this._isRequest(data)) { - const method = data.method; - const id = data.id; - const params = data.params; - - if ("number" === typeof(id)) { - this._invoke(method, params, id); - } - else { - this._notify(method, params); - } - } - else if (this._isResponse(data)) { - const id = data.id; - const result = data.result; - const error = data.error; - - const request = this._removePendingRequest(id); - if (request) { - if (result) { - request.resolve(result); - } - else { - request.reject(error); - } - } - } - - } - catch (ex) { - // swallow - } - } - - _invoke(method, params, id) { - this._invokeAsync(method, params). - then((result) => { - const response = { result, id }; - this._ws.send(JSON.stringify(response)); - }). - catch((ex) => { - const code = ex.code || BadState.BAD; - const response = {error: {code}, id}; - this._ws.send(JSON.stringify(response)); - }); - - } - - async _invokeAsync(method, params) { - switch(method) - { - case "lookup": - return this._lookup(params); - case "getattr": - return this._getattr(params); - case "readdir": - return this._readdir(params); - case "open": - return this._open(params); - case "read": - return this._read(params); - default: - throw new BadState(BadState.NOT_IMPLEMENTED); - } - } - - _notify(method, params) { - switch(method) { - case 'close': - this._close(params); - break; - default: - throw new Error(`Invalid method: "${method}"`); - } - } - - _getProvider(name) { - if (name in this._provider) { - return this._provider[name]; - } - else { - throw new Error('Unknown provider'); - } - } - - async _lookup([providerName, parent, name]) { - const provider = this._getProvider(providerName); - - return provider.lookup(parent, name); - } - - async _getattr([providerName, inode]) { - const provider = this._getProvider(providerName); - - return provider.getattr(inode); - } - - async _readdir([providerName, inode]) { - const provider = this._getProvider(providerName); - - return provider.readdir(inode); - } - - async _open([providerName, inode, mode]) { - const provider = this._getProvider(providerName); - - return provider.open(inode, mode); - } - - _close([providerName, inode, handle, mode]) { - const provider = this._getProvider(providerName); - - provider.close(inode, handle, mode); - } - - async _read([providerName, inode, handle, offset, length]) { - const provider = this._getProvider(providerName); - const data = await provider.read(inode, handle, offset, length); - - if ("string" === typeof(data)) { - return { - data: btoa(data), - format: "base64", - count: data.length - }; - } - else { - throw new BadState(BadState.BAD); - } - } -} \ No newline at end of file diff --git a/www/js/webfuse/file_mode.js b/www/js/webfuse/file_mode.js deleted file mode 100644 index b81a1ea..0000000 --- a/www/js/webfuse/file_mode.js +++ /dev/null @@ -1,10 +0,0 @@ -export class FileMode { - static get ACCESS_MODE() { return 0x003; } - static get READONLY() { return 0x000; } - static get WRITEONLY() { return 0x001; } - static get READWRITE() { return 0x002; } - static get CREATE() { return 0x040; } - static get EXCLUSIVE() { return 0x080; } - static get TRUNKATE() { return 0x200; } - static get APPEND() { return 0x400; } -} \ No newline at end of file diff --git a/www/js/webfuse/provider.js b/www/js/webfuse/provider.js deleted file mode 100644 index b9c5dc2..0000000 --- a/www/js/webfuse/provider.js +++ /dev/null @@ -1,30 +0,0 @@ -/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */ - -import { BadState } from "./bad_state.js"; - -export class Provider { - - async lookup(_parent, _name) { - throw new BadState(BadState.NOT_IMPLEMENTED); - } - - async getattr(_inode) { - throw new BadState(BadState.NOT_IMPLEMENTED); - } - - async readdir(_inode) { - throw new BadState(BadState.NOT_IMPLEMENTED); - } - - async open(_inode, _mode) { - throw new BadState(BadState.NOT_IMPLEMENTED); - } - - close(_inode, _handle, _mode) { - // empty - } - - async read(_inode, _handle, _offset, _length) { - throw new BadState(BadState.NOT_IMPLEMENTED); - } -} diff --git a/www/package.json b/www/package.json new file mode 100644 index 0000000..30a1097 --- /dev/null +++ b/www/package.json @@ -0,0 +1,34 @@ +{ + "name": "webfuse-example", + "version": "0.1.0", + "description": "Example to demonstate webfuse", + "private": true, + "main": "./dist/webfuse-example.js", + "scripts": { + "build": "webpack --config webpack.config.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/falk-werner/webfuse-example.git" + }, + "keywords": [ + "webfuse", + "websockets", + "libfuse", + "fuse", + "example" + ], + "author": "Falk Werner", + "license": "MIT", + "homepage": "https://github.com/falk-werner/webfuse-example#readme", + "devDependencies": { + "copy-webpack-plugin": "^5.1.1", + "html-webpack-plugin": "^4.2.0", + "webpack": "^4.42.1", + "webpack-cli": "^3.3.11" + }, + "dependencies": { + "webfuse": "^0.1.0" + } +} diff --git a/www/js/.eslintrc.js b/www/src/.eslintrc.js similarity index 100% rename from www/js/.eslintrc.js rename to www/src/.eslintrc.js diff --git a/www/js/connection_view.js b/www/src/connection_view.js similarity index 100% rename from www/js/connection_view.js rename to www/src/connection_view.js diff --git a/www/js/filesystem_provider.js b/www/src/filesystem_provider.js similarity index 95% rename from www/js/filesystem_provider.js rename to www/src/filesystem_provider.js index 85ad287..f06a2e1 100644 --- a/www/js/filesystem_provider.js +++ b/www/src/filesystem_provider.js @@ -1,8 +1,6 @@ /* eslint no-unused-vars: ["error", { "argsIgnorePattern": "^_" }] */ -import { BadState } from "./webfuse/bad_state.js"; -import { FileMode } from "./webfuse/file_mode.js"; -import { Provider } from "./webfuse/provider.js"; +import { BadState, FileMode, Provider } from "webfuse"; export class FileSystemProvider extends Provider { constructor(root) { diff --git a/www/src/index.html b/www/src/index.html new file mode 100644 index 0000000..ce665e3 --- /dev/null +++ b/www/src/index.html @@ -0,0 +1,20 @@ + + + <%= htmlWebpackPlugin.options.title %> + + + <%= htmlWebpackPlugin.tags.headTags %> + + + +
+
+
Connection
+
+
+
+ +<%= htmlWebpackPlugin.tags.bodyTage %> + + + \ No newline at end of file diff --git a/www/js/startup.js b/www/src/index.js similarity index 94% rename from www/js/startup.js rename to www/src/index.js index 284d229..0632653 100644 --- a/www/js/startup.js +++ b/www/src/index.js @@ -1,4 +1,4 @@ -import { Client } from "./webfuse/client.js"; +import { Client } from "webfuse"; import { ConnectionView } from "./connection_view.js"; import { FileSystemProvider } from "./filesystem_provider.js"; diff --git a/www/style/main.css b/www/src/style/main.css similarity index 100% rename from www/style/main.css rename to www/src/style/main.css diff --git a/www/webpack.config.js b/www/webpack.config.js new file mode 100644 index 0000000..bb7234f --- /dev/null +++ b/www/webpack.config.js @@ -0,0 +1,29 @@ +const path = require('path'); +const HtmlWebpackPlugin = require('html-webpack-plugin'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); + +module.exports = { + mode: 'production', + entry: './src/index.js', + output: { + filename: 'webfuse-example.js', + library: 'webfuse', + libraryTarget: 'umd', + path: path.resolve(__dirname, './dist') + }, + plugins: [ + new HtmlWebpackPlugin({ + title: "Webfuse Example", + filename: "index.html", + template: "./src/index.html" + }), + new CopyWebpackPlugin([ + { from: './src/style', to: 'style' } + ]) + ], + resolve: { + alias: { + webfuse: "webfuse/src/index.js" + } + } +};