mirror of https://github.com/jetkvm/kvm.git
Compare commits
3 Commits
ddd1758a14
...
d6798d53f3
Author | SHA1 | Date |
---|---|---|
|
d6798d53f3 | |
|
55fbd6c359 | |
|
cf650b4aa1 |
|
@ -0,0 +1,355 @@
|
|||
<div align="center">
|
||||
<img alt="JetKVM logo" src="https://jetkvm.com/logo-blue.png" height="28">
|
||||
|
||||
### Development Guide
|
||||
|
||||
[Discord](https://jetkvm.com/discord) | [Website](https://jetkvm.com) | [Issues](https://github.com/jetkvm/cloud-api/issues) | [Docs](https://jetkvm.com/docs)
|
||||
|
||||
[](https://twitter.com/jetkvm)
|
||||
|
||||
[](https://goreportcard.com/report/github.com/jetkvm/kvm)
|
||||
|
||||
</div>
|
||||
|
||||
# JetKVM Development Guide
|
||||
|
||||
Welcome to JetKVM development! This guide will help you get started quickly, whether you're fixing bugs, adding features, or just exploring the codebase.
|
||||
|
||||
## Get Started
|
||||
|
||||
### Prerequisites
|
||||
- **A JetKVM device** (for full development)
|
||||
- **[Go 1.24.4+](https://go.dev/doc/install)** and **[Node.js 22.15.0](https://nodejs.org/en/download/)**
|
||||
- **[Git](https://git-scm.com/downloads)** for version control
|
||||
- **[SSH access](https://jetkvm.com/docs/advanced-usage/developing#developer-mode)** to your JetKVM device
|
||||
|
||||
### Development Environment
|
||||
|
||||
**Recommended:** Development is best done on **Linux** or **macOS**.
|
||||
|
||||
If you're using Windows, we strongly recommend using **WSL (Windows Subsystem for Linux)** for the best development experience:
|
||||
- [Install WSL on Windows](https://docs.microsoft.com/en-us/windows/wsl/install)
|
||||
- [WSL Setup Guide](https://docs.microsoft.com/en-us/windows/wsl/setup/environment)
|
||||
|
||||
This ensures compatibility with shell scripts and build tools used in the project.
|
||||
|
||||
### Project Setup
|
||||
|
||||
1. **Clone the repository:**
|
||||
```bash
|
||||
git clone https://github.com/jetkvm/kvm.git
|
||||
cd kvm
|
||||
```
|
||||
|
||||
2. **Check your tools:**
|
||||
```bash
|
||||
go version && node --version
|
||||
```
|
||||
|
||||
3. **Find your JetKVM IP address** (check your router or device screen)
|
||||
|
||||
4. **Deploy and test:**
|
||||
```bash
|
||||
./dev_deploy.sh -r 192.168.1.100 # Replace with your device IP
|
||||
```
|
||||
|
||||
5. **Open in browser:** `http://192.168.1.100`
|
||||
|
||||
That's it! You're now running your own development version of JetKVM.
|
||||
|
||||
---
|
||||
|
||||
## Common Tasks
|
||||
|
||||
### Modify the UI
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
npm install
|
||||
./dev_device.sh 192.168.1.100 # Replace with your device IP
|
||||
```
|
||||
|
||||
Now edit files in `ui/src/` and see changes live in your browser!
|
||||
|
||||
### Modify the backend
|
||||
|
||||
```bash
|
||||
# Edit Go files (config.go, web.go, etc.)
|
||||
./dev_deploy.sh -r 192.168.1.100 --skip-ui-build
|
||||
```
|
||||
|
||||
### Run tests
|
||||
|
||||
```bash
|
||||
./dev_deploy.sh -r 192.168.1.100 --run-go-tests
|
||||
```
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
ssh root@192.168.1.100
|
||||
tail -f /var/log/jetkvm.log
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Project Layout
|
||||
|
||||
```
|
||||
/kvm/
|
||||
├── main.go # App entry point
|
||||
├── config.go # Settings & configuration
|
||||
├── web.go # API endpoints
|
||||
├── ui/ # React frontend
|
||||
│ ├── src/routes/ # Pages (login, settings, etc.)
|
||||
│ └── src/components/ # UI components
|
||||
└── internal/ # Internal Go packages
|
||||
```
|
||||
|
||||
**Key files for beginners:**
|
||||
|
||||
- `web.go` - Add new API endpoints here
|
||||
- `config.go` - Add new settings here
|
||||
- `ui/src/routes/` - Add new pages here
|
||||
- `ui/src/components/` - Add new UI components here
|
||||
|
||||
---
|
||||
|
||||
## Development Modes
|
||||
|
||||
### Full Development (Recommended)
|
||||
|
||||
*Best for: Complete feature development*
|
||||
|
||||
```bash
|
||||
# Deploy everything to your JetKVM device
|
||||
./dev_deploy.sh -r <YOUR_DEVICE_IP>
|
||||
```
|
||||
|
||||
### Frontend Only
|
||||
|
||||
*Best for: UI changes without device*
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
npm install
|
||||
./dev_device.sh <YOUR_DEVICE_IP>
|
||||
```
|
||||
|
||||
### Quick Backend Changes
|
||||
|
||||
*Best for: API or backend logic changes*
|
||||
|
||||
```bash
|
||||
# Skip frontend build for faster deployment
|
||||
./dev_deploy.sh -r <YOUR_DEVICE_IP> --skip-ui-build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Debugging Made Easy
|
||||
|
||||
### Check if everything is working
|
||||
|
||||
```bash
|
||||
# Test connection to device
|
||||
ping 192.168.1.100
|
||||
|
||||
# Check if JetKVM is running
|
||||
ssh root@192.168.1.100 ps aux | grep jetkvm
|
||||
```
|
||||
|
||||
### View live logs
|
||||
|
||||
```bash
|
||||
ssh root@192.168.1.100
|
||||
tail -f /var/log/jetkvm.log
|
||||
```
|
||||
|
||||
### Reset everything (if stuck)
|
||||
|
||||
```bash
|
||||
ssh root@192.168.1.100
|
||||
rm /userdata/kvm_config.json
|
||||
systemctl restart jetkvm
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing Your Changes
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. Deploy your changes: `./dev_deploy.sh -r <IP>`
|
||||
2. Open browser: `http://<IP>`
|
||||
3. Test your feature
|
||||
4. Check logs: `ssh root@<IP> tail -f /var/log/jetkvm.log`
|
||||
|
||||
### Automated Testing
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
./dev_deploy.sh -r <IP> --run-go-tests
|
||||
|
||||
# Frontend linting
|
||||
cd ui && npm run lint
|
||||
```
|
||||
|
||||
### API Testing
|
||||
|
||||
```bash
|
||||
# Test login endpoint
|
||||
curl -X POST http://<IP>/auth/password-local \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"password": "test123"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Common Issues & Solutions
|
||||
|
||||
### "Build failed" or "Permission denied"
|
||||
|
||||
```bash
|
||||
# Fix permissions
|
||||
ssh root@<IP> chmod +x /userdata/jetkvm/bin/jetkvm_app_debug
|
||||
|
||||
# Clean and rebuild
|
||||
go clean -modcache
|
||||
go mod tidy
|
||||
make build_dev
|
||||
```
|
||||
|
||||
### "Can't connect to device"
|
||||
|
||||
```bash
|
||||
# Check network
|
||||
ping <IP>
|
||||
|
||||
# Check SSH
|
||||
ssh root@<IP> echo "Connection OK"
|
||||
```
|
||||
|
||||
### "Frontend not updating"
|
||||
|
||||
```bash
|
||||
# Clear cache and rebuild
|
||||
cd ui
|
||||
npm cache clean --force
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Adding a New Feature
|
||||
|
||||
1. **Backend:** Add API endpoint in `web.go`
|
||||
2. **Config:** Add settings in `config.go`
|
||||
3. **Frontend:** Add UI in `ui/src/routes/`
|
||||
4. **Test:** Deploy and test with `./dev_deploy.sh`
|
||||
|
||||
### Code Style
|
||||
|
||||
- **Go:** Follow standard Go conventions
|
||||
- **TypeScript:** Use TypeScript for type safety
|
||||
- **React:** Keep components small and reusable
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Enable debug logging
|
||||
export LOG_TRACE_SCOPES="jetkvm,cloud,websocket,native,jsonrpc"
|
||||
|
||||
# Frontend development
|
||||
export JETKVM_PROXY_URL="ws://<IP>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Need Help?
|
||||
|
||||
1. **Check logs first:** `ssh root@<IP> tail -f /var/log/jetkvm.log`
|
||||
2. **Search issues:** [GitHub Issues](https://github.com/jetkvm/kvm/issues)
|
||||
3. **Ask on Discord:** [JetKVM Discord](https://jetkvm.com/discord)
|
||||
4. **Read docs:** [JetKVM Documentation](https://jetkvm.com/docs)
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
### Ready to contribute?
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Test thoroughly
|
||||
5. Submit a pull request
|
||||
|
||||
### Before submitting:
|
||||
|
||||
- [ ] Code works on device
|
||||
- [ ] Tests pass
|
||||
- [ ] Code follows style guidelines
|
||||
- [ ] Documentation updated (if needed)
|
||||
|
||||
---
|
||||
|
||||
## Advanced Topics
|
||||
|
||||
### Performance Profiling
|
||||
|
||||
```bash
|
||||
# Enable profiling
|
||||
go build -o bin/jetkvm_app -ldflags="-X main.enableProfiling=true" cmd/main.go
|
||||
|
||||
# Access profiling
|
||||
curl http://<IP>:6060/debug/pprof/
|
||||
```
|
||||
### Advanced Environment Variables
|
||||
|
||||
```bash
|
||||
# Enable trace logging (useful for debugging)
|
||||
export LOG_TRACE_SCOPES="jetkvm,cloud,websocket,native,jsonrpc"
|
||||
|
||||
# For frontend development
|
||||
export JETKVM_PROXY_URL="ws://<JETKVM_IP>"
|
||||
|
||||
# Enable SSL in development
|
||||
export USE_SSL=true
|
||||
```
|
||||
|
||||
### Configuration Management
|
||||
|
||||
The application uses a JSON configuration file stored at `/userdata/kvm_config.json`.
|
||||
|
||||
#### Adding New Configuration Options
|
||||
|
||||
1. **Update the Config struct in `config.go`:**
|
||||
|
||||
```go
|
||||
type Config struct {
|
||||
// ... existing fields
|
||||
NewFeatureEnabled bool `json:"new_feature_enabled"`
|
||||
}
|
||||
```
|
||||
|
||||
2. **Update the default configuration:**
|
||||
|
||||
```go
|
||||
var defaultConfig = &Config{
|
||||
// ... existing defaults
|
||||
NewFeatureEnabled: false,
|
||||
}
|
||||
```
|
||||
|
||||
3. **Add migration logic if needed for existing installations**
|
||||
|
||||
|
||||
---
|
||||
|
||||
**Happy coding!**
|
||||
|
||||
For more information, visit the [JetKVM Documentation](https://jetkvm.com/docs) or join our [Discord Server](https://jetkvm.com/discord).
|
|
@ -37,7 +37,9 @@ JetKVM is written in Go & TypeScript. with some bits and pieces written in C. An
|
|||
|
||||
The project contains two main parts, the backend software that runs on the KVM device and the frontend software that is served by the KVM device, and also the cloud.
|
||||
|
||||
For most of local device development, all you need is to use the `./dev_deploy.sh` script. It will build the frontend and backend and deploy them to the local KVM device. Run `./dev_deploy.sh --help` for more information.
|
||||
For comprehensive development information, including setup, testing, debugging, and contribution guidelines, see **[DEVELOPMENT.md](DEVELOPMENT.md)**.
|
||||
|
||||
For quick device development, use the `./dev_deploy.sh` script. It will build the frontend and backend and deploy them to the local KVM device. Run `./dev_deploy.sh --help` for more information.
|
||||
|
||||
## Backend
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
"react-dom": "^19.1.0",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-router-dom": "^7.6.3",
|
||||
"react-simple-keyboard": "^3.8.93",
|
||||
"react-use-websocket": "^4.13.0",
|
||||
"react-xtermjs": "^1.0.10",
|
||||
|
@ -1030,15 +1030,6 @@
|
|||
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
|
||||
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.11",
|
||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.11.tgz",
|
||||
|
@ -1788,6 +1779,66 @@
|
|||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||
"version": "1.4.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.0.2",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||
"version": "1.4.3",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.0.2",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "0.2.11",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.4.3",
|
||||
"@emnapi/runtime": "^1.4.3",
|
||||
"@tybys/wasm-util": "^0.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||
"version": "0.9.0",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||
"version": "2.8.0",
|
||||
"dev": true,
|
||||
"inBundle": true,
|
||||
"license": "0BSD",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.1.11",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz",
|
||||
|
@ -2829,6 +2880,15 @@
|
|||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
|
||||
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
|
@ -5830,35 +5890,41 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-router": {
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
|
||||
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.6.3.tgz",
|
||||
"integrity": "sha512-zf45LZp5skDC6I3jDLXQUu0u26jtuP4lEGbc7BbdyxenBN1vJSTA18czM2D+h5qyMBuMrD+9uB+mU37HIoKGRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.0"
|
||||
"cookie": "^1.0.1",
|
||||
"set-cookie-parser": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8"
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-router-dom": {
|
||||
"version": "6.30.1",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
|
||||
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
|
||||
"version": "7.6.3",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.6.3.tgz",
|
||||
"integrity": "sha512-DiWJm9qdUAmiJrVWaeJdu4TKu13+iB/8IEi0EW/XgaHCjW/vWGrwzup0GVvaMteuZjKnh5bEvJP/K0MDnzawHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remix-run/router": "1.23.0",
|
||||
"react-router": "6.30.1"
|
||||
"react-router": "7.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
"node": ">=20.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16.8",
|
||||
"react-dom": ">=16.8"
|
||||
"react": ">=18",
|
||||
"react-dom": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/react-simple-keyboard": {
|
||||
|
@ -6171,6 +6237,12 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
|
||||
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"react-dom": "^19.1.0",
|
||||
"react-hot-toast": "^2.5.2",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-router-dom": "^6.22.3",
|
||||
"react-router-dom": "^7.6.3",
|
||||
"react-simple-keyboard": "^3.8.93",
|
||||
"react-use-websocket": "^4.13.0",
|
||||
"react-xtermjs": "^1.0.10",
|
||||
|
|
Loading…
Reference in New Issue