-
Notifications
You must be signed in to change notification settings - Fork 161
/
parsepatchenvelopes.go
163 lines (137 loc) · 5.04 KB
/
parsepatchenvelopes.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// Copyright (c) 2023 Zededa, Inc.
// SPDX-License-Identifier: Apache-2.0
package zedagent
import (
"encoding/hex"
"fmt"
"crypto/sha256"
zconfig "github.com/lf-edge/eve-api/go/config"
"github.com/lf-edge/eve/pkg/pillar/persistcache"
"github.com/lf-edge/eve/pkg/pillar/types"
"github.com/lf-edge/eve/pkg/pillar/utils/generics"
)
func parsePatchEnvelopes(ctx *getconfigContext, config *zconfig.EdgeDevConfig) {
parsePatchEnvelopesImpl(ctx, config, types.PersistCachePatchEnvelopes)
}
func parsePatchEnvelopesImpl(ctx *getconfigContext, config *zconfig.EdgeDevConfig,
persistCacheFilepath string) {
log.Tracef("Parsing patchEnvelope from configuration")
// Store list of binary blobs which were created before
pc, err := persistcache.New(persistCacheFilepath)
if err != nil {
log.Errorf("Failed to load persistCache %v", err)
return
}
blobsBefore := pc.Objects()
var blobsAfter []string
patchEnvelopes := config.GetPatchEnvelopes()
result := types.PatchEnvelopeInfoList{}
for _, pe := range patchEnvelopes {
peInfo := types.PatchEnvelopeInfo{
AllowedApps: pe.GetAppInstIdsAllowed(),
PatchID: pe.GetUuid(),
Name: pe.GetDisplayName(),
Version: pe.GetVersion(),
State: evePatchEnvelopeActionToState(pe.GetAction()),
}
for _, a := range pe.GetArtifacts() {
err := addBinaryBlobToPatchEnvelope(&peInfo, a, persistCacheFilepath)
if err != nil {
msg := fmt.Sprintf("Failed to compose binary blob for patch envelope %v", err)
peInfo.Errors = append(peInfo.Errors, msg)
log.Errorf(msg)
return
}
}
result.Envelopes = append(result.Envelopes, peInfo)
for _, inlineBlob := range peInfo.BinaryBlobs {
blobsAfter = append(blobsAfter, inlineBlob.FileName)
}
}
publishPatchEnvelopes(ctx, result)
// Provide zedrouter with newest version for description.json and then delete files
blobsToDelete, _ := generics.DiffSets(blobsBefore, blobsAfter)
for _, blob := range blobsToDelete {
pc.Delete(blob)
}
}
func publishPatchEnvelopes(ctx *getconfigContext, patchEnvelopes types.PatchEnvelopeInfoList) {
key := patchEnvelopes.Key()
pub := ctx.pubPatchEnvelopeInfo
pub.Publish(key, patchEnvelopes)
log.Tracef("publishPatchEnvelopes(%s) done\n", key)
}
func addBinaryBlobToPatchEnvelope(pe *types.PatchEnvelopeInfo, artifact *zconfig.EveBinaryArtifact, persistCacheFilepath string) error {
format := artifact.GetFormat()
switch format {
case zconfig.EVE_OPAQUE_OBJECT_CATEGORY_BINARYBLOB:
binaryArtifact := artifact.GetVolumeRef()
if binaryArtifact == nil {
return fmt.Errorf("ExternalOpaqueBinaryBlob is empty, type indicates it should be present")
}
volumeRef, err := getBinaryBlobVolumeRef(binaryArtifact)
if err != nil {
return err
}
volumeRef.ArtifactMetadata = artifact.GetArtifactMetaData()
pe.VolumeRefs = append(pe.VolumeRefs, *volumeRef)
return nil
case zconfig.EVE_OPAQUE_OBJECT_CATEGORY_SECRET:
case zconfig.EVE_OPAQUE_OBJECT_CATEGORY_BASE64:
inlineArtifact := artifact.GetInline()
if inlineArtifact == nil {
return fmt.Errorf("InlineOpaqueBase64data is empty, type indicates it should be present")
}
binaryBlob, err := cacheInlineBase64Artifact(inlineArtifact, persistCacheFilepath)
if err != nil {
return err
}
binaryBlob.ArtifactMetadata = artifact.GetArtifactMetaData()
pe.BinaryBlobs = append(pe.BinaryBlobs, *binaryBlob)
return nil
}
return fmt.Errorf("Unknown EveBinaryArtifact format")
}
// cacheInlineBinaryArtifact stores inline artifact as file and
// returns path to it to be served by HTTP server
func cacheInlineBase64Artifact(artifact *zconfig.InlineOpaqueBase64Data, persistCacheFilepath string) (*types.BinaryBlobCompleted, error) {
pc, err := persistcache.New(persistCacheFilepath)
if err != nil {
return nil, err
}
metadata := artifact.GetBase64MetaData()
data := artifact.GetBase64Data()
// We want write inline data to a file to serve it from http server
url, err := pc.Put(artifact.GetFileNameToUse(), []byte(data))
if err != nil {
return nil, err
}
shaBytes := sha256.Sum256([]byte(data))
return &types.BinaryBlobCompleted{
FileName: artifact.GetFileNameToUse(),
FileSha: hex.EncodeToString(shaBytes[:]),
FileMetadata: metadata,
URL: url,
Size: int64(len(data)),
}, nil
}
func getBinaryBlobVolumeRef(artifact *zconfig.ExternalOpaqueBinaryBlob) (*types.BinaryBlobVolumeRef, error) {
// Since Volumes will be handled by volumemgr we can only provide
// reference for now. It will be updated once download is completed
// down the processing pipeline
return &types.BinaryBlobVolumeRef{
ImageName: artifact.GetImageName(),
FileName: artifact.GetFileNameToUse(),
FileMetadata: artifact.GetBlobMetaData(),
ImageID: artifact.GetImageId(),
}, nil
}
func evePatchEnvelopeActionToState(action zconfig.EVE_PATCH_ENVELOPE_ACTION) types.PatchEnvelopeState {
switch action {
case zconfig.EVE_PATCH_ENVELOPE_ACTION_STORE:
return types.PatchEnvelopeStateReady
case zconfig.EVE_PATCH_ENVELOPE_ACTION_ACTIVATE:
return types.PatchEnvelopeStateActive
}
return types.PatchEnvelopeStateError
}