Monorepo for Tangled

appview/repo: use slog logger in artifact handlers

Signed-off-by: oppiliappan <me@oppi.li>

+39 -30
+39 -30
appview/repo/artifact.go
··· 5 "encoding/json" 6 "fmt" 7 "io" 8 - "log" 9 "net/http" 10 "net/url" 11 "time" ··· 31 32 // TODO: proper statuses here on early exit 33 func (rp *Repo) AttachArtifact(w http.ResponseWriter, r *http.Request) { 34 user := rp.oauth.GetMultiAccountUser(r) 35 tagParam := chi.URLParam(r, "tag") 36 f, err := rp.repoResolver.Resolve(r) 37 if err != nil { 38 - log.Println("failed to get repo and knot", err) 39 rp.pages.Notice(w, "upload", "failed to upload artifact, error in repo resolution") 40 return 41 } 42 43 tag, err := rp.resolveTag(r.Context(), f, tagParam) 44 if err != nil { 45 - log.Println("failed to resolve tag", err) 46 rp.pages.Notice(w, "upload", "failed to upload artifact, error in tag resolution") 47 return 48 } 49 50 file, header, err := r.FormFile("artifact") 51 if err != nil { 52 - log.Println("failed to upload artifact", err) 53 rp.pages.Notice(w, "upload", "failed to upload artifact") 54 return 55 } ··· 57 58 client, err := rp.oauth.AuthorizedClient(r) 59 if err != nil { 60 - log.Println("failed to get authorized client", err) 61 rp.pages.Notice(w, "upload", "failed to get authorized client") 62 return 63 } 64 65 uploadBlobResp, err := xrpc.RepoUploadBlob(r.Context(), client, file, header.Header.Get("Content-Type")) 66 if err != nil { 67 - log.Println("failed to upload blob", err) 68 rp.pages.Notice(w, "upload", "Failed to upload blob to your PDS. Try again later.") 69 return 70 } 71 72 - log.Println("uploaded blob", humanize.Bytes(uint64(uploadBlobResp.Blob.Size)), uploadBlobResp.Blob.Ref.String()) 73 74 rkey := tid.TID() 75 createdAt := time.Now() ··· 89 }, 90 }) 91 if err != nil { 92 - log.Println("failed to create record", err) 93 rp.pages.Notice(w, "upload", "Failed to create artifact record. Try again later.") 94 return 95 } 96 97 - log.Println(putRecordResp.Uri) 98 99 tx, err := rp.db.BeginTx(r.Context(), nil) 100 if err != nil { 101 - log.Println("failed to start tx") 102 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 103 return 104 } ··· 118 119 err = db.AddArtifact(tx, artifact) 120 if err != nil { 121 - log.Println("failed to add artifact record to db", err) 122 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 123 return 124 } 125 126 err = tx.Commit() 127 if err != nil { 128 - log.Println("failed to add artifact record to db") 129 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 130 return 131 } ··· 138 } 139 140 func (rp *Repo) DownloadArtifact(w http.ResponseWriter, r *http.Request) { 141 f, err := rp.repoResolver.Resolve(r) 142 if err != nil { 143 - log.Println("failed to get repo and knot", err) 144 http.Error(w, "failed to resolve repo", http.StatusInternalServerError) 145 return 146 } ··· 150 151 tag, err := rp.resolveTag(r.Context(), f, tagParam) 152 if err != nil { 153 - log.Println("failed to resolve tag", err) 154 rp.pages.Notice(w, "upload", "failed to upload artifact, error in tag resolution") 155 return 156 } ··· 162 orm.FilterEq("name", filename), 163 ) 164 if err != nil { 165 - log.Println("failed to get artifacts", err) 166 http.Error(w, "failed to get artifact", http.StatusInternalServerError) 167 return 168 } 169 170 if len(artifacts) != 1 { 171 - log.Printf("too many or too few artifacts found") 172 http.Error(w, "artifact not found", http.StatusNotFound) 173 return 174 } ··· 177 178 ownerId, err := rp.idResolver.ResolveIdent(r.Context(), f.Did) 179 if err != nil { 180 - log.Println("failed to resolve repo owner did", f.Did, err) 181 http.Error(w, "repository owner not found", http.StatusNotFound) 182 return 183 } ··· 191 192 req, err := http.NewRequest(http.MethodGet, url.String(), nil) 193 if err != nil { 194 - log.Println("failed to create request", err) 195 http.Error(w, "failed to create request", http.StatusInternalServerError) 196 return 197 } ··· 199 200 resp, err := http.DefaultClient.Do(req) 201 if err != nil { 202 - log.Println("failed to make request", err) 203 http.Error(w, "failed to make request to PDS", http.StatusInternalServerError) 204 return 205 } ··· 215 216 // stream the body directly to the client 217 if _, err := io.Copy(w, resp.Body); err != nil { 218 - log.Println("error streaming response to client:", err) 219 } 220 } 221 222 // TODO: proper statuses here on early exit 223 func (rp *Repo) DeleteArtifact(w http.ResponseWriter, r *http.Request) { 224 user := rp.oauth.GetMultiAccountUser(r) 225 tagParam := chi.URLParam(r, "tag") 226 filename := chi.URLParam(r, "file") 227 f, err := rp.repoResolver.Resolve(r) 228 if err != nil { 229 - log.Println("failed to get repo and knot", err) 230 return 231 } 232 ··· 241 orm.FilterEq("name", filename), 242 ) 243 if err != nil { 244 - log.Println("failed to get artifacts", err) 245 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 246 return 247 } ··· 253 artifact := artifacts[0] 254 255 if user.Active.Did != artifact.Did { 256 - log.Println("user not authorized to delete artifact", err) 257 rp.pages.Notice(w, "remove", "Unauthorized deletion of artifact.") 258 return 259 } ··· 264 Rkey: artifact.Rkey, 265 }) 266 if err != nil { 267 - log.Println("failed to get blob from pds", err) 268 rp.pages.Notice(w, "remove", "Failed to remove blob from PDS.") 269 return 270 } 271 272 tx, err := rp.db.BeginTx(r.Context(), nil) 273 if err != nil { 274 - log.Println("failed to start tx") 275 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 276 return 277 } ··· 283 orm.FilterEq("name", filename), 284 ) 285 if err != nil { 286 - log.Println("failed to remove artifact record from db", err) 287 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 288 return 289 } 290 291 err = tx.Commit() 292 if err != nil { 293 - log.Println("failed to remove artifact record from db") 294 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 295 return 296 } 297 298 w.Write([]byte{}) 299 } 300 301 func (rp *Repo) resolveTag(ctx context.Context, f *models.Repo, tagParam string) (*types.TagReference, error) { 302 tagParam, err := url.QueryUnescape(tagParam) 303 if err != nil { 304 return nil, err ··· 317 xrpcBytes, err := tangled.RepoTags(ctx, xrpcc, "", 0, repo) 318 if err != nil { 319 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 320 - log.Println("failed to call XRPC repo.tags", xrpcerr) 321 return nil, xrpcerr 322 } 323 - log.Println("failed to reach knotserver", err) 324 return nil, err 325 } 326 327 var result types.RepoTagsResponse 328 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 329 - log.Println("failed to decode XRPC tags response", err) 330 return nil, err 331 } 332
··· 5 "encoding/json" 6 "fmt" 7 "io" 8 "net/http" 9 "net/url" 10 "time" ··· 30 31 // TODO: proper statuses here on early exit 32 func (rp *Repo) AttachArtifact(w http.ResponseWriter, r *http.Request) { 33 + l := rp.logger.With("handler", "AttachArtifact") 34 + 35 user := rp.oauth.GetMultiAccountUser(r) 36 tagParam := chi.URLParam(r, "tag") 37 f, err := rp.repoResolver.Resolve(r) 38 if err != nil { 39 + l.Error("failed to get repo and knot", "err", err) 40 rp.pages.Notice(w, "upload", "failed to upload artifact, error in repo resolution") 41 return 42 } 43 44 tag, err := rp.resolveTag(r.Context(), f, tagParam) 45 if err != nil { 46 + l.Error("failed to resolve tag", "err", err) 47 rp.pages.Notice(w, "upload", "failed to upload artifact, error in tag resolution") 48 return 49 } 50 51 file, header, err := r.FormFile("artifact") 52 if err != nil { 53 + l.Error("failed to upload artifact", "err", err) 54 rp.pages.Notice(w, "upload", "failed to upload artifact") 55 return 56 } ··· 58 59 client, err := rp.oauth.AuthorizedClient(r) 60 if err != nil { 61 + l.Error("failed to get authorized client", "err", err) 62 rp.pages.Notice(w, "upload", "failed to get authorized client") 63 return 64 } 65 66 uploadBlobResp, err := xrpc.RepoUploadBlob(r.Context(), client, file, header.Header.Get("Content-Type")) 67 if err != nil { 68 + l.Error("failed to upload blob", "err", err) 69 rp.pages.Notice(w, "upload", "Failed to upload blob to your PDS. Try again later.") 70 return 71 } 72 73 + l.Info("uploaded blob", "size", humanize.Bytes(uint64(uploadBlobResp.Blob.Size)), "blobRef", uploadBlobResp.Blob.Ref.String()) 74 75 rkey := tid.TID() 76 createdAt := time.Now() ··· 90 }, 91 }) 92 if err != nil { 93 + l.Error("failed to create record", "err", err) 94 rp.pages.Notice(w, "upload", "Failed to create artifact record. Try again later.") 95 return 96 } 97 98 + l.Debug("created record for blob", "aturi", putRecordResp.Uri) 99 100 tx, err := rp.db.BeginTx(r.Context(), nil) 101 if err != nil { 102 + l.Error("failed to start tx") 103 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 104 return 105 } ··· 119 120 err = db.AddArtifact(tx, artifact) 121 if err != nil { 122 + l.Error("failed to add artifact record to db", "err", err) 123 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 124 return 125 } 126 127 err = tx.Commit() 128 if err != nil { 129 + l.Error("failed to add artifact record to db") 130 rp.pages.Notice(w, "upload", "Failed to create artifact. Try again later.") 131 return 132 } ··· 139 } 140 141 func (rp *Repo) DownloadArtifact(w http.ResponseWriter, r *http.Request) { 142 + l := rp.logger.With("handler", "DownloadArtifact") 143 + 144 f, err := rp.repoResolver.Resolve(r) 145 if err != nil { 146 + l.Error("failed to get repo and knot", "err", err) 147 http.Error(w, "failed to resolve repo", http.StatusInternalServerError) 148 return 149 } ··· 153 154 tag, err := rp.resolveTag(r.Context(), f, tagParam) 155 if err != nil { 156 + l.Error("failed to resolve tag", "err", err) 157 rp.pages.Notice(w, "upload", "failed to upload artifact, error in tag resolution") 158 return 159 } ··· 165 orm.FilterEq("name", filename), 166 ) 167 if err != nil { 168 + l.Error("failed to get artifacts", "err", err) 169 http.Error(w, "failed to get artifact", http.StatusInternalServerError) 170 return 171 } 172 173 if len(artifacts) != 1 { 174 + l.Error("too many or too few artifacts found") 175 http.Error(w, "artifact not found", http.StatusNotFound) 176 return 177 } ··· 180 181 ownerId, err := rp.idResolver.ResolveIdent(r.Context(), f.Did) 182 if err != nil { 183 + l.Error("failed to resolve repo owner did", f.Did, "err", err) 184 http.Error(w, "repository owner not found", http.StatusNotFound) 185 return 186 } ··· 194 195 req, err := http.NewRequest(http.MethodGet, url.String(), nil) 196 if err != nil { 197 + l.Error("failed to create request", "err", err) 198 http.Error(w, "failed to create request", http.StatusInternalServerError) 199 return 200 } ··· 202 203 resp, err := http.DefaultClient.Do(req) 204 if err != nil { 205 + l.Error("failed to make request", "err", err) 206 http.Error(w, "failed to make request to PDS", http.StatusInternalServerError) 207 return 208 } ··· 218 219 // stream the body directly to the client 220 if _, err := io.Copy(w, resp.Body); err != nil { 221 + l.Error("error streaming response to client:", "err", err) 222 } 223 } 224 225 // TODO: proper statuses here on early exit 226 func (rp *Repo) DeleteArtifact(w http.ResponseWriter, r *http.Request) { 227 + l := rp.logger.With("handler", "DeleteArtifact") 228 + 229 user := rp.oauth.GetMultiAccountUser(r) 230 tagParam := chi.URLParam(r, "tag") 231 filename := chi.URLParam(r, "file") 232 f, err := rp.repoResolver.Resolve(r) 233 if err != nil { 234 + l.Error("failed to get repo and knot", "err", err) 235 return 236 } 237 ··· 246 orm.FilterEq("name", filename), 247 ) 248 if err != nil { 249 + l.Error("failed to get artifacts", "err", err) 250 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 251 return 252 } ··· 258 artifact := artifacts[0] 259 260 if user.Active.Did != artifact.Did { 261 + l.Error("user not authorized to delete artifact", "err", err) 262 rp.pages.Notice(w, "remove", "Unauthorized deletion of artifact.") 263 return 264 } ··· 269 Rkey: artifact.Rkey, 270 }) 271 if err != nil { 272 + l.Error("failed to get blob from pds", "err", err) 273 rp.pages.Notice(w, "remove", "Failed to remove blob from PDS.") 274 return 275 } 276 277 tx, err := rp.db.BeginTx(r.Context(), nil) 278 if err != nil { 279 + l.Error("failed to start tx") 280 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 281 return 282 } ··· 288 orm.FilterEq("name", filename), 289 ) 290 if err != nil { 291 + l.Error("failed to remove artifact record from db", "err", err) 292 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 293 return 294 } 295 296 err = tx.Commit() 297 if err != nil { 298 + l.Error("failed to remove artifact record from db") 299 rp.pages.Notice(w, "remove", "Failed to delete artifact. Try again later.") 300 return 301 } 302 + 303 + l.Info("successfully deleted artifact", "tag", tagParam, "file", filename) 304 305 w.Write([]byte{}) 306 } 307 308 func (rp *Repo) resolveTag(ctx context.Context, f *models.Repo, tagParam string) (*types.TagReference, error) { 309 + l := rp.logger.With("handler", "resolveTag") 310 + 311 tagParam, err := url.QueryUnescape(tagParam) 312 if err != nil { 313 return nil, err ··· 326 xrpcBytes, err := tangled.RepoTags(ctx, xrpcc, "", 0, repo) 327 if err != nil { 328 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 329 + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 330 return nil, xrpcerr 331 } 332 + l.Error("failed to reach knotserver", "err", err) 333 return nil, err 334 } 335 336 var result types.RepoTagsResponse 337 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 338 + l.Error("failed to decode XRPC tags response", "err", err) 339 return nil, err 340 } 341