blob: 9816927d610b72f80a63764303b79b56b95a718d [file] [log] [blame]
Mahir Gunyelfa6ea272020-06-10 17:03:51 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package device
18
19import (
20 "context"
Andrea Campanella025667e2021-01-14 11:50:07 +010021 "github.com/opencord/voltha-protos/v4/go/common"
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070022
23 "github.com/gogo/protobuf/proto"
24 "github.com/golang/protobuf/ptypes"
Himani Chawlab4c25912020-11-12 17:16:38 +053025 coreutils "github.com/opencord/voltha-go/rw_core/utils"
Maninderdfadc982020-10-28 14:04:33 +053026 "github.com/opencord/voltha-lib-go/v4/pkg/log"
27 "github.com/opencord/voltha-protos/v4/go/voltha"
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070028 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30)
31
Andrea Campanella025667e2021-01-14 11:50:07 +010032func (agent *Agent) downloadImage(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070033 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
34 return nil, err
35 }
Himani Chawlab4c25912020-11-12 17:16:38 +053036 logger.Debugw(ctx, "download-image", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070037
Andrea Campanella025667e2021-01-14 11:50:07 +010038 if agent.device.Root {
39 return nil, status.Errorf(codes.FailedPrecondition, "device-id:%s, is an OLT. Image update "+
40 "not supported by VOLTHA. Use Device Manager or other means", agent.deviceID)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070041 }
Andrea Campanella025667e2021-01-14 11:50:07 +010042
43 device := agent.cloneDeviceWithoutLock()
44 if device.ImageDownloads != nil {
45 for _, image := range device.ImageDownloads {
46 if image.DownloadState == voltha.ImageDownload_DOWNLOAD_REQUESTED {
47 return nil, status.Errorf(codes.FailedPrecondition, "device-id:%s, already downloading image:%s",
48 agent.deviceID, image.Name)
49 }
50 }
Kent Hagermanf6db9f12020-07-22 17:16:19 -040051 }
52
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070053 // Save the image
54 clonedImg := proto.Clone(img).(*voltha.ImageDownload)
55 clonedImg.DownloadState = voltha.ImageDownload_DOWNLOAD_REQUESTED
Kent Hagermanf6db9f12020-07-22 17:16:19 -040056 cloned := agent.cloneDeviceWithoutLock()
Andrea Campanellac05c4c42021-02-11 10:25:28 +010057 _, index, err := getImage(img, device)
58 if err != nil {
59 cloned.ImageDownloads = append(device.ImageDownloads, clonedImg)
60 } else {
61 cloned.ImageDownloads[index] = clonedImg
62 }
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070063
Kent Hagermanf6db9f12020-07-22 17:16:19 -040064 cloned.AdminState = voltha.AdminState_DOWNLOADING_IMAGE
65 if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
66 return nil, err
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070067 }
Kent Hagermanf6db9f12020-07-22 17:16:19 -040068
69 // Send the request to the adapter
Rohan Agrawalcf12f202020-08-03 04:42:01 +000070 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
Himani Chawlab4c25912020-11-12 17:16:38 +053071 subCtx = coreutils.WithRPCMetadataFromContext(subCtx, ctx)
72
Andrea Campanella025667e2021-01-14 11:50:07 +010073 ch, err := agent.adapterProxy.DownloadImage(subCtx, cloned, clonedImg)
Kent Hagermanf6db9f12020-07-22 17:16:19 -040074 if err != nil {
75 cancel()
76 return nil, err
77 }
Andrea Campanella025667e2021-01-14 11:50:07 +010078 go agent.waitForAdapterResponse(subCtx, cancel, "downloadImage", ch, agent.onImageSuccess, agent.onImageFailure)
Kent Hagermanf6db9f12020-07-22 17:16:19 -040079
Andrea Campanella025667e2021-01-14 11:50:07 +010080 return &common.OperationResp{Code: voltha.OperationResp_OPERATION_SUCCESS}, nil
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070081}
82
Andrea Campanella025667e2021-01-14 11:50:07 +010083// getImage is a helper method to figure out if an image is already registered
84func getImage(img *voltha.ImageDownload, device *voltha.Device) (*voltha.ImageDownload, int, error) {
85 for pos, image := range device.ImageDownloads {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070086 if image.Id == img.Id && image.Name == img.Name {
Andrea Campanella025667e2021-01-14 11:50:07 +010087 return image, pos, nil
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070088 }
89 }
Andrea Campanella025667e2021-01-14 11:50:07 +010090 return nil, -1, status.Errorf(codes.FailedPrecondition, "device-id:%s, image-not-registered:%s",
91 device.Id, img.Name)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070092}
93
Andrea Campanella025667e2021-01-14 11:50:07 +010094func (agent *Agent) cancelImageDownload(ctx context.Context, img *voltha.ImageDownload) (*common.OperationResp, error) {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070095 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
96 return nil, err
97 }
Himani Chawlab4c25912020-11-12 17:16:38 +053098 logger.Debugw(ctx, "cancel-image-download", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -070099
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700100 // Update image download state
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400101 cloned := agent.cloneDeviceWithoutLock()
Andrea Campanella025667e2021-01-14 11:50:07 +0100102 _, index, err := getImage(img, cloned)
103 if err != nil {
104 agent.requestQueue.RequestComplete()
105 return nil, err
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700106 }
107
Andrea Campanella025667e2021-01-14 11:50:07 +0100108 cloned.ImageDownloads[index].DownloadState = voltha.ImageDownload_DOWNLOAD_CANCELLED
109
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400110 if cloned.AdminState != voltha.AdminState_DOWNLOADING_IMAGE {
111 agent.requestQueue.RequestComplete()
112 } else {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700113 // Set the device to Enabled
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400114 cloned.AdminState = voltha.AdminState_ENABLED
115 if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700116 return nil, err
117 }
Rohan Agrawalcf12f202020-08-03 04:42:01 +0000118 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
Himani Chawlab4c25912020-11-12 17:16:38 +0530119 subCtx = coreutils.WithRPCMetadataFromContext(subCtx, ctx)
120
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400121 ch, err := agent.adapterProxy.CancelImageDownload(subCtx, cloned, img)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700122 if err != nil {
123 cancel()
124 return nil, err
125 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100126 go agent.waitForAdapterResponse(subCtx, cancel, "cancelImageDownload", ch, agent.onImageSuccess,
127 agent.onImageFailure)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700128 }
129 return &voltha.OperationResp{Code: voltha.OperationResp_OPERATION_SUCCESS}, nil
130}
131
132func (agent *Agent) activateImage(ctx context.Context, img *voltha.ImageDownload) (*voltha.OperationResp, error) {
133 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
134 return nil, err
135 }
Himani Chawlab4c25912020-11-12 17:16:38 +0530136 logger.Debugw(ctx, "activate-image", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700137
Andrea Campanella025667e2021-01-14 11:50:07 +0100138 // Update image download state
139 cloned := agent.cloneDeviceWithoutLock()
140 image, index, err := getImage(img, cloned)
141 if err != nil {
142 agent.requestQueue.RequestComplete()
143 return nil, err
144 }
145
Andrea Campanella025667e2021-01-14 11:50:07 +0100146 if image.DownloadState != voltha.ImageDownload_DOWNLOAD_SUCCEEDED {
147 agent.requestQueue.RequestComplete()
148 return nil, status.Errorf(codes.FailedPrecondition, "device-id:%s, device-has-not-downloaded-image:%s", agent.deviceID, img.Name)
149 }
150
151 //TODO does this need to be removed ?
152 if cloned.AdminState == voltha.AdminState_DOWNLOADING_IMAGE {
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400153 agent.requestQueue.RequestComplete()
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700154 return nil, status.Errorf(codes.FailedPrecondition, "device-id:%s, device-in-downloading-state:%s", agent.deviceID, img.Name)
155 }
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400156
Andrea Campanella025667e2021-01-14 11:50:07 +0100157 // Save the image
158 cloned.ImageDownloads[index].ImageState = voltha.ImageDownload_IMAGE_ACTIVATING
159
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400160 cloned.AdminState = voltha.AdminState_DOWNLOADING_IMAGE
161 if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700162 return nil, err
163 }
164
Rohan Agrawalcf12f202020-08-03 04:42:01 +0000165 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
Himani Chawlab4c25912020-11-12 17:16:38 +0530166 subCtx = coreutils.WithRPCMetadataFromContext(subCtx, ctx)
167
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400168 ch, err := agent.adapterProxy.ActivateImageUpdate(subCtx, cloned, img)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700169 if err != nil {
170 cancel()
171 return nil, err
172 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100173 go agent.waitForAdapterResponse(subCtx, cancel, "activateImageUpdate", ch, agent.onImageSuccess, agent.onFailure)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700174
175 // The status of the AdminState will be changed following the update_download_status response from the adapter
176 // The image name will also be removed from the device list
177 return &voltha.OperationResp{Code: voltha.OperationResp_OPERATION_SUCCESS}, nil
178}
179
180func (agent *Agent) revertImage(ctx context.Context, img *voltha.ImageDownload) (*voltha.OperationResp, error) {
181 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
182 return nil, err
183 }
Himani Chawlab4c25912020-11-12 17:16:38 +0530184 logger.Debugw(ctx, "revert-image", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700185
Andrea Campanella025667e2021-01-14 11:50:07 +0100186 // Update image download state
187 cloned := agent.cloneDeviceWithoutLock()
188 _, index, err := getImage(img, cloned)
189 if err != nil {
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400190 agent.requestQueue.RequestComplete()
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700191 return nil, status.Errorf(codes.FailedPrecondition, "deviceId:%s, image-not-registered:%s", agent.deviceID, img.Name)
192 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100193 if cloned.AdminState != voltha.AdminState_ENABLED {
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400194 agent.requestQueue.RequestComplete()
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700195 return nil, status.Errorf(codes.FailedPrecondition, "deviceId:%s, device-not-enabled-state:%s", agent.deviceID, img.Name)
196 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100197
198 cloned.ImageDownloads[index].ImageState = voltha.ImageDownload_IMAGE_REVERTING
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700199
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400200 if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700201 return nil, err
202 }
203
Rohan Agrawalcf12f202020-08-03 04:42:01 +0000204 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
Himani Chawlab4c25912020-11-12 17:16:38 +0530205 subCtx = coreutils.WithRPCMetadataFromContext(subCtx, ctx)
206
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400207 ch, err := agent.adapterProxy.RevertImageUpdate(subCtx, cloned, img)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700208 if err != nil {
209 cancel()
210 return nil, err
211 }
212 go agent.waitForAdapterResponse(subCtx, cancel, "revertImageUpdate", ch, agent.onSuccess, agent.onFailure)
213
214 return &voltha.OperationResp{Code: voltha.OperationResp_OPERATION_SUCCESS}, nil
215}
216
217func (agent *Agent) getImageDownloadStatus(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530218 logger.Debugw(ctx, "get-image-download-status", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700219
220 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
221 return nil, err
222 }
Kent Hagermancba2f302020-07-28 13:37:36 -0400223 device := agent.getDeviceReadOnlyWithoutLock()
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700224 ch, err := agent.adapterProxy.GetImageDownloadStatus(ctx, device, img)
225 agent.requestQueue.RequestComplete()
226 if err != nil {
227 return nil, err
228 }
229 // Wait for the adapter response
230 rpcResponse, ok := <-ch
231 if !ok {
232 return nil, status.Errorf(codes.Aborted, "channel-closed-device-id-%s", agent.deviceID)
233 }
234 if rpcResponse.Err != nil {
235 return nil, rpcResponse.Err
236 }
237 // Successful response
238 imgDownload := &voltha.ImageDownload{}
239 if err := ptypes.UnmarshalAny(rpcResponse.Reply, imgDownload); err != nil {
240 return nil, status.Errorf(codes.InvalidArgument, "%s", err.Error())
241 }
242 return imgDownload, nil
243}
244
245func (agent *Agent) updateImageDownload(ctx context.Context, img *voltha.ImageDownload) error {
246 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
247 return err
248 }
Rohan Agrawal31f21802020-06-12 05:38:46 +0000249 logger.Debugw(ctx, "updating-image-download", log.Fields{"device-id": agent.deviceID, "img": img})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700250
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700251 // Update the image as well as remove it if the download was cancelled
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400252 cloned := agent.cloneDeviceWithoutLock()
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700253 clonedImages := make([]*voltha.ImageDownload, len(cloned.ImageDownloads))
254 for _, image := range cloned.ImageDownloads {
255 if image.Id == img.Id && image.Name == img.Name {
256 if image.DownloadState != voltha.ImageDownload_DOWNLOAD_CANCELLED {
257 clonedImages = append(clonedImages, img)
258 }
259 }
260 }
261 cloned.ImageDownloads = clonedImages
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400262
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700263 // Set the Admin state to enabled if required
264 if (img.DownloadState != voltha.ImageDownload_DOWNLOAD_REQUESTED &&
265 img.DownloadState != voltha.ImageDownload_DOWNLOAD_STARTED) ||
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400266 img.ImageState != voltha.ImageDownload_IMAGE_ACTIVATING {
267 cloned.AdminState = voltha.AdminState_ENABLED
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700268 }
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400269 return agent.updateDeviceAndReleaseLock(ctx, cloned)
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700270}
271
272func (agent *Agent) getImageDownload(ctx context.Context, img *voltha.ImageDownload) (*voltha.ImageDownload, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530273 logger.Debugw(ctx, "get-image-download", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700274
Kent Hagermancba2f302020-07-28 13:37:36 -0400275 device, err := agent.getDeviceReadOnly(ctx)
276 if err != nil {
277 return nil, status.Errorf(codes.Aborted, "%s", err)
278 }
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400279 for _, image := range device.ImageDownloads {
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700280 if image.Id == img.Id && image.Name == img.Name {
281 return image, nil
282 }
283 }
284 return nil, status.Errorf(codes.NotFound, "image-not-found:%s", img.Name)
285}
286
287func (agent *Agent) listImageDownloads(ctx context.Context, deviceID string) (*voltha.ImageDownloads, error) {
Himani Chawlab4c25912020-11-12 17:16:38 +0530288 logger.Debugw(ctx, "list-image-downloads", log.Fields{"device-id": agent.deviceID})
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700289
Kent Hagermancba2f302020-07-28 13:37:36 -0400290 device, err := agent.getDeviceReadOnly(ctx)
291 if err != nil {
292 return nil, status.Errorf(codes.Aborted, "%s", err)
293 }
294 return &voltha.ImageDownloads{Items: device.ImageDownloads}, nil
Mahir Gunyelfa6ea272020-06-10 17:03:51 -0700295}
Andrea Campanella025667e2021-01-14 11:50:07 +0100296
297// onImageFailure brings back the device to Enabled state and sets the image to image download_failed.
298func (agent *Agent) onImageFailure(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100299 // original context has failed due to timeout , let's open a new one
300 subCtx, cancel := context.WithTimeout(log.WithSpanFromContext(context.Background(), ctx), agent.defaultTimeout)
301 subCtx = coreutils.WithRPCMetadataFromContext(subCtx, ctx)
302
303 if err := agent.requestQueue.WaitForGreenLight(subCtx); err != nil {
304 logger.Errorw(subCtx, "can't obtain lock", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": err, "args": reqArgs})
305 cancel()
Andrea Campanella025667e2021-01-14 11:50:07 +0100306 return
307 }
308 if res, ok := response.(error); ok {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100309 logger.Errorw(subCtx, "rpc-failed", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": res, "args": reqArgs})
310 cloned := agent.cloneDeviceWithoutLock()
Andrea Campanella025667e2021-01-14 11:50:07 +0100311 //TODO base this on IMAGE ID when created
312 var imageFailed *voltha.ImageDownload
313 var index int
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100314 if cloned.ImageDownloads != nil {
315 for pos, image := range cloned.ImageDownloads {
Andrea Campanella025667e2021-01-14 11:50:07 +0100316 if image.DownloadState == voltha.ImageDownload_DOWNLOAD_REQUESTED ||
317 image.ImageState == voltha.ImageDownload_IMAGE_ACTIVATING {
318 imageFailed = image
319 index = pos
320 }
321 }
322 }
323
324 if imageFailed == nil {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100325 logger.Errorw(subCtx, "can't find image", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "args": reqArgs})
326 cancel()
Andrea Campanella025667e2021-01-14 11:50:07 +0100327 return
328 }
329
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100330 //update image state on failure
Andrea Campanella025667e2021-01-14 11:50:07 +0100331 if imageFailed.DownloadState == voltha.ImageDownload_DOWNLOAD_REQUESTED {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100332 cloned.ImageDownloads[index].DownloadState = voltha.ImageDownload_DOWNLOAD_FAILED
Andrea Campanella025667e2021-01-14 11:50:07 +0100333 } else if imageFailed.ImageState == voltha.ImageDownload_IMAGE_ACTIVATING {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100334 cloned.ImageDownloads[index].ImageState = voltha.ImageDownload_IMAGE_INACTIVE
Andrea Campanella025667e2021-01-14 11:50:07 +0100335 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100336 //Enabled is the only state we can go back to.
337 cloned.AdminState = voltha.AdminState_ENABLED
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100338 if err := agent.updateDeviceAndReleaseLock(subCtx, cloned); err != nil {
339 logger.Errorw(subCtx, "failed-enable-device-after-image-failure",
Andrea Campanella025667e2021-01-14 11:50:07 +0100340 log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": res, "args": reqArgs})
341 }
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100342 cancel()
Andrea Campanella025667e2021-01-14 11:50:07 +0100343 } else {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100344 logger.Errorw(subCtx, "rpc-failed-invalid-error", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "args": reqArgs})
345 cancel()
346 return
Andrea Campanella025667e2021-01-14 11:50:07 +0100347 }
348 // TODO: Post failure message onto kafka
349}
350
351// onImageSuccess brings back the device to Enabled state and sets the image to image download_failed.
352func (agent *Agent) onImageSuccess(ctx context.Context, rpc string, response interface{}, reqArgs ...interface{}) {
353 if err := agent.requestQueue.WaitForGreenLight(ctx); err != nil {
Himani Chawlab4c25912020-11-12 17:16:38 +0530354 logger.Errorw(ctx, "cannot-obtain-lock", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "error": err, "args": reqArgs})
Andrea Campanella025667e2021-01-14 11:50:07 +0100355 return
356 }
Matteo Scandolo03686da2021-03-09 13:16:55 -0800357 logger.Infow(ctx, "rpc-successful", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "response": response, "args": reqArgs})
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100358 cloned := agent.cloneDeviceWithoutLock()
Andrea Campanella025667e2021-01-14 11:50:07 +0100359 //TODO base this on IMAGE ID when created
360 var imageSucceeded *voltha.ImageDownload
361 var index int
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100362 if cloned.ImageDownloads != nil {
363 for pos, image := range cloned.ImageDownloads {
Andrea Campanella025667e2021-01-14 11:50:07 +0100364 if image.DownloadState == voltha.ImageDownload_DOWNLOAD_REQUESTED ||
365 image.ImageState == voltha.ImageDownload_IMAGE_ACTIVATING {
366 imageSucceeded = image
367 index = pos
368 }
369 }
370 }
371
372 if imageSucceeded == nil {
373 logger.Errorw(ctx, "can't find image", log.Fields{"rpc": rpc, "device-id": agent.deviceID, "args": reqArgs})
374 return
375 }
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100376 //update image state on success
Andrea Campanella025667e2021-01-14 11:50:07 +0100377 if imageSucceeded.DownloadState == voltha.ImageDownload_DOWNLOAD_REQUESTED {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100378 cloned.ImageDownloads[index].DownloadState = voltha.ImageDownload_DOWNLOAD_SUCCEEDED
Andrea Campanella025667e2021-01-14 11:50:07 +0100379 } else if imageSucceeded.ImageState == voltha.ImageDownload_IMAGE_ACTIVATING {
Andrea Campanellac05c4c42021-02-11 10:25:28 +0100380 cloned.ImageDownloads[index].ImageState = voltha.ImageDownload_IMAGE_ACTIVE
Andrea Campanella025667e2021-01-14 11:50:07 +0100381 }
Andrea Campanella025667e2021-01-14 11:50:07 +0100382 //Enabled is the only state we can go back to.
383 cloned.AdminState = voltha.AdminState_ENABLED
384 if err := agent.updateDeviceAndReleaseLock(ctx, cloned); err != nil {
385 logger.Errorw(ctx, "failed-enable-device-after-image-download-success",
386 log.Fields{"rpc": rpc, "device-id": agent.deviceID, "response": response, "args": reqArgs})
387 }
388
389}