A mini cloud-management platform that simulates how a real cloud provider provisions virtual machines. It combines a Go backend (concurrent worker pool, REST API, bitwise subnet calculator) with a MySQL database and a React + Tailwind dashboard.
The project is built around three core computer-science ideas:
| Layer | Concept | Where |
|---|---|---|
| Operating Systems | Worker pool (threads/goroutines), job queue, per-instance mutex locks | CLOUD/main.go |
| Networking | CIDR / subnet math using bitwise operations, TCP port checks | CLOUD/main.go |
| DBMS | MySQL-backed persistence of instances and their lifecycle state | CLOUD/main.go, CLOUD/db/ |
- Provision virtual machines with a chosen name, vCPU count (1–8) and RAM (1–8 GB).
- Asynchronous provisioning – requests are placed on a job queue and handled by a pool of 3 worker goroutines.
- Live status tracking – instances move through
PENDING → PROVISIONING → RUNNING; the dashboard auto-refreshes every 2 seconds. - Per-instance mutex locks so two workers never operate on the same instance at once.
- Subnet (CIDR) calculator – returns network address, broadcast address, total hosts and usable hosts, computed with bitwise operations.
- TCP ping utility (
TCPPing) for Layer-4 reachability checks. - Dark-themed React dashboard built with Vite, Tailwind CSS and Lucide icons.
┌──────────────────────┐ HTTP /api/* ┌───────────────────────────────┐
│ React Dashboard │ ──────────────► │ Go HTTP API (:8080) │
│ (Vite dev :5173) │ ◄────────────── │ │
└──────────────────────┘ │ ┌───────────────────────┐ │
│ │ Job Queue (cap 10) │ │
│ └──────────┬────────────┘ │
│ ┌───────┴───────┐ │
│ Worker 1 Worker 2 Worker 3│
│ └───────┬───────┘ │
└──────────────┼────────────────┘
▼
┌──────────────────┐
│ MySQL │
│ cloud_manager DB │
└──────────────────┘
Provisioning flow
- The client sends
POST /api/instances. - The API inserts a row with status
PENDINGand pushes aJobonto the queue. - A free worker acquires the instance's mutex, sets the status to
PROVISIONING, simulates a 3-second boot delay, then sets it toRUNNING. - The dashboard polls
GET /api/instancesand shows the new state.
Backend: Go, database/sql, go-sql-driver/mysql, net/http
Database: MySQL
Frontend: React 19, Vite, Tailwind CSS 4, Lucide React, Oxlint
Cloud-Manager/
├── CLOUD/ # Go backend
│ ├── main.go # Worker pool, CIDR calculator, REST handlers, entry point
│ ├── worker/pool.go # Worker package
│ ├── db/database.go # MySQL connection helper
│ ├── go.mod
│ └── go.sum
└── cloud-frontend/ # React dashboard
├── src/
│ ├── App.jsx # Dashboard UI
│ ├── main.jsx
│ └── index.css
├── vite.config.js # Dev server + /api proxy to :8080
└── package.json
- Go (the module targets the version in
CLOUD/go.mod) - Node.js 18+ and npm
- MySQL 8+ running locally on port
3306
git clone https://github.com/Sagar07-star/Cloud-Manager.git
cd Cloud-ManagerCreate the database and the instances table (schema inferred from the API code):
CREATE DATABASE IF NOT EXISTS cloud_manager;
USE cloud_manager;
CREATE TABLE IF NOT EXISTS instances (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
subnet_id INT NOT NULL,
name VARCHAR(255) NOT NULL,
vcpus INT NOT NULL,
ram_mb INT NOT NULL,
ip_address VARCHAR(45),
status VARCHAR(20) NOT NULL DEFAULT 'PENDING'
);In CLOUD/main.go, update the DSN in main() with your own MySQL credentials:
dsn := "<user>:<password>@tcp(127.0.0.1:3306)/cloud_manager?parseTime=true"Do not commit real passwords. Consider reading credentials from environment variables (e.g.
os.Getenv("DB_PASSWORD")) instead of hard-coding them.
cd CLOUD
go mod tidy
go run main.goYou should see:
[DBMS Engine] Connected to MySQL Successfully!
[OS Engine] Started 3 Worker Threads
[HTTP API Gateway] Server running at http://localhost:8080
In a second terminal:
cd cloud-frontend
npm install
npm run devOpen the URL Vite prints (usually http://localhost:5173). Requests to /api/* are proxied to the Go server on port 8080.
Base URL: http://localhost:8080
Returns all instances.
[
{
"id": 1,
"user_id": 1,
"subnet_id": 1,
"name": "web-server-node-1",
"vcpus": 2,
"ram_mb": 2048,
"ip_address": "10.0.1.10",
"status": "RUNNING"
}
]Creates an instance and enqueues a provisioning job.
Request body
{ "name": "web-server-node-1", "vcpus": 2, "ram_mb": 2048 }Response – 201 Created
{
"message": "Provisioning job enqueued",
"instance_id": 1,
"status": "PENDING"
}Calculates subnet details. Defaults to 10.0.1.0/24 if cidr is omitted.
{
"cidr": "10.0.1.0/24",
"network_address": "10.0.1.0",
"broadcast_address": "10.0.1.255",
"total_hosts": 256,
"usable_hosts": 254
}Returns 400 Bad Request for an invalid CIDR.
For a CIDR such as 10.0.1.0/24:
mask = 0xFFFFFFFF << (32 - prefix)
network = ip & mask
broadcast = network | ^mask
total = 1 << (32 - prefix)
usable = total - 2 (0 for /31 and /32)
# Create an instance
curl -X POST http://localhost:8080/api/instances \
-H "Content-Type: application/json" \
-d '{"name":"demo-vm","vcpus":2,"ram_mb":2048}'
# List instances (status changes PENDING → PROVISIONING → RUNNING)
curl http://localhost:8080/api/instances
# Subnet calculation
curl "http://localhost:8080/api/subnet-calc?cidr=192.168.0.0/16"- Move DB credentials to environment variables / a config file
- User authentication and multi-user support (currently hard-coded
user_id = 1) - Dynamic IP allocation from subnets (currently
10.0.1.10) - Start / stop / delete instance endpoints
- Subnet management and persistence
- Dockerfile and
docker-compose.ymlfor one-command startup
- Fork the repo
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push the branch:
git push origin feature/my-feature - Open a Pull Request
Sagar – @Sagar07-star