main function
Show/Hide Function Body
{}
Configuration for system extensions
Provide plugin information as a JSON string
{
plugininfo := &api.PluginInfo{Name: "sysext", Type: api.FinalizePlugin}
pluginjson, err := json.Marshal(plugininfo)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString(string(pluginjson))
}
Provide the plugin scope
{ // int32 is defined as GoInt32 in cgo which is the same as a C int
return api.IMAGENAME | api.FS | api.RECIPE
}
Process and finalize the build by creating an extension release file and
creating a SquashFS image from the filesystem
{
var module *Sysext
var data *api.ScopeData
err := json.Unmarshal([]byte(C.GoString(moduleInterface)), &module)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
err = json.Unmarshal([]byte(C.GoString(extraData)), &data)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
var extensionRelease strings.Builder
fmt.Fprintf(&extensionRelease, "ID=%s\n", module.OSReleaseID)
fmt.Fprintf(&extensionRelease, "VERSION_ID=%s\n", module.OSReleaseVersionID)
err = os.MkdirAll(filepath.Join(data.FS, "usr/lib/extension-release.d"), 0o777)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
err = os.WriteFile(filepath.Join(data.FS, fmt.Sprintf("usr/lib/extension-release.d/extension-release.%s", data.Recipe.Id)), []byte(extensionRelease.String()), 0o777)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
mksquashfs, err := exec.LookPath("mksquashfs")
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
cmd := exec.Command(
mksquashfs, data.FS,
filepath.Join(data.Recipe.ParentPath, fmt.Sprintf("%s.raw", data.Recipe.Id)),
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = data.Recipe.ParentPath
err = cmd.Run()
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString("")
}
{}
Configuration for systemd repartitioning
Provide plugin information as a JSON string
{
plugininfo := &api.PluginInfo{Name: "systemd-repart", Type: api.FinalizePlugin}
pluginjson, err := json.Marshal(plugininfo)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString(string(pluginjson))
}
Provide the plugin scope
{ // int32 is defined as GoInt32 in cgo which is the same as a C int
return api.IMAGENAME | api.FS | api.RECIPE
}
Finalize the build by executing systemd-repart with the provided configuration
to generate and apply partitioning specifications and output results
{
var module *SystemdRepart
var data *api.ScopeData
err := json.Unmarshal([]byte(C.GoString(moduleInterface)), &module)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
err = json.Unmarshal([]byte(C.GoString(extraData)), &data)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
repart, err := exec.LookPath("systemd-repart")
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
if len(strings.TrimSpace(module.Json)) == 0 {
module.Json = "off"
}
args := []string{
"--definitions=definitions",
"--empty=create",
fmt.Sprintf("--size=%s", module.Size),
"--dry-run=no",
"--discard=no",
"--offline=true",
"--no-pager",
fmt.Sprintf("--split=%t", module.Split),
fmt.Sprintf("--seed=%s", module.Seed),
fmt.Sprintf("--root=%s", data.FS),
module.Output,
fmt.Sprintf("--json=%s", module.Json),
}
if len(module.DeferPartitions) > 0 {
args = append(args, fmt.Sprintf("--defer-partitions=%s", strings.Join(module.DeferPartitions, ",")))
}
cmd := exec.Command(
repart,
args...,
)
jsonFile, err := os.Create(module.SpecOutput)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
defer jsonFile.Close()
cmd.Stdout = jsonFile
cmd.Stderr = os.Stderr
cmd.Dir = data.Recipe.ParentPath
err = cmd.Run()
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString("")
}
{}
Configuration for generating an image
Provide plugin information as a JSON string
{
plugininfo := &api.PluginInfo{Name: "genimage", Type: api.FinalizePlugin}
pluginjson, err := json.Marshal(plugininfo)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString(string(pluginjson))
}
Provide the plugin scope
{ // int32 is defined as GoInt32 in cgo which is the same as a C int
return api.IMAGENAME | api.FS | api.RECIPE
}
Replace placeholders in the path with actual values from ScopeData
$PROJROOT -> Recipe.ParentPath
$FSROOT -> FS
{
path = strings.Replace(path, "$PROJROOT", data.Recipe.ParentPath, 1)
path = strings.Replace(path, "$FSROOT", data.FS, 1)
return path
}
Complete the build process for a generated image module.
Find the binary if not specified, replace path placeholders
in the module paths, and run the command
with the provided configuration
{
var module *Genimage
var data *api.ScopeData
err := json.Unmarshal([]byte(C.GoString(moduleInterface)), &module)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
err = json.Unmarshal([]byte(C.GoString(extraData)), &data)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
genimage := module.GenimagePath
if genimage == "" {
genimage, err = exec.LookPath("genimage")
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
}
cmd := exec.Command(
genimage,
"--config",
ParsePath(module.Config, data),
"--rootpath",
ParsePath(module.Rootpath, data),
"--outputpath",
ParsePath(module.Outputpath, data),
"--inputpath",
ParsePath(module.Inputpath, data),
)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = data.Recipe.ParentPath
err = cmd.Run()
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString("")
}
{}
Configuration for a set of shell commands
Provide plugin information as a JSON string
{
plugininfo := &api.PluginInfo{Name: "shell-final", Type: api.FinalizePlugin}
pluginjson, err := json.Marshal(plugininfo)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
return C.CString(string(pluginjson))
}
Provide the plugin scope
{ // int32 is defined as GoInt32 in cgo which is the same as a C int
return api.IMAGENAME | api.FS | api.RECIPE
}
Replace placeholders in the path with actual values from ScopeData
$PROJROOT -> Recipe.ParentPath
$FSROOT -> FS
{
path = strings.ReplaceAll(path, "$PROJROOT", data.Recipe.ParentPath)
path = strings.ReplaceAll(path, "$FSROOT", data.FS)
return path
}
Check if the command is in $PATH or includes a directory path.
Return the full path if found, otherwise return the command unchanged.
{
commandParts := strings.Split(command, " ")
if strings.Contains(commandParts[0], "/") {
return parsePath(commandParts[0], data)
} else {
command, err := exec.LookPath(commandParts[0])
if err != nil {
return commandParts[0]
}
return command
}
}
Extract and return arguments from a command string
{
commandParts := strings.Split(parsePath(command, data), " ")
return commandParts[1:]
}
Generate an executable command by resolving the base command and arguments
and wrapping them with appropriate syntax for execution.
{
baseCommand := baseCommand(command, data)
args := getArgs(command, data)
return append(append(append([]string{"-c", "'"}, strings.Join(args, " ")), baseCommand), "'")
}
Execute shell commands from a Shell struct using the provided ScopeData.
It parses and runs each command in the context of the provided working directory,
or the recipe's parent path if no specific directory is given.
{
var module *Shell
var data *api.ScopeData
err := json.Unmarshal([]byte(C.GoString(moduleInterface)), &module)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
err = json.Unmarshal([]byte(C.GoString(extraData)), &data)
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
for _, command := range module.Commands {
fmt.Println("shell-final:: bash ", "-c ", command)
cmd := exec.Command(
"bash", "-c", parsePath(command, data),
)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = os.Environ()
if len(strings.TrimSpace(module.Cwd)) == 0 {
cmd.Dir = data.Recipe.ParentPath
} else {
cmd.Dir = parsePath(module.Cwd, data)
}
err = cmd.Run()
if err != nil {
return C.CString(fmt.Sprintf("ERROR: %s", err.Error()))
}
}
return C.CString("")
}
{}
import "C"
import "encoding/json"
import "fmt"
import "os"
import "os/exec"
import "path/filepath"
import "strings"
import "github.com/vanilla-os/vib/api"
import "C"
import "encoding/json"
import "fmt"
import "github.com/vanilla-os/vib/api"
import "os"
import "os/exec"
import "strings"
import "C"
import "encoding/json"
import "fmt"
import "github.com/vanilla-os/vib/api"
import "os"
import "os/exec"
import "strings"
import "C"
import "encoding/json"
import "fmt"
import "github.com/vanilla-os/vib/api"
import "os"
import "os/exec"
import "strings"