@@ -16,14 +16,17 @@ import (
1616 "sort"
1717 "strconv"
1818 "strings"
19+ "net/http"
1920
2021 "cloud.google.com/go/storage"
2122 "github.com/frikky/kin-openapi/openapi3"
23+ docker "github.com/docker/docker/client"
2224
2325 //"github.com/satori/go.uuid"
2426 "gopkg.in/yaml.v2"
2527)
2628
29+ var downloadedImages = []string {}
2730var pythonAllowed = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"
2831var pythonReplacements = map [string ]string {
2932 "[" : "" ,
@@ -3771,3 +3774,125 @@ func RemoveJsonValues(input []byte, depth int64) ([]byte, string, error) {
37713774
37723775 return input , keyToken , nil
37733776}
3777+
3778+ func DownloadDockerImageBackend (topClient * http.Client , imageName string ) error {
3779+ // Check environment SHUFFLE_AUTO_IMAGE_DOWNLOAD
3780+ if os .Getenv ("SHUFFLE_AUTO_IMAGE_DOWNLOAD" ) == "false" {
3781+ log .Printf ("[DEBUG] SHUFFLE_AUTO_IMAGE_DOWNLOAD is false. Not downloading image %s" , imageName )
3782+ return nil
3783+ }
3784+
3785+ if ArrayContains (downloadedImages , imageName ) && project .Environment == "worker" {
3786+ log .Printf ("[DEBUG] Image %s already downloaded - not re-downloading. This only applies to workers." , imageName )
3787+ return nil
3788+ }
3789+
3790+ baseUrl := os .Getenv ("BASE_URL" )
3791+ log .Printf ("[DEBUG] Trying to download image %s from backend %s as it doesn't exist. All images: %#v" , imageName , baseUrl , downloadedImages )
3792+
3793+ downloadedImages = append (downloadedImages , imageName )
3794+
3795+ data := fmt .Sprintf (`{"name": "%s"}` , imageName )
3796+ dockerImgUrl := fmt .Sprintf ("%s/api/v1/get_docker_image" , baseUrl )
3797+
3798+ req , err := http .NewRequest (
3799+ "POST" ,
3800+ dockerImgUrl ,
3801+ bytes .NewBuffer ([]byte (data )),
3802+ )
3803+
3804+ // Specific to the worker
3805+ authorization := os .Getenv ("AUTHORIZATION" )
3806+ if len (authorization ) > 0 {
3807+ req .Header .Add ("Authorization" , fmt .Sprintf ("Bearer %s" , authorization ))
3808+ } else {
3809+ // Specific to Orborus auth (org + auth) -> environment auth
3810+ authorization = os .Getenv ("AUTH" )
3811+ if len (authorization ) > 0 {
3812+ log .Printf ("[DEBUG] Found Orborus environment auth - adding to header." )
3813+ req .Header .Add ("Authorization" , fmt .Sprintf ("Bearer %s" , authorization ))
3814+
3815+ org := os .Getenv ("ORG" )
3816+ if len (org ) > 0 {
3817+ req .Header .Add ("Org-Id" , org )
3818+ }
3819+
3820+ } else {
3821+ log .Printf ("[WARNING] No auth found - running backend download without it." )
3822+ }
3823+ }
3824+
3825+ newresp , err := topClient .Do (req )
3826+ if err != nil {
3827+ log .Printf ("[ERROR] Failed download request for %s: %s" , imageName , err )
3828+ return err
3829+ }
3830+
3831+ defer newresp .Body .Close ()
3832+ if newresp .StatusCode != 200 {
3833+ log .Printf ("[ERROR] Docker download for image %s (backend) StatusCode (1): %d" , imageName , newresp .StatusCode )
3834+ return errors .New (fmt .Sprintf ("Failed to get image - status code %d" , newresp .StatusCode ))
3835+ }
3836+
3837+ newImageName := strings .Replace (imageName , "/" , "_" , - 1 )
3838+ newFileName := newImageName + ".tar"
3839+
3840+ tar , err := os .Create (newFileName )
3841+ if err != nil {
3842+ log .Printf ("[WARNING] Failed creating file: %s" , err )
3843+ return err
3844+ }
3845+
3846+ defer tar .Close ()
3847+ _ , err = io .Copy (tar , newresp .Body )
3848+ if err != nil {
3849+ log .Printf ("[WARNING] Failed response body copying: %s" , err )
3850+ return err
3851+ }
3852+ tar .Seek (0 , 0 )
3853+
3854+ dockercli , err := docker .NewEnvClient ()
3855+ if err != nil {
3856+ log .Printf ("[ERROR] Unable to create docker client (3): %s" , err )
3857+ return err
3858+ }
3859+
3860+ defer dockercli .Close ()
3861+
3862+ imageLoadResponse , err := dockercli .ImageLoad (context .Background (), tar , true )
3863+ if err != nil {
3864+ log .Printf ("[ERROR] Error loading images: %s" , err )
3865+ return err
3866+ }
3867+
3868+ defer imageLoadResponse .Body .Close ()
3869+ body , err := ioutil .ReadAll (imageLoadResponse .Body )
3870+ if err != nil {
3871+ log .Printf ("[ERROR] Error reading: %s" , err )
3872+ return err
3873+ }
3874+
3875+ if strings .Contains (string (body ), "no such file" ) {
3876+ return errors .New (string (body ))
3877+ }
3878+
3879+ baseTag := strings .Split (imageName , ":" )
3880+ if len (baseTag ) > 1 {
3881+ tag := baseTag [1 ]
3882+ log .Printf ("[DEBUG] Creating tag copies of downloaded containers from tag %s" , tag )
3883+
3884+ // Remapping
3885+ ctx := context .Background ()
3886+ dockercli .ImageTag (ctx , imageName , fmt .Sprintf ("frikky/shuffle:%s" , tag ))
3887+ dockercli .ImageTag (ctx , imageName , fmt .Sprintf ("registry.hub.docker.com/frikky/shuffle:%s" , tag ))
3888+
3889+ downloadedImages = append (downloadedImages , fmt .Sprintf ("frikky/shuffle:%s" , tag ))
3890+ downloadedImages = append (downloadedImages , fmt .Sprintf ("registry.hub.docker.com/frikky/shuffle:%s" , tag ))
3891+
3892+ }
3893+
3894+ os .Remove (newFileName )
3895+
3896+ log .Printf ("[INFO] Successfully loaded image %s: %s" , imageName , string (body ))
3897+ return nil
3898+ }
0 commit comments