add parallelism [pre] section run before all other | update readme accordingly
This commit is contained in:
parent
5fd41cae67
commit
a6207e0a34
12
README.md
12
README.md
|
@ -235,17 +235,13 @@ $ nix-amer -p apt-get myserver.build
|
|||
_myserver.build_
|
||||
|
||||
```
|
||||
[ comment starts with opening brackets '['
|
||||
|
||||
[aliases]
|
||||
alias sshd /etc/ssh/sshd_config
|
||||
# [pre] is executed before launching everything else
|
||||
[pre]
|
||||
install nginx ssh sslh
|
||||
alias nginx /etc/nginx/nginx.conf
|
||||
alias sshd /etc/ssh/sshd_config
|
||||
alias sslh /etc/default/sslh
|
||||
|
||||
[install packages]
|
||||
install nginx ssh
|
||||
install sslh
|
||||
|
||||
[nginx]
|
||||
set nginx@http.gzip off
|
||||
service enable nginx
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -125,10 +126,18 @@ func (r *Reader) Execute() error {
|
|||
// return fmt.Errorf("cannot upgrade | %s", err)
|
||||
// }
|
||||
refresh := make(chan bool, 1)
|
||||
wg := new(sync.WaitGroup)
|
||||
wgstatus := new(sync.WaitGroup)
|
||||
|
||||
// 1. create status table
|
||||
// 1. create status table + extract [pre] section if one
|
||||
table := make([]tableSection, 0)
|
||||
index := make(map[string]int, 0)
|
||||
|
||||
var pre *[]instruction.T = nil
|
||||
var preTable *tableSection = nil
|
||||
|
||||
for secname, sec := range r.Content {
|
||||
|
||||
tableSec := tableSection{
|
||||
name: secname,
|
||||
instructions: make([]execStatus, len(*sec), len(*sec)+1),
|
||||
|
@ -137,39 +146,69 @@ func (r *Reader) Execute() error {
|
|||
// for each instruction
|
||||
for i, inst := range *sec {
|
||||
tableSec.instructions[i].name = inst.Raw()
|
||||
tableSec.instructions[i].start = time.Now()
|
||||
}
|
||||
|
||||
table = append(table, tableSec)
|
||||
go execSection(sec, *r.Context, refresh, &table[len(table)-1])
|
||||
index[secname] = len(table) - 1
|
||||
|
||||
// [pre] section
|
||||
if secname == "pre" {
|
||||
pre = sec
|
||||
preTable = &tableSec
|
||||
}
|
||||
|
||||
// add one section
|
||||
wg.Add(len(*sec))
|
||||
|
||||
}
|
||||
|
||||
// 2. create status updater
|
||||
go status(refresh, table)
|
||||
time.Sleep(time.Second * 10)
|
||||
// 2. launch status updater
|
||||
wgstatus.Add(1)
|
||||
go status(table, refresh, wgstatus)
|
||||
|
||||
// 3. launch [pre] (it set)
|
||||
if pre != nil {
|
||||
execSection(pre, *r.Context, preTable, refresh, wg)
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
|
||||
// 4. launch each other section
|
||||
for secname, sec := range r.Content {
|
||||
// do not launch pre again
|
||||
if secname == "pre" {
|
||||
continue
|
||||
}
|
||||
i, ok := index[secname]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
go execSection(sec, *r.Context, &table[i], refresh, wg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
close(refresh)
|
||||
wgstatus.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func execSection(section *[]instruction.T, ctx instruction.ExecutionContext, refresher chan<- bool, tsec *tableSection) {
|
||||
func execSection(section *[]instruction.T, ctx instruction.ExecutionContext, tsec *tableSection, refresher chan<- bool, wg *sync.WaitGroup) {
|
||||
|
||||
for i, inst := range *section {
|
||||
tsec.instructions[i].start = time.Now()
|
||||
_, err := inst.Exec(ctx)
|
||||
tsec.instructions[i].stop = time.Now()
|
||||
tsec.instructions[i].stopped = true
|
||||
tsec.instructions[i].err = err
|
||||
refresher <- true
|
||||
wg.Done()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func status(refresher chan bool, table []tableSection) {
|
||||
fmt.Printf("status\n")
|
||||
remain := false
|
||||
func status(table []tableSection, refresher <-chan bool, wg *sync.WaitGroup) {
|
||||
|
||||
for <-refresher {
|
||||
for opened := true; true; _, opened = <-refresher {
|
||||
|
||||
// 1. clean screen
|
||||
fmt.Printf("\033[H\033[2J")
|
||||
|
@ -185,7 +224,6 @@ func status(refresher chan bool, table []tableSection) {
|
|||
if !inst.stopped {
|
||||
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.name)))
|
||||
fmt.Printf("%s\n", clifmt.Color(33, "processing"))
|
||||
remain = true
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -201,11 +239,12 @@ func status(refresher chan bool, table []tableSection) {
|
|||
}
|
||||
}
|
||||
|
||||
// 4. close refresher if no remaining task
|
||||
if !remain {
|
||||
if !opened {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue