New command: automatic generate app description
This commit is contained in:
parent
197a78f595
commit
f18d55bd27
16
README.md
16
README.md
@ -7,8 +7,6 @@ Simple application VMs (hypervisor-based sandbox) based on Nix package manager.
|
|||||||
|
|
||||||
Uses one **read-only** /nix directory for all appvms. So creating a new appvm (but not first) is just about one minute.
|
Uses one **read-only** /nix directory for all appvms. So creating a new appvm (but not first) is just about one minute.
|
||||||
|
|
||||||
Currently optimized for full screen usage (but remote-viewer has ability to resize window dynamically without change resolution).
|
|
||||||
|
|
||||||
![appvm screenshot](screenshots/2018-07-05.png)
|
![appvm screenshot](screenshots/2018-07-05.png)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
@ -82,18 +80,8 @@ to crontab like that:
|
|||||||
<nix/base.nix>
|
<nix/base.nix>
|
||||||
];
|
];
|
||||||
|
|
||||||
environment.systemPackages = [ pkgs.chromium ];
|
services.xserver.displayManager.sessionCommands =
|
||||||
services.xserver.displayManager.sessionCommands = "while [ 1 ]; do ${pkgs.chromium}/bin/chromium; done &";
|
"while [ 1 ]; do ${pkgs.chromium}/bin/chromium; done &";
|
||||||
}
|
}
|
||||||
|
|
||||||
For create new app you should add package name (search at https://nixos.org/nixos/packages.html) and path to binary (typically same as package name).
|
For create new app you should add package name (search at https://nixos.org/nixos/packages.html) and path to binary (typically same as package name).
|
||||||
|
|
||||||
## Defined applications (pull requests are welcome!)
|
|
||||||
|
|
||||||
* chromium
|
|
||||||
* thunderbird
|
|
||||||
* tdesktop
|
|
||||||
* evince
|
|
||||||
* libreoffice
|
|
||||||
* wire
|
|
||||||
* torbrowser
|
|
||||||
|
6
appvm.go
6
appvm.go
@ -390,9 +390,15 @@ func main() {
|
|||||||
stopName := kingpin.Command("stop", "Stop application").Arg("name", "Application name").Required().String()
|
stopName := kingpin.Command("stop", "Stop application").Arg("name", "Application name").Required().String()
|
||||||
dropName := kingpin.Command("drop", "Remove application data").Arg("name", "Application name").Required().String()
|
dropName := kingpin.Command("drop", "Remove application data").Arg("name", "Application name").Required().String()
|
||||||
|
|
||||||
|
generateCommand := kingpin.Command("generate", "Generate appvm definition")
|
||||||
|
generateName := generateCommand.Arg("name", "Nix package name").Required().String()
|
||||||
|
generateBin := generateCommand.Arg("bin", "Binary").Default("").String()
|
||||||
|
|
||||||
switch kingpin.Parse() {
|
switch kingpin.Parse() {
|
||||||
case "list":
|
case "list":
|
||||||
list(l)
|
list(l)
|
||||||
|
case "generate":
|
||||||
|
generate(l, *generateName, *generateBin)
|
||||||
case "start":
|
case "start":
|
||||||
start(l, *startName, *startVerbose)
|
start(l, *startName, *startVerbose)
|
||||||
case "stop":
|
case "stop":
|
||||||
|
93
generate.go
Normal file
93
generate.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/digitalocean/go-libvirt"
|
||||||
|
)
|
||||||
|
|
||||||
|
var template = `
|
||||||
|
{pkgs, ...}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
<nixpkgs/nixos/modules/virtualisation/qemu-vm.nix>
|
||||||
|
<nix/base.nix>
|
||||||
|
];
|
||||||
|
|
||||||
|
services.xserver.displayManager.sessionCommands =
|
||||||
|
"while [ 1 ]; do ${pkgs.%s}/bin/%s; done &";
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
func isPackageExists(name string) bool {
|
||||||
|
cmd := exec.Command("nix-env", "-iA", name)
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nixPath(name string) (path string, err error) {
|
||||||
|
command := exec.Command("nix", "path-info", name)
|
||||||
|
bytes, err := command.Output()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
path = string(bytes)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func generate(l *libvirt.Libvirt, name, bin string) {
|
||||||
|
if !isPackageExists(name) {
|
||||||
|
log.Println("Package pkgs."+name, "does not exists")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path, err := nixPath(name)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Cannot find nix path")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path = strings.TrimSpace(path)
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir(path + "/bin/")
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if bin == "" && len(files) != 1 {
|
||||||
|
fmt.Println("There's more than one binary in */bin, " +
|
||||||
|
"you should specify one of them explicitly")
|
||||||
|
fmt.Println("Files in", path+"/bin/:")
|
||||||
|
for _, f := range files {
|
||||||
|
fmt.Println("\t", f.Name())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if bin != "" {
|
||||||
|
var found bool = false
|
||||||
|
for _, f := range files {
|
||||||
|
if bin == f.Name() {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
log.Println("There's no such file in */bin")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bin = files[0].Name()
|
||||||
|
}
|
||||||
|
|
||||||
|
realName := strings.Split(name, ".")[1]
|
||||||
|
|
||||||
|
fmt.Printf(template, realName, bin)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user