prompt-less signing via passphrase file

To support signing images without prompting the user, add CLI flags for
providing a passphrase file.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2022-01-20 11:55:23 +01:00
parent 639aabbaf3
commit bb49923af4
95 changed files with 3369 additions and 191 deletions

View File

@@ -5,7 +5,6 @@ import (
"context"
"fmt"
"io"
"log"
"runtime/debug"
"strings"
"sync"
@@ -36,7 +35,6 @@ type Bar struct {
cacheState *bState
container *Progress
dlogger *log.Logger
recoveredPanic interface{}
}
@@ -64,7 +62,7 @@ type bState struct {
averageDecorators []decor.AverageDecorator
ewmaDecorators []decor.EwmaDecorator
shutdownListeners []decor.ShutdownListener
bufP, bufB, bufA *bytes.Buffer
buffers [3]*bytes.Buffer
filler BarFiller
middleware func(BarFiller) BarFiller
extender extenderFunc
@@ -81,7 +79,6 @@ type frame struct {
}
func newBar(container *Progress, bs *bState) *Bar {
logPrefix := fmt.Sprintf("%sbar#%02d ", container.dlogger.Prefix(), bs.id)
ctx, cancel := context.WithCancel(container.ctx)
bar := &Bar{
@@ -93,7 +90,6 @@ func newBar(container *Progress, bs *bState) *Bar {
frameCh: make(chan *frame, 1),
done: make(chan struct{}),
cancel: cancel,
dlogger: log.New(bs.debugOut, logPrefix, log.Lshortfile),
}
go bar.serve(ctx, bs)
@@ -106,7 +102,7 @@ func (b *Bar) ProxyReader(r io.Reader) io.ReadCloser {
if r == nil {
panic("expected non nil io.Reader")
}
return newProxyReader(r, b)
return b.newProxyReader(r)
}
// ID returs id of the bar.
@@ -279,7 +275,7 @@ func (b *Bar) Abort(drop bool) {
done := make(chan struct{})
select {
case b.operateState <- func(s *bState) {
if s.completed == true {
if s.completed {
close(done)
return
}
@@ -346,13 +342,16 @@ func (b *Bar) render(tw int) {
// recovering if user defined decorator panics for example
if p := recover(); p != nil {
if b.recoveredPanic == nil {
if s.debugOut != nil {
fmt.Fprintln(s.debugOut, p)
_, _ = s.debugOut.Write(debug.Stack())
}
s.extender = makePanicExtender(p)
b.toShutdown = !b.toShutdown
b.recoveredPanic = p
}
reader, lines := s.extender(nil, s.reqWidth, stat)
b.frameCh <- &frame{reader, lines + 1}
b.dlogger.Println(p)
}
s.completeFlushed = s.completed
}()
@@ -429,40 +428,41 @@ func (b *Bar) wSyncTable() [][]chan int {
}
func (s *bState) draw(stat decor.Statistics) io.Reader {
bufP, bufB, bufA := s.buffers[0], s.buffers[1], s.buffers[2]
nlr := strings.NewReader("\n")
tw := stat.AvailableWidth
for _, d := range s.pDecorators {
str := d.Decor(stat)
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
s.bufP.WriteString(str)
bufP.WriteString(str)
}
if stat.AvailableWidth < 1 {
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufP.String()), tw, "…"))
s.bufP.Reset()
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufP.String()), tw, "…"))
bufP.Reset()
return io.MultiReader(trunc, nlr)
}
if !s.trimSpace && stat.AvailableWidth > 1 {
stat.AvailableWidth -= 2
s.bufB.WriteByte(' ')
defer s.bufB.WriteByte(' ')
bufB.WriteByte(' ')
defer bufB.WriteByte(' ')
}
tw = stat.AvailableWidth
for _, d := range s.aDecorators {
str := d.Decor(stat)
stat.AvailableWidth -= runewidth.StringWidth(stripansi.Strip(str))
s.bufA.WriteString(str)
bufA.WriteString(str)
}
if stat.AvailableWidth < 1 {
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(s.bufA.String()), tw, "…"))
s.bufA.Reset()
return io.MultiReader(s.bufP, s.bufB, trunc, nlr)
trunc := strings.NewReader(runewidth.Truncate(stripansi.Strip(bufA.String()), tw, "…"))
bufA.Reset()
return io.MultiReader(bufP, bufB, trunc, nlr)
}
s.filler.Fill(s.bufB, s.reqWidth, stat)
s.filler.Fill(bufB, s.reqWidth, stat)
return io.MultiReader(s.bufP, s.bufB, s.bufA, nlr)
return io.MultiReader(bufP, bufB, bufA, nlr)
}
func (s *bState) wSyncTable() [][]chan int {
@@ -489,39 +489,51 @@ func (s *bState) wSyncTable() [][]chan int {
func (s bState) decoratorEwmaUpdate(dur time.Duration) {
wg := new(sync.WaitGroup)
wg.Add(len(s.ewmaDecorators))
for _, d := range s.ewmaDecorators {
d := d
go func() {
for i := 0; i < len(s.ewmaDecorators); i++ {
switch d := s.ewmaDecorators[i]; i {
case len(s.ewmaDecorators) - 1:
d.EwmaUpdate(s.lastIncrement, dur)
wg.Done()
}()
default:
wg.Add(1)
go func() {
d.EwmaUpdate(s.lastIncrement, dur)
wg.Done()
}()
}
}
wg.Wait()
}
func (s bState) decoratorAverageAdjust(start time.Time) {
wg := new(sync.WaitGroup)
wg.Add(len(s.averageDecorators))
for _, d := range s.averageDecorators {
d := d
go func() {
for i := 0; i < len(s.averageDecorators); i++ {
switch d := s.averageDecorators[i]; i {
case len(s.averageDecorators) - 1:
d.AverageAdjust(start)
wg.Done()
}()
default:
wg.Add(1)
go func() {
d.AverageAdjust(start)
wg.Done()
}()
}
}
wg.Wait()
}
func (s bState) decoratorShutdownNotify() {
wg := new(sync.WaitGroup)
wg.Add(len(s.shutdownListeners))
for _, d := range s.shutdownListeners {
d := d
go func() {
for i := 0; i < len(s.shutdownListeners); i++ {
switch d := s.shutdownListeners[i]; i {
case len(s.shutdownListeners) - 1:
d.Shutdown()
wg.Done()
}()
default:
wg.Add(1)
go func() {
d.Shutdown()
wg.Done()
}()
}
}
wg.Wait()
}
@@ -547,14 +559,11 @@ func extractBaseDecorator(d decor.Decorator) decor.Decorator {
func makePanicExtender(p interface{}) extenderFunc {
pstr := fmt.Sprint(p)
stack := debug.Stack()
stackLines := bytes.Count(stack, []byte("\n"))
return func(_ io.Reader, _ int, st decor.Statistics) (io.Reader, int) {
mr := io.MultiReader(
strings.NewReader(runewidth.Truncate(pstr, st.AvailableWidth, "…")),
strings.NewReader(fmt.Sprintf("\n%#v\n", st)),
bytes.NewReader(stack),
strings.NewReader("\n"),
)
return mr, stackLines + 1
return mr, 0
}
}

View File

@@ -32,13 +32,13 @@ type BarStyleComposer interface {
}
type bFiller struct {
rev bool
components [components]*component
tip struct {
count uint
onComplete *component
frames []*component
}
flush func(dst io.Writer, filling, padding [][]byte)
}
type component struct {
@@ -113,14 +113,7 @@ func (s *barStyle) Reverse() BarStyleComposer {
}
func (s *barStyle) Build() BarFiller {
bf := new(bFiller)
if s.rev {
bf.flush = func(dst io.Writer, filling, padding [][]byte) {
flush(dst, padding, filling)
}
} else {
bf.flush = flush
}
bf := &bFiller{rev: s.rev}
bf.components[iLbound] = &component{
width: runewidth.StringWidth(stripansi.Strip(s.lbound)),
bytes: []byte(s.lbound),
@@ -164,8 +157,9 @@ func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
return
}
w.Write(s.components[iLbound].bytes)
defer w.Write(s.components[iRbound].bytes)
ow := optimisticWriter(w)
ow(s.components[iLbound].bytes)
defer ow(s.components[iRbound].bytes)
if width == 0 {
return
@@ -236,14 +230,27 @@ func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
}
}
s.flush(w, filling, padding)
if s.rev {
flush(ow, padding, filling)
} else {
flush(ow, filling, padding)
}
}
func flush(dst io.Writer, filling, padding [][]byte) {
func flush(ow func([]byte), filling, padding [][]byte) {
for i := len(filling) - 1; i >= 0; i-- {
dst.Write(filling[i])
ow(filling[i])
}
for i := 0; i < len(padding); i++ {
dst.Write(padding[i])
ow(padding[i])
}
}
func optimisticWriter(w io.Writer) func([]byte) {
return func(p []byte) {
_, err := w.Write(p)
if err != nil {
panic(err)
}
}
}

View File

@@ -73,15 +73,19 @@ func (s *sFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
return
}
var err error
rest := width - frameWidth
switch s.position {
case positionLeft:
io.WriteString(w, frame+strings.Repeat(" ", rest))
_, err = io.WriteString(w, frame+strings.Repeat(" ", rest))
case positionRight:
io.WriteString(w, strings.Repeat(" ", rest)+frame)
_, err = io.WriteString(w, strings.Repeat(" ", rest)+frame)
default:
str := strings.Repeat(" ", rest/2) + frame + strings.Repeat(" ", rest/2+rest%2)
io.WriteString(w, str)
_, err = io.WriteString(w, str)
}
if err != nil {
panic(err)
}
s.count++
}

View File

@@ -89,7 +89,10 @@ func BarFillerOnComplete(message string) BarOption {
return BarFillerMiddleware(func(base BarFiller) BarFiller {
return BarFillerFunc(func(w io.Writer, reqWidth int, st decor.Statistics) {
if st.Completed {
io.WriteString(w, message)
_, err := io.WriteString(w, message)
if err != nil {
panic(err)
}
} else {
base.Fill(w, reqWidth, st)
}

View File

@@ -76,9 +76,9 @@ func (w *Writer) GetWidth() (int, error) {
return tw, err
}
func (w *Writer) ansiCuuAndEd() (err error) {
func (w *Writer) ansiCuuAndEd() error {
buf := make([]byte, 8)
buf = strconv.AppendInt(buf[:copy(buf, escOpen)], int64(w.lines), 10)
_, err = w.out.Write(append(buf, cuuAndEd...))
return
_, err := w.out.Write(append(buf, cuuAndEd...))
return err
}

View File

@@ -0,0 +1,12 @@
package decor
import "io"
func optimisticStringWriter(w io.Writer) func(string) {
return func(s string) {
_, err := io.WriteString(w, s)
if err != nil {
panic(err)
}
}
}

View File

@@ -2,7 +2,6 @@ package decor
import (
"fmt"
"io"
"strconv"
"github.com/vbauerster/mpb/v7/internal"
@@ -24,12 +23,12 @@ func (s percentageType) Format(st fmt.State, verb rune) {
}
}
io.WriteString(st, strconv.FormatFloat(float64(s), 'f', prec, 64))
osw := optimisticStringWriter(st)
osw(strconv.FormatFloat(float64(s), 'f', prec, 64))
if st.Flag(' ') {
io.WriteString(st, " ")
osw(" ")
}
io.WriteString(st, "%")
osw("%")
}
// Percentage returns percentage decorator. It's a wrapper of NewPercentage.

View File

@@ -2,8 +2,6 @@ package decor
import (
"fmt"
"io"
"math"
"strconv"
)
@@ -47,16 +45,16 @@ func (self SizeB1024) Format(st fmt.State, verb rune) {
unit = _iMiB
case self < _iTiB:
unit = _iGiB
case self <= math.MaxInt64:
default:
unit = _iTiB
}
io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
osw := optimisticStringWriter(st)
osw(strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
if st.Flag(' ') {
io.WriteString(st, " ")
osw(" ")
}
io.WriteString(st, unit.String())
osw(unit.String())
}
const (
@@ -96,14 +94,14 @@ func (self SizeB1000) Format(st fmt.State, verb rune) {
unit = _MB
case self < _TB:
unit = _GB
case self <= math.MaxInt64:
default:
unit = _TB
}
io.WriteString(st, strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
osw := optimisticStringWriter(st)
osw(strconv.FormatFloat(float64(self)/float64(unit), 'f', prec, 64))
if st.Flag(' ') {
io.WriteString(st, " ")
osw(" ")
}
io.WriteString(st, unit.String())
osw(unit.String())
}

View File

@@ -2,7 +2,6 @@ package decor
import (
"fmt"
"io"
"math"
"time"
@@ -24,7 +23,7 @@ type speedFormatter struct {
func (self *speedFormatter) Format(st fmt.State, verb rune) {
self.Formatter.Format(st, verb)
io.WriteString(st, "/s")
optimisticStringWriter(st)("/s")
}
// EwmaSpeed exponential-weighted-moving-average based speed decorator.

View File

@@ -4,7 +4,7 @@ require (
github.com/VividCortex/ewma v1.2.0
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/mattn/go-runewidth v0.0.13
golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
)
go 1.14

View File

@@ -6,5 +6,5 @@ github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d h1:1oIt9o40TWWI9FUaveVpUvBe13FNqBNVXy3ue2fcfkw=
golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

View File

@@ -6,8 +6,6 @@ import (
"context"
"fmt"
"io"
"io/ioutil"
"log"
"math"
"os"
"sync"
@@ -33,7 +31,6 @@ type Progress struct {
done chan struct{}
refreshCh chan time.Time
once sync.Once
dlogger *log.Logger
}
// pState holds bars in its priorityQueue. It gets passed to
@@ -75,7 +72,6 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
rr: prr,
parkedBars: make(map[*Bar]*Bar),
output: os.Stdout,
debugOut: ioutil.Discard,
}
for _, opt := range options {
@@ -91,7 +87,6 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress {
bwg: new(sync.WaitGroup),
operateState: make(chan func(*pState)),
done: make(chan struct{}),
dlogger: log.New(s.debugOut, "[mpb] ", log.Lshortfile),
}
p.cwg.Add(1)
@@ -234,12 +229,26 @@ func (p *Progress) serve(s *pState, cw *cwriter.Writer) {
op(s)
case <-p.refreshCh:
if err := s.render(cw); err != nil {
p.dlogger.Println(err)
if s.debugOut != nil {
_, e := fmt.Fprintln(s.debugOut, err)
if e != nil {
panic(err)
}
} else {
panic(err)
}
}
case <-s.shutdownNotifier:
for s.heapUpdated {
if err := s.render(cw); err != nil {
p.dlogger.Println(err)
if s.debugOut != nil {
_, e := fmt.Fprintln(s.debugOut, err)
if e != nil {
panic(err)
}
} else {
panic(err)
}
}
}
return
@@ -311,7 +320,10 @@ func (s *pState) flush(cw *cwriter.Writer) error {
for s.bHeap.Len() > 0 {
b := heap.Pop(&s.bHeap).(*Bar)
frame := <-b.frameCh
cw.ReadFrom(frame.reader)
_, err := cw.ReadFrom(frame.reader)
if err != nil {
return err
}
if b.toShutdown {
if b.recoveredPanic != nil {
s.barShutdownQueue = append(s.barShutdownQueue, b)
@@ -402,9 +414,9 @@ func (s *pState) makeBarState(total int64, filler BarFiller, options ...BarOptio
bs.priority = -(math.MaxInt32 - s.idCount)
}
bs.bufP = bytes.NewBuffer(make([]byte, 0, 128))
bs.bufB = bytes.NewBuffer(make([]byte, 0, 256))
bs.bufA = bytes.NewBuffer(make([]byte, 0, 128))
for i := 0; i < len(bs.buffers); i++ {
bs.buffers[i] = bytes.NewBuffer(make([]byte, 0, 512))
}
return bs
}

View File

@@ -11,7 +11,7 @@ type proxyReader struct {
bar *Bar
}
func (x *proxyReader) Read(p []byte) (int, error) {
func (x proxyReader) Read(p []byte) (int, error) {
n, err := x.ReadCloser.Read(p)
x.bar.IncrBy(n)
if err == io.EOF {
@@ -21,12 +21,11 @@ func (x *proxyReader) Read(p []byte) (int, error) {
}
type proxyWriterTo struct {
io.ReadCloser // *proxyReader
wt io.WriterTo
bar *Bar
proxyReader
wt io.WriterTo
}
func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
func (x proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
n, err := x.wt.WriteTo(w)
x.bar.IncrInt64(n)
if err == io.EOF {
@@ -36,13 +35,12 @@ func (x *proxyWriterTo) WriteTo(w io.Writer) (int64, error) {
}
type ewmaProxyReader struct {
io.ReadCloser // *proxyReader
bar *Bar
proxyReader
}
func (x *ewmaProxyReader) Read(p []byte) (int, error) {
func (x ewmaProxyReader) Read(p []byte) (int, error) {
start := time.Now()
n, err := x.ReadCloser.Read(p)
n, err := x.proxyReader.Read(p)
if n > 0 {
x.bar.DecoratorEwmaUpdate(time.Since(start))
}
@@ -50,12 +48,11 @@ func (x *ewmaProxyReader) Read(p []byte) (int, error) {
}
type ewmaProxyWriterTo struct {
io.ReadCloser // *ewmaProxyReader
wt io.WriterTo // *proxyWriterTo
bar *Bar
ewmaProxyReader
wt proxyWriterTo
}
func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
func (x ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
start := time.Now()
n, err := x.wt.WriteTo(w)
if n > 0 {
@@ -64,17 +61,19 @@ func (x *ewmaProxyWriterTo) WriteTo(w io.Writer) (int64, error) {
return n, err
}
func newProxyReader(r io.Reader, bar *Bar) io.ReadCloser {
rc := toReadCloser(r)
rc = &proxyReader{rc, bar}
if wt, isWriterTo := r.(io.WriterTo); bar.hasEwmaDecorators {
rc = &ewmaProxyReader{rc, bar}
if isWriterTo {
rc = &ewmaProxyWriterTo{rc, wt, bar}
func (b *Bar) newProxyReader(r io.Reader) (rc io.ReadCloser) {
pr := proxyReader{toReadCloser(r), b}
if wt, ok := r.(io.WriterTo); ok {
pw := proxyWriterTo{pr, wt}
if b.hasEwmaDecorators {
rc = ewmaProxyWriterTo{ewmaProxyReader{pr}, pw}
} else {
rc = pw
}
} else if isWriterTo {
rc = &proxyWriterTo{rc, wt, bar}
} else if b.hasEwmaDecorators {
rc = ewmaProxyReader{pr}
} else {
rc = pr
}
return rc
}