iotz
Version:
a containerized cross compiler box for arduino, arm mbed, espressif, micro-python, raspberry pi and ... more
129 lines (106 loc) • 6.08 kB
Markdown
**iotz**, brings a `Ubuntu` base image with most common dependencies are pre-installed.
That image is named/tagged as `azureiot/iotz`.
In order to explain things easier, lets assume that we want to develop an application for `Arduino Uno`
board using Arduino toolchain. In order to setup the environment, `iotz` expects us to execute `iotz init arduino uno`
under the project folder.
Once we do that, **iotz** will call `createExtension` function from `iotz` Arduino extension.
That function returns a set of docker specific commands to create a specialized arduino base container.
Eventually, we will find the container named as `azureiot/iotz_local_arduino`.
This specialized container image (fork from the base image) has all the necessary tools to compile an Arduino project.
_Initial creation process for extension image may take time. However, it happens once (unless you force update them)._
Lets step back for a second and talk more about `iotz init arduino uno` call we made.
Assuming, we executed that command under a project folder located at `pre_folder/app_folder/` path.
On the file system, that path has a unique id / inode number (locally unique).
**iotz** uses that unique id to create specific image for that folder only. (image is based on arduino base image)
If unique id for `pre_folder/app_folder/` path was `8595881942`, the final image name would be `aiot_iotz_8595881942`.
_Unless you list the docker container list manually, all the things mentioned above won't be visible to you._
Later calls to iotz (under the same path) will always resolve under the same container.
i.e. `iotz connect` under the same path will simply mount `pre_folder` on the same container named `aiot_iotz_8595881942`.
However, it will put you on the shell under the `pre_folder/app_folder` instead.
Mount location is predefined to `../<current path>` but the actual work path and unique id are set based on current path.
_please note; the path approach mentioned above is premature and will be configurable to suit more needs_
During the `init` step, `iotz` gathered everything it needs to setup the environment.
We have a configuration file that has been filled by `iotz` (iotz.json). So,
next time, we may just call `iotz init` and it will grab the rest from that file.
Finally, `iotz` created a specialized Docker image that is bound to our project folder (`aiot_iotz_8595881942`).
As a last step, we will execute `iotz compile`. *iotz* will gather the `compile`
related set of commands from the Arduino extension and execute them on `aiot_iotz_8595881942`.
That's it!
Details for the extension template is given below.
_reminder; By default, iotz searches the extension under the official extensions_
_folder and then tries to require blindly. So, if you have published your iotz_
_extension to npm, the user should install that extension globally to make it available to iotz_
```
// meaning for some of the arguments below
// runCmd -> args after the command. i.e. -> iotz init mbed mxchip. -> runCmd == 'mbed mxchip'
// command -> the command itself. i.e. -> iotz init mbed mxchip -> command is 'init'
// project_path -> pwd (current path)
exports.detectProject = function(project_path, runCmd, command) {
// return config file json or null based on whether the project on `project_path` is a
// match to extension. If multiple extensions returns with a configuration. User has to set the
// correct extension manually
}
// adds additional commands to local container project
// i.e. user already has a config file (iotz.json) on the current path with toolchain defined
exports.addFeatures = function(config, runCmd, command, compile_path) {
if (command == "??????????") {
return {
run: "...", // commands to run
calllback: null, // callback after exec
commitChanges: false // update container with the changes. `run` must have docker commands
}
}
}
exports.selfCall = function(config, runCmd, command, compile_path) {
// define the behavior for a named call
// i.e. your extension name is `abc`
// user might call `iotz abc`
// what bash command you want to execute on the container?
// check what we do with arduino, mbed, and raspberry-pi
}
exports.createExtension = function() {
// what bash command you want to run on the container to prepare the environment
// for your extension?
return {
run: // commands to run under Dockerfile
callback: function()... optional callback to run after container is created
commitChanges: false // update container with the changes. `run` must have docker commands
}
}
exports.buildCommands = function(config, runCmd, command, compile_path, mount_path) {
var callback = null;
var runString = "";
// define things to do for `init`, `localFolderContainerConstructer`, `clean`,
// `compile`, and `export` commands
// set bash stuff into `runString`
// if you want to run any additional post init logic, set the callback = function(config)
// `config` corresponds to `iotz.json` contents
if (command == 'init') {
// set init stuff here
} else if (command == 'localFolderContainerConstructer') {
// set localFolderContainerConstructer things here.
// difference between `localFolderContainerConstructer` and `init` is.. `init` is a user command
// `localFolderContainerConstructer` will be called no matter what and will be called
// prior to `init`
} else if (command == 'clean') {
// set what to do for `clean`
} else if (command == 'compile') {
// things for `compile`
} else if (command == 'export') {
// things for `export`
} else {
console.error(" -", colors.bold("error :"),
"Unknown command", command);
process.exit(1);
}
return {
run: runString,
callback: callback,
commitChanges: false // update container with the changes. `run` must have docker commands
};
}
exports.createProject = function createProject(compile_path, runCmd) {
// create an empty project based on the information provided by user
}
```