2020-02-06 11:47:45 +02:00
package docker
import (
"fmt"
"io"
"net/url"
"strings"
pkgutil "github.com/GoogleContainerTools/container-diff/pkg/util"
"github.com/google/go-containerregistry/pkg/legacy/tarball"
"github.com/google/go-containerregistry/pkg/name"
)
// Client defines an docker client object
type Client struct {
imageName string
registryURL string
localPath string
includeLayers bool
}
// ClientOptions defines the options to be set on the client
type ClientOptions struct {
ImageName string
RegistryURL string
LocalPath string
IncludeLayers bool
}
//Download interface for download an image to a local path
type Download interface {
GetImageSource ( ) ( string , error )
DownloadImageToPath ( imageSource , filePath string ) ( pkgutil . Image , error )
2020-02-06 12:14:11 +02:00
TarImage ( writer io . Writer , image pkgutil . Image ) error
2020-02-06 11:47:45 +02:00
}
// SetOptions sets options used for the docker client
func ( c * Client ) SetOptions ( options ClientOptions ) {
c . imageName = options . ImageName
c . registryURL = options . RegistryURL
c . includeLayers = options . IncludeLayers
c . localPath = options . LocalPath
}
const (
daemonPrefix = "daemon://"
remotePrefix = "remote://"
)
//GetImageSource get the image source from client attributes (localPath, imageName, registryURL)
func ( c * Client ) GetImageSource ( ) ( string , error ) {
imageSource := c . imageName
if len ( c . registryURL ) > 0 && len ( c . localPath ) <= 0 {
registry := c . registryURL
url , _ := url . Parse ( c . registryURL )
//remove protocoll from registryURL to get registry
if len ( url . Scheme ) > 0 {
registry = strings . Replace ( c . registryURL , fmt . Sprintf ( "%v://" , url . Scheme ) , "" , 1 )
}
if strings . HasSuffix ( registry , "/" ) {
imageSource = fmt . Sprintf ( "%v%v%v" , remotePrefix , registry , c . imageName )
} else {
imageSource = fmt . Sprintf ( "%v%v/%v" , remotePrefix , registry , c . imageName )
}
} else if len ( c . localPath ) > 0 {
imageSource = c . localPath
if ! pkgutil . IsTar ( c . localPath ) {
imageSource = fmt . Sprintf ( "%v%v" , daemonPrefix , c . localPath )
}
}
if len ( imageSource ) <= 0 {
return imageSource , fmt . Errorf ( "There is no image source for the parameters: (Name: %v, Registry: %v, local Path: %v)" , c . imageName , c . registryURL , c . localPath )
}
return imageSource , nil
}
//DownloadImageToPath download the image to the specified path
func ( c * Client ) DownloadImageToPath ( imageSource , filePath string ) ( pkgutil . Image , error ) {
return pkgutil . GetImage ( imageSource , c . includeLayers , filePath )
}
//TarImage write a tar from the given image
func ( c * Client ) TarImage ( writer io . Writer , image pkgutil . Image ) error {
reference , err := name . ParseReference ( image . Digest . String ( ) , name . WeakValidation )
if err != nil {
return err
}
err = tarball . Write ( reference , image . Image , writer )
if err != nil {
return err
}
return nil
}