Skip to main content
Version: Next

Rubix OS Modules

ROS provides built-in modules for additional functionality built on top of the plugin system. Modules are built for extending ROS functionality.

tip

Modules can only be developed after contacting Nube iO support: support@nube-io.com

demo module

For quick start see example: demo module

Module Features

  • Registering custom http handlers
  • YAML-based configuration system on the Rubix CE software (Rubix Computer Edition)

Module Applications

  • Protocol drivers
  • Database connections and cloud connections

Module Naming

module-core-lora
module-oem-cps
module-contrib-xxx (for open module developed by the third party)
module-contrib-oem-xxx (for private module developed by the third party)

module-<TYPE>-<SPECIFICS>

Prerequisites

Creating a Plugin

To create a new Rubix OS module (plugin), start by running the following command,

go mod init github.com/NubeIO/<module-name>

This command initializes a new Go module with the specified module path. The module path follows the URL- similar to syntax and should be unique. Once executed, a go.mod file will be created, and you can add necessary dependencies.

Managing Dependencies

Adding a dependency to your Go module is as simple as importing the desired package in your code. Go modules will automatically detect and manage the dependency.

To add a new dependency, run the following command in your project's directory:

go get <package-name>

This command downloads the specified package and adds it to your go.mod file, along with its version. If you want to use a specific version of the package, you can append @<version> to the package name.

Rubix OS as Dependency

rubix-os is one of the major dependencies that needs to be added to all modules. Follow the following command to add rubix-os:

go get github.com/NubeIO/rubix-os

Additionally, if you want to use a local version of rubix-os, use the following command to point to the local rubix-os:

go mod edit -replace github.com/NubeIO/rubix-os=/<path-to>/rubix-os

Plugin System Over RPC

A plugin system over RPC allows users separate or extend the core functionality of the Rubix OS. With this system, a plugin must adhere to the pre-defined interface, and the main application can communicate with plugins using RPC.

Installation

go-plugin by HashiCorp is used to build a plugin system over RPC. To add this package follow the following command:

go get github.com/hashicorp/go-plugin

Implement the Interface

Create plugin implementations that satisfy the interface requirements by going through the following steps:

1. Define a struct

Each plugin will need to define a struct that implements the interface methods. For example, in above mentioned module Example, we've defined struct Module as follows:

// ./pkg/module.go

type Module struct {
dbHelper shared.DBHelper
moduleName string
grpcMarshaller shared.Marshaller
config *Config
store *cache.Cache
}

2. Add Necessary Implementation

Following pre-defined methods needs to be implemented by previously defined struct,

  • ValidateAndSetConfig
  • Init
  • Enable
  • Disable
  • GetInfo
  • Get
  • Post
  • Put
  • Patch
  • Delete

NOTE: Refer to Example for a reference.

Serve the Plugin

Finally, call plugin.Serve to serve a plugin from the main function.

API

http://0.0.0.0:1660/api/modules/MODULE NAME/END POINT

example

http://0.0.0.0:1660/api/modules/module-core-modbus/schema/json/network
// main.go

func ServePlugin() {
plugin.Serve(&plugin.ServeConfig{
HandshakeConfig: shared.HandshakeConfig,
Plugins: plugin.PluginSet{"module-core-system": &shared.NubeModule{Impl: &pkg.Module{}}},
GRPCServer: plugin.DefaultGRPCServer,
})
}

func main() {
ServePlugin()
}

NOTE: shared.NubeModule is the interface provided by rubix-os that an author struct Module needs to implement.

Logging with Logrus

Logrus is used to log necessary information which is crucial for tackling any issues.

Installation

To get started with Logrus, use the following command to install the package:

go get github.com/sirupsen/logrus

Configuration

Logrus can be configured by passing required arguments to their pre-defined methods. rubix-os requires only two configurations which are as follows,

log.SetFormatter(&log.TextFormatter{
DisableTimestamp: true,
})
log.SetLevel(<log-level>)

Here, the <log-level> is extracted from an argument passed to the ValidateAndSetConfig method of the plugin interface. As logrus's SetLevel method takes pre-defined logrus log level constant, you may need to parse the extracted log level value coming in an argument.

func (m *Module) ValidateAndSetConfig(config []byte) ([]byte, error) {
newConfig := DefaultConfig()
_ = yaml.Unmarshal(config, newConfig)

logLevel, err := log.ParseLevel(newConfig.LogLevel)
if err != nil {
logLevel = log.ErrorLevel
}
logger.SetLevel(logLevel)
}

Build the Plugin

Finally, use the following command to build the module:

go build -o <module-name>

add in the build in the modules dir and restart rubix-os

/home/user/rubix-os/data/modules

Proto

https://github.com/NubeIO/rubix-os#update-proto