Skip to content

Commit

Permalink
fix busy text file during plugin installation (#929)
Browse files Browse the repository at this point in the history
<!-- markdownlint-disable MD041 -->
#### What this PR does / why we need it

A binary just written cannot be executed while the file is still open
for write (even on Unix).
Therefore, we have to close the file for the plugin executable, before
it can be executed to extract
the plugin descriptor.

#### Which issue(s) this PR fixes
<!--
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
-->
  • Loading branch information
mandelsoft authored Sep 17, 2024
1 parent 2056314 commit de49dd0
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 32 deletions.
3 changes: 2 additions & 1 deletion api/ocm/extensions/repositories/genericocireg/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ func (a *RepositorySpec) IsIntermediate() bool {
// TODO: host etc is missing

func (a *RepositorySpec) AsUniformSpec(cpi.Context) *cpi.UniformRepositorySpec {
return &cpi.UniformRepositorySpec{Type: a.GetKind(), SubPath: a.SubPath}
spec := a.RepositorySpec.UniformRepositorySpec()
return &cpi.UniformRepositorySpec{Type: a.GetKind(), Scheme: spec.Scheme, Host: spec.Host, Info: spec.Info, TypeHint: spec.TypeHint, SubPath: a.SubPath}
}

func (u *RepositorySpec) UnmarshalJSON(data []byte) error {
Expand Down
3 changes: 2 additions & 1 deletion api/ocm/plugin/cache/updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,13 @@ func (o *PluginUpdater) download(session ocm.Session, cv ocm.ComponentVersionAcc
if err != nil {
return errors.Wrapf(err, "cannot create plugin file %s", target)
}
defer dst.Close()
src, err := fs.OpenFile(file.Name(), vfs.O_RDONLY, 0)
if err != nil {
dst.Close()
return errors.Wrapf(err, "cannot open plugin executable %s", file.Name())
}
_, err = io.Copy(dst, src)
dst.Close()
utils.IgnoreError(src.Close())
utils.IgnoreError(os.Remove(file.Name()))
utils.IgnoreError(SetPluginSourceInfo(dir, cv, found.Meta().Name, desc.PluginName))
Expand Down
78 changes: 78 additions & 0 deletions cmds/ocm/commands/ocmcmds/components/get/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const (
COMP = "test.de/x"
COMP2 = "test.de/y"
COMP3 = "test.de/z"
COMP4 = "test.de/c"
COMP5 = "test.de/d"
PROVIDER = "mandelsoft"
)

Expand Down Expand Up @@ -235,4 +237,80 @@ spec:
`, compdescv3.SchemaVersion)))
})
})
Context("ctf", func() {
BeforeEach(func() {
env.OCMCommonTransport(ARCH, accessio.FormatDirectory, func() {
env.Component(COMP, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Reference("yy", COMP2, VERSION)
})
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Reference("zz", COMP3, VERSION)
})
})

env.Component(COMP2, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Reference("aa", COMP4, VERSION)
})
})

env.Component(COMP3, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Reference("cc", COMP4, VERSION)
})
})

env.Component(COMP4, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
env.Reference("dd", COMP5, VERSION)
})
})

env.Component(COMP5, func() {
env.Version(VERSION, func() {
env.Provider(PROVIDER)
})
})
})
})

// TODO: avoid duplicate entries in output
It("lists closure", func() {
buf := bytes.NewBuffer(nil)
Expect(env.CatchOutput(buf).Execute("get", "components", "-r", "--repo", ARCH, COMP)).To(Succeed())
Expect(buf.String()).To(StringEqualTrimmedWithContext(
`
REFERENCEPATH COMPONENT VERSION PROVIDER IDENTITY
test.de/x v1 mandelsoft
test.de/x:v1 test.de/y v1 mandelsoft "name"="yy"
test.de/x:v1->test.de/y:v1 test.de/c v1 mandelsoft "name"="aa"
test.de/x:v1->test.de/y:v1->test.de/c:v1 test.de/d v1 mandelsoft "name"="dd"
test.de/x:v1 test.de/z v1 mandelsoft "name"="zz"
test.de/x:v1->test.de/z:v1 test.de/c v1 mandelsoft "name"="cc"
test.de/x:v1->test.de/z:v1->test.de/c:v1 test.de/d v1 mandelsoft "name"="dd"
`))
})
It("lists closure as tree ", func() {
buf := bytes.NewBuffer(nil)
Expect(env.CatchOutput(buf).Execute("get", "components", "-otree", "-r", "--repo", ARCH, COMP)).To(Succeed())
Expect(buf.String()).To(StringEqualTrimmedWithContext(
`
NESTING COMPONENT VERSION PROVIDER IDENTITY
└─ ⊗ test.de/x v1 mandelsoft
├─ ⊗ test.de/y v1 mandelsoft "name"="yy"
│ └─ ⊗ test.de/c v1 mandelsoft "name"="aa"
│ └─ test.de/d v1 mandelsoft "name"="dd"
└─ ⊗ test.de/z v1 mandelsoft "name"="zz"
└─ ⊗ test.de/c v1 mandelsoft "name"="cc"
└─ test.de/d v1 mandelsoft "name"="dd"
`))
})
})

})
26 changes: 21 additions & 5 deletions cmds/ocm/common/output/treeoutput.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package output

import (
"github.com/mandelsoft/goutils/generics"

"ocm.software/ocm/cmds/ocm/common/data"
"ocm.software/ocm/cmds/ocm/common/processing"
"ocm.software/ocm/cmds/ocm/common/tree"
Expand All @@ -22,9 +24,16 @@ func (f TreeNodeTitleFunc) ApplyTreeOutputOption(o *TreeOutputOptions) {
o.nodeTitle = f
}

type TreeSymbol string

func (s TreeSymbol) ApplyTreeOutputOption(o *TreeOutputOptions) {
o.symbol = generics.Pointer(string(s))
}

type TreeOutputOptions struct {
nodeMapping TreeNodeMappingFunc
nodeTitle TreeNodeTitleFunc
symbol *string
}

func (o TreeOutputOptions) ApplyTreeOutputOption(opts *TreeOutputOptions) {
Expand Down Expand Up @@ -60,18 +69,25 @@ func (o TreeOutputOptions) NodeTitle(obj *tree.TreeObject) string {
func TreeOutput(t *TableOutput, header string, o ...TreeOutputOption) *TableOutput {
opts := *t.Options
opts.FixedColums = 1
topts := TreeOutputOptions{}.Apply(o...)
return &TableOutput{
Headers: Fields(header, t.Headers),
Options: &opts,
Chain: processing.Append(t.Chain, processing.Transform(treeTransform)),
Mapping: treeMapping(len(t.Headers), t.Mapping, TreeOutputOptions{}.Apply(o...)),
Chain: processing.Append(t.Chain, processing.Transform(transformer{topts.symbol}.treeTransform)),
Mapping: treeMapping(len(t.Headers), t.Mapping, topts),
}
}

func treeTransform(s data.Iterable) data.Iterable {
type transformer struct {
symbol *string
}

func (t transformer) treeTransform(s data.Iterable) data.Iterable {
Print(data.Slice(s), "tree transform")
result := tree.MapToTree(tree.ObjectSlice(s), nil)
return result
if t.symbol == nil {
return tree.MapToTree(tree.ObjectSlice(s), nil)
}
return tree.MapToTree(tree.ObjectSlice(s), nil, *t.symbol)
}

func treeMapping(n int, m processing.MappingFunction, opts TreeOutputOptions) processing.MappingFunction {
Expand Down
8 changes: 8 additions & 0 deletions cmds/ocm/common/tree/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ var (
_ data.Iterable = TreeObjects{}
)

func (o TreeObjects) String() string {
s := ""
for _, e := range o {
s += e.String() + "\n"
}
return s
}

func (o TreeObjects) Len() int {
return len(o)
}
Expand Down
23 changes: 23 additions & 0 deletions cmds/ocm/common/tree/tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,16 @@ func Check(t tree.TreeObjects, result string) {

for i, l := range lines {
if i >= min {
fmt.Println(t)
Fail(fmt.Sprintf("additional %d lines expected (%s...)", len(lines)-min, l), 1)
}
if l != t[i].String() {
fmt.Println(t)
Fail(fmt.Sprintf("mismatch of line %d:\nfound: %s\nexpected: %s\n", i+1, t[i].String(), l), 1)
}
}
if min < len(t) {
fmt.Println(t)
Fail(fmt.Sprintf("additional %d lines found in output (%s...)", len(t)-min, t[min]), 1)
}
}
Expand Down Expand Up @@ -123,6 +126,26 @@ var _ = Describe("tree", func() {
└─ a
`)
})

It("composes simple tree with nested elements", func() {
data := []tree.Object{
E("a"),
E("b"),
E("a", "b"),
E("a", "c"),
}

t := tree.MapToTree(data, nil)
Check(t, `
├─ a
├─ b
├─ b
│ └─ a
└─ c
└─ a
`)
})

It("composes simple node tree with nested elements", func() {
data := []tree.Object{
N("a"),
Expand Down
6 changes: 2 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ require (
github.com/klauspost/compress v1.17.9
github.com/klauspost/pgzip v1.2.6
github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3
github.com/mandelsoft/goutils v0.0.0-20240910114310-fc2a9de4c494
github.com/mandelsoft/goutils v0.0.0-20240915132328-95975bffaef0
github.com/mandelsoft/logging v0.0.0-20240618075559-fdca28a87b0a
github.com/mandelsoft/spiff v1.7.0-beta-5
github.com/mandelsoft/vfs v0.4.3
github.com/mandelsoft/vfs v0.4.4-0.20240915223828-8bc9369139c8
github.com/marstr/guid v1.1.0
github.com/mikefarah/yq/v4 v4.44.3
github.com/mitchellh/copystructure v1.2.0
Expand Down Expand Up @@ -205,7 +205,6 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/gomodule/redigo v1.8.9 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/certificate-transparency-go v1.2.1 // indirect
github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 // indirect
Expand Down Expand Up @@ -237,7 +236,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/jinzhu/gorm v1.9.16 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/jmoiron/sqlx v1.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
Expand Down
Loading

0 comments on commit de49dd0

Please sign in to comment.