@@ -2,6 +2,9 @@ package main
2
2
3
3
import (
4
4
"fmt"
5
+ "os"
6
+ "os/exec"
7
+ "path/filepath"
5
8
"strings"
6
9
7
10
"github.com/sirupsen/logrus"
@@ -78,3 +81,154 @@ var updateOpenEBSAddonCommand = &cli.Command{
78
81
return nil
79
82
},
80
83
}
84
+
85
+ type addonComponent struct {
86
+ name string
87
+ wolfiPackageName string
88
+ upstreamVersionMakefileVar string
89
+ upstreamVersionFlagOverride string
90
+ }
91
+
92
+ var openebsComponents = []addonComponent {
93
+ {
94
+ name : "openebs-provisioner-localpv" ,
95
+ wolfiPackageName : "dynamic-localpv-provisioner" ,
96
+ upstreamVersionMakefileVar : "OPENEBS_IMAGE_VERSION" ,
97
+ upstreamVersionFlagOverride : "openebs-version" ,
98
+ },
99
+ {
100
+ name : "openebs-linux-utils" ,
101
+ upstreamVersionMakefileVar : "OPENEBS_IMAGE_VERSION" ,
102
+ upstreamVersionFlagOverride : "openebs-version" ,
103
+ },
104
+ {
105
+ name : "openebs-kubectl" ,
106
+ wolfiPackageName : "kubectl" ,
107
+ upstreamVersionMakefileVar : "OPENEBS_KUBECTL_IMAGE_VERSION" ,
108
+ upstreamVersionFlagOverride : "kubectl-version" ,
109
+ },
110
+ }
111
+
112
+ var updateOpenEBSImagesCommand = & cli.Command {
113
+ Name : "openebs" ,
114
+ Usage : "Updates the openebs images" ,
115
+ UsageText : environmentUsageText ,
116
+ Flags : []cli.Flag {
117
+ & cli.StringFlag {
118
+ Name : "openebs-version" ,
119
+ Usage : "The version of openebs to use to determine image versions" ,
120
+ },
121
+ & cli.StringFlag {
122
+ Name : "kubectl-version" ,
123
+ Usage : "The version of kubectl to use to determine image versions" ,
124
+ },
125
+ },
126
+ Action : func (c * cli.Context ) error {
127
+ logrus .Infof ("updating openebs images" )
128
+
129
+ if err := ApkoLogin (); err != nil {
130
+ return fmt .Errorf ("failed to apko login: %w" , err )
131
+ }
132
+
133
+ wolfiAPKIndex , err := GetWolfiAPKIndex ()
134
+ if err != nil {
135
+ return fmt .Errorf ("failed to get APK index: %w" , err )
136
+ }
137
+
138
+ for _ , component := range openebsComponents {
139
+ upstreamVersion , err := getAddonComponentUpstreamVersion (c , component )
140
+ if err != nil {
141
+ return fmt .Errorf ("failed to get upstream version for %s: %w" , component .name , err )
142
+ }
143
+
144
+ packageVersion := upstreamVersion
145
+ if component .wolfiPackageName != "" {
146
+ packageVersion , err = GetWolfiPackageVersion (wolfiAPKIndex , component .name , upstreamVersion )
147
+ if err != nil {
148
+ return fmt .Errorf ("failed to get package version for %s: %w" , component .name , err )
149
+ }
150
+ }
151
+
152
+ if err := ApkoBuildAndPublish (component .name , packageVersion ); err != nil {
153
+ return fmt .Errorf ("failed to apko build and publish for %s: %w" , component .name , err )
154
+ }
155
+
156
+ digest , err := GetDigestFromBuildFile ()
157
+ if err != nil {
158
+ return fmt .Errorf ("failed to get digest from build file: %w" , err )
159
+ }
160
+
161
+ makefileVar := getAddonComponentImageTagMakefileVar (component )
162
+ if err := SetMakefileVariable (makefileVar , fmt .Sprintf ("%s@%s" , packageVersion , digest )); err != nil {
163
+ return fmt .Errorf ("failed to set %s version: %w" , component .name , err )
164
+ }
165
+ }
166
+
167
+ return nil
168
+ },
169
+ }
170
+
171
+ func getAddonComponentUpstreamVersion (c * cli.Context , component addonComponent ) (string , error ) {
172
+ if ver := c .String (component .upstreamVersionFlagOverride ); ver != "" {
173
+ return ver , nil
174
+ }
175
+ ver , err := GetMakefileVariable (component .upstreamVersionMakefileVar )
176
+ if err != nil {
177
+ return "" , fmt .Errorf ("get version from makefile: %w" , err )
178
+ }
179
+ return ver , nil
180
+ }
181
+
182
+ func getAddonComponentImageTagMakefileVar (component addonComponent ) string {
183
+ return fmt .Sprintf ("%s_IMAGE_TAG" , strings .ReplaceAll (strings .ToUpper (component .name ), "-" , "_" ))
184
+ }
185
+
186
+ func ApkoLogin () error {
187
+ if err := RunCommand ("make" , "apko" ); err != nil {
188
+ return fmt .Errorf ("make apko: %w" , err )
189
+ }
190
+ if os .Getenv ("REGISTRY_PASS" ) != "" {
191
+ if err := RunCommand (
192
+ "make" ,
193
+ "apko-login" ,
194
+ fmt .Sprintf ("REGISTRY=%s" , os .Getenv ("REGISTRY_SERVER" )),
195
+ fmt .Sprintf ("USERNAME=%s" , os .Getenv ("REGISTRY_USER" )),
196
+ fmt .Sprintf ("PASSWORD=%s" , os .Getenv ("REGISTRY_PASS" )),
197
+ ); err != nil {
198
+ return err
199
+ }
200
+ }
201
+ return nil
202
+ }
203
+
204
+ func ApkoBuildAndPublish (componentName string , packageVersion string ) error {
205
+ if err := RunCommand (
206
+ "make" ,
207
+ "apko-build-and-publish" ,
208
+ fmt .Sprintf ("IMAGE=%s/replicated/ec-%s:%s" , os .Getenv ("REGISTRY_SERVER" ), componentName , packageVersion ),
209
+ fmt .Sprintf ("APKO_CONFIG=%s" , filepath .Join ("deploy" , "images" , componentName , "apko.tmpl.yaml" )),
210
+ fmt .Sprintf ("PACKAGE_VERSION=%s" , packageVersion ),
211
+ ); err != nil {
212
+ return err
213
+ }
214
+ return nil
215
+ }
216
+
217
+ func GetDigestFromBuildFile () (string , error ) {
218
+ contents , err := os .ReadFile ("build/digest" )
219
+ if err != nil {
220
+ return "" , fmt .Errorf ("read build file: %w" , err )
221
+ }
222
+ parts := strings .Split (string (contents ), "@" )
223
+ if len (parts ) != 2 {
224
+ return "" , fmt .Errorf ("incorrect number of parts in build file" )
225
+ }
226
+ return strings .TrimSpace (parts [1 ]), nil
227
+ }
228
+
229
+ func RunCommand (name string , args ... string ) error {
230
+ cmd := exec .Command (name , args ... )
231
+ cmd .Stdout = os .Stdout
232
+ cmd .Stderr = os .Stderr
233
+ return cmd .Run ()
234
+ }
0 commit comments