@@ -4,39 +4,19 @@ import (
44 "archive/tar"
55 "bytes"
66 "context"
7- "errors"
87 "io"
98 "net/http"
10- "net/url"
119 "os"
1210 "path/filepath"
13- "strconv"
14- "strings"
15-
16- version "github.com/aquasecurity/go-pep440-version"
1711
1812 "github.com/replicate/cog/pkg/api"
1913 "github.com/replicate/cog/pkg/config"
20- "github.com/replicate/cog/pkg/dockercontext"
2114 "github.com/replicate/cog/pkg/dockerignore"
22- "github.com/replicate/cog/pkg/env"
23- "github.com/replicate/cog/pkg/requirements"
24- "github.com/replicate/cog/pkg/util"
25- "github.com/replicate/cog/pkg/util/console"
26- "github.com/replicate/cog/pkg/util/files"
27- )
28-
29- const EtagHeader = "etag"
30-
31- var (
32- ErrorBadStatus = errors .New ("Bad status from pipelines-runtime requirements.txt endpoint" )
33- ErrorPythonPackage = errors .New ("Python package not available in pipelines runtime" )
34- ErrorPythonPackages = errors .New ("Python packages is not supported in pipelines runtime" )
35- ErrorETagHeaderNotFound = errors .New ("ETag header was not found on pipelines runtime requirements.txt" )
15+ "github.com/replicate/cog/pkg/procedure"
3616)
3717
3818func PipelinePush (ctx context.Context , image string , projectDir string , apiClient * api.Client , client * http.Client , cfg * config.Config ) error {
39- err := validateRequirements (projectDir , client , cfg )
19+ err := procedure . Validate (projectDir , client , cfg , false )
4020 if err != nil {
4121 return err
4222 }
@@ -104,145 +84,3 @@ func createTarball(folder string) (*bytes.Buffer, error) {
10484
10585 return & buf , nil
10686}
107-
108- func downloadRequirements (projectDir string , client * http.Client ) (string , error ) {
109- tmpDir , err := dockercontext .CogBuildArtifactsDirPath (projectDir )
110- if err != nil {
111- return "" , err
112- }
113- url := requirementsURL ()
114-
115- resp , err := client .Head (url .String ())
116- if err != nil {
117- return "" , err
118- }
119- defer resp .Body .Close ()
120- exists := false
121- var requirementsFilePath string
122- if resp .StatusCode >= 400 {
123- console .Warn ("Failed to fetch HEAD for pipelines-runtime requirements.txt" )
124- } else {
125- etag := strings .ReplaceAll (filepath .Base (resp .Header .Get (EtagHeader )), "\" " , "" )
126- requirementsFilePath = filepath .Join (tmpDir , "pipelines_runtime_requirements_" + etag + ".txt" )
127- exists , err = files .Exists (requirementsFilePath )
128- if err != nil {
129- return "" , err
130- }
131- }
132-
133- if ! exists {
134- resp , err = client .Get (url .String ())
135- if err != nil {
136- return "" , err
137- }
138-
139- if resp .StatusCode >= 400 {
140- return "" , util .WrapError (ErrorBadStatus , strconv .Itoa (resp .StatusCode ))
141- }
142-
143- etag := strings .ReplaceAll (filepath .Base (resp .Header .Get (EtagHeader )), "\" " , "" )
144- if etag == "." {
145- return "" , ErrorETagHeaderNotFound
146- }
147- requirementsFilePath = filepath .Join (tmpDir , "pipelines_runtime_requirements_" + etag + ".txt" )
148-
149- file , err := os .Create (requirementsFilePath )
150- if err != nil {
151- console .Info ("CREATION FAILED!" )
152- return "" , err
153- }
154- defer file .Close ()
155-
156- _ , err = io .Copy (file , resp .Body )
157- if err != nil {
158- return "" , err
159- }
160- }
161-
162- return requirementsFilePath , nil
163- }
164-
165- func requirementsURL () url.URL {
166- requirementsURL := pipelinesRuntimeBaseURL ()
167- requirementsURL .Path = "requirements.txt"
168- return requirementsURL
169- }
170-
171- func pipelinesRuntimeBaseURL () url.URL {
172- return url.URL {
173- Scheme : env .SchemeFromEnvironment (),
174- Host : env .PipelinesRuntimeHostFromEnvironment (),
175- }
176- }
177-
178- func validateRequirements (projectDir string , client * http.Client , cfg * config.Config ) error {
179- if len (cfg .Build .PythonPackages ) > 0 {
180- return ErrorPythonPackages
181- }
182-
183- if cfg .Build .PythonRequirements == "" {
184- return nil
185- }
186-
187- requirementsFilePath , err := downloadRequirements (projectDir , client )
188- if err != nil {
189- return err
190- }
191-
192- pipelineRequirements , err := requirements .ReadRequirements (requirementsFilePath )
193- if err != nil {
194- return err
195- }
196-
197- projectRequirements , err := requirements .ReadRequirements (cfg .RequirementsFile (projectDir ))
198- if err != nil {
199- return err
200- }
201-
202- for _ , projectRequirement := range projectRequirements {
203- projectPackage := requirements .PackageName (projectRequirement )
204- projectVersionSpecifier := requirements .VersionSpecifier (projectRequirement )
205- // Continue in case the project does not specify a specific version
206- if projectVersionSpecifier == "" {
207- continue
208- }
209- found := false
210- for _ , pipelineRequirement := range pipelineRequirements {
211- if pipelineRequirement == projectRequirement {
212- found = true
213- break
214- }
215- if strings .Contains (pipelineRequirement , "@" ) {
216- continue
217- }
218- pipelinePackage , pipelineVersion , _ , _ , err := requirements .SplitPinnedPythonRequirement (pipelineRequirement )
219- if err != nil {
220- return err
221- }
222- if pipelinePackage == projectPackage {
223- if pipelineVersion == "" {
224- found = true
225- } else {
226- pipelineVersion , err := version .Parse (pipelineVersion )
227- if err != nil {
228- return err
229- }
230- specifier , err := version .NewSpecifiers (projectVersionSpecifier )
231- if err != nil {
232- return err
233- }
234- if specifier .Check (pipelineVersion ) {
235- found = true
236- break
237- }
238- }
239- break
240- }
241- }
242- if ! found {
243- return util .WrapError (ErrorPythonPackage , projectRequirement )
244- }
245- }
246-
247- return nil
248- }
0 commit comments