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_
|
_myserver.build_
|
||||||
|
|
||||||
```
|
```
|
||||||
[ comment starts with opening brackets '['
|
# [pre] is executed before launching everything else
|
||||||
|
[pre]
|
||||||
[aliases]
|
install nginx ssh sslh
|
||||||
alias sshd /etc/ssh/sshd_config
|
|
||||||
alias nginx /etc/nginx/nginx.conf
|
alias nginx /etc/nginx/nginx.conf
|
||||||
|
alias sshd /etc/ssh/sshd_config
|
||||||
alias sslh /etc/default/sslh
|
alias sslh /etc/default/sslh
|
||||||
|
|
||||||
[install packages]
|
|
||||||
install nginx ssh
|
|
||||||
install sslh
|
|
||||||
|
|
||||||
[nginx]
|
[nginx]
|
||||||
set nginx@http.gzip off
|
set nginx@http.gzip off
|
||||||
service enable nginx
|
service enable nginx
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -125,10 +126,18 @@ func (r *Reader) Execute() error {
|
||||||
// return fmt.Errorf("cannot upgrade | %s", err)
|
// return fmt.Errorf("cannot upgrade | %s", err)
|
||||||
// }
|
// }
|
||||||
refresh := make(chan bool, 1)
|
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)
|
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 {
|
for secname, sec := range r.Content {
|
||||||
|
|
||||||
tableSec := tableSection{
|
tableSec := tableSection{
|
||||||
name: secname,
|
name: secname,
|
||||||
instructions: make([]execStatus, len(*sec), len(*sec)+1),
|
instructions: make([]execStatus, len(*sec), len(*sec)+1),
|
||||||
|
@ -137,39 +146,69 @@ func (r *Reader) Execute() error {
|
||||||
// for each instruction
|
// for each instruction
|
||||||
for i, inst := range *sec {
|
for i, inst := range *sec {
|
||||||
tableSec.instructions[i].name = inst.Raw()
|
tableSec.instructions[i].name = inst.Raw()
|
||||||
tableSec.instructions[i].start = time.Now()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table = append(table, tableSec)
|
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
|
// 2. launch status updater
|
||||||
go status(refresh, table)
|
wgstatus.Add(1)
|
||||||
time.Sleep(time.Second * 10)
|
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)
|
close(refresh)
|
||||||
|
wgstatus.Wait()
|
||||||
|
|
||||||
return nil
|
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 {
|
for i, inst := range *section {
|
||||||
|
tsec.instructions[i].start = time.Now()
|
||||||
_, err := inst.Exec(ctx)
|
_, err := inst.Exec(ctx)
|
||||||
tsec.instructions[i].stop = time.Now()
|
tsec.instructions[i].stop = time.Now()
|
||||||
tsec.instructions[i].stopped = true
|
tsec.instructions[i].stopped = true
|
||||||
tsec.instructions[i].err = err
|
tsec.instructions[i].err = err
|
||||||
refresher <- true
|
refresher <- true
|
||||||
|
wg.Done()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func status(refresher chan bool, table []tableSection) {
|
func status(table []tableSection, refresher <-chan bool, wg *sync.WaitGroup) {
|
||||||
fmt.Printf("status\n")
|
|
||||||
remain := false
|
|
||||||
|
|
||||||
for <-refresher {
|
for opened := true; true; _, opened = <-refresher {
|
||||||
|
|
||||||
// 1. clean screen
|
// 1. clean screen
|
||||||
fmt.Printf("\033[H\033[2J")
|
fmt.Printf("\033[H\033[2J")
|
||||||
|
@ -185,7 +224,6 @@ func status(refresher chan bool, table []tableSection) {
|
||||||
if !inst.stopped {
|
if !inst.stopped {
|
||||||
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.name)))
|
clifmt.Align(fmt.Sprintf("(%d) %s", i, clifmt.Color(0, inst.name)))
|
||||||
fmt.Printf("%s\n", clifmt.Color(33, "processing"))
|
fmt.Printf("%s\n", clifmt.Color(33, "processing"))
|
||||||
remain = true
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,11 +239,12 @@ func status(refresher chan bool, table []tableSection) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. close refresher if no remaining task
|
if !opened {
|
||||||
if !remain {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wg.Done()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue