How CasaOS Implements the Shares Service for File Sharing

CasaOS implements its shares service using a database-backed Gorm model that synchronizes Samba configuration files and automatically restarts the SMB daemon when shares are created, modified, or deleted.

The CasaOS project provides a dedicated shares service that bridges the gap between database records and Samba-based file sharing. This service manages the complete lifecycle of file shares, from persistence in SQLite to runtime configuration in the Samba daemon. The implementation centers on two primary files: service/shares.go for business logic and service/model/o_shares.go for data modeling.

Architecture of the Shares Service

The shares service follows a database-driven configuration pattern where share definitions live in an SQLite database while Samba consumes generated configuration files.

Database Model and Persistence

At the core of the system is the SharesDBModel struct defined in service/model/o_shares.go. This Gorm model represents the o_shares table and stores essential share metadata including the ID, filesystem path, anonymity flag, and timestamps. When the service initializes via NewSharesService(db *gorm.DB), it receives a *gorm.DB handle that enables all subsequent database operations.

Samba Configuration Generation

The service maintains two key files on the host filesystem:

The UpdateConfigFile method reads all rows from the o_shares table and translates each into a Samba share stanza. For example, a share named "myshare" at path /mnt/data becomes a configuration block like [myshare] with the path directive set accordingly.

Core Implementation Files

The shares service implementation spans several critical files within the CasaOS repository:

  • service/shares.go – Implements the SharesService interface with CRUD operations and Samba configuration management
  • service/model/o_shares.go – Defines the SharesDBModel struct and database schema for the o_shares table
  • pkg/utils/file – Provides utility functions for file operations including WriteToPath and existence checks
  • pkg/utils/command – Wraps shell command execution for restarting services

CRUD Operations and Samba Synchronization

Every mutating operation follows a consistent pattern: update the database, regenerate the configuration, and restart the Samba daemon.

Creating a Share

When CreateShare receives a SharesDBModel, it first inserts the record into the database using db.Create. Immediately after persistence, it triggers InitSambaConfig to ensure the base /etc/samba/smb.conf contains the CasaOS header and the include=/etc/samba/smb.casa.conf directive. Finally, UpdateConfigFile rebuilds the include file with all existing shares and executes the restart command via command.OnlyExec("source "+config.AppInfo.ShellPath+"/helper.sh ;RestartSMBD").

Deleting and Querying Shares

The service provides several query methods:

  • GetSharesList() – Retrieves all share records from the database
  • GetSharesByPath(path) – Finds shares matching a specific filesystem path
  • GetSharesByName(name) – Locates shares by their configured name

Deletion methods include DeleteShare (by ID) and DeleteShareByPath (removing all shares under a directory tree). Both operations follow the same synchronization pattern: modify the database, regenerate smb.casa.conf, and restart Samba.

Working with the Shares Service

Below is a practical example demonstrating how to interact with the shares service in a CasaOS environment:

// Assume `db` is an opened *gorm.DB (CasaOS bootstraps this already)
sharesSvc := service.NewSharesService(db)

// 1. Create a new share
newShare := model.SharesDBModel{
    Anonymous: false,
    Path:      "/mnt/usbdrive/shared",
    Name:      "myshare",
}
sharesSvc.CreateShare(newShare)

// 2. List all shares
allShares := sharesSvc.GetSharesList()
for _, s := range allShares {
    fmt.Printf("Share ID=%d, Path=%s, Anonymous=%t\n", s.ID, s.Path, s.Anonymous)
}

// 3. Find a share by its underlying filesystem path
matches := sharesSvc.GetSharesByPath("/mnt/usbdrive/shared")
if len(matches) > 0 {
    fmt.Println("Found share:", matches[0].Name)
}

// 4. Delete a share by its database ID (stringified uint)
sharesSvc.DeleteShare(fmt.Sprintf("%d", newShare.ID))

// 5. Delete all shares that reside under a given directory tree
sharesSvc.DeleteShareByPath("/mnt/usbdrive/")

These calls automatically keep the Samba configuration file in sync, requiring no additional system commands from the caller.

Summary

  • CasaOS manages Samba shares through a database-backed service defined in service/shares.go and service/model/o_shares.go.
  • The SharesDBModel struct persists share metadata to an SQLite database via Gorm.
  • UpdateConfigFile generates /etc/samba/smb.casa.conf by translating database rows into Samba configuration stanzas.
  • InitSambaConfig ensures the main /etc/samba/smb.conf includes the CasaOS-generated file and applies global settings.
  • Every CRUD operation triggers an automatic Samba daemon restart via the RestartSMBD helper command.

Frequently Asked Questions

How does CasaOS store share definitions?

CasaOS stores share definitions in an SQLite database using the o_shares table, mapped by the SharesDBModel struct in service/model/o_shares.go. This table tracks the share path, name, anonymity settings, and timestamps.

What happens when a new share is created in CasaOS?

When CreateShare is called, the service inserts the record into the database, ensures the base Samba configuration exists via InitSambaConfig, regenerates the include file through UpdateConfigFile, and executes the RestartSMBD command to apply changes immediately.

Where does CasaOS write the Samba configuration files?

CasaOS writes share-specific configuration to /etc/samba/smb.casa.conf and ensures the main /etc/samba/smb.conf contains an include directive pointing to this file. The service also applies CasaOS-specific global settings to the main configuration if they are not already present.

Can external applications use the CasaOS shares service?

Yes, external applications or plugins can import the service package and call NewSharesService(db) to obtain a service instance. They can then use methods like CreateShare, DeleteShare, and GetSharesList to manage shares, with all Samba configuration updates handled automatically by the service.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →