Skip to content

Commit 4722e6d

Browse files
ilopezlunadoringeman
authored andcommitted
Download GGUF, package as Docker Model and push it to Hub (docker#87)
* Use username + pass auth if DOCKER_USERNAME & DOCKER_PASSWORD are defined * Added GHA to package and push a model * Install certs * Don't initialize client twice
1 parent 5afe628 commit 4722e6d

2 files changed

Lines changed: 65 additions & 13 deletions

File tree

pkg/distribution/distribution/client.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ type options struct {
3636
logger *logrus.Entry
3737
transport http.RoundTripper
3838
userAgent string
39+
username string
40+
password string
3941
}
4042

4143
// WithStoreRootPath sets the store root path
@@ -74,6 +76,16 @@ func WithUserAgent(ua string) Option {
7476
}
7577
}
7678

79+
// WithRegistryAuth sets the registry authentication credentials
80+
func WithRegistryAuth(username, password string) Option {
81+
return func(o *options) {
82+
if username != "" && password != "" {
83+
o.username = username
84+
o.password = password
85+
}
86+
}
87+
}
88+
7789
func defaultOptions() *options {
7890
return &options{
7991
logger: logrus.NewEntry(logrus.StandardLogger()),
@@ -100,14 +112,22 @@ func NewClient(opts ...Option) (*Client, error) {
100112
return nil, fmt.Errorf("initializing store: %w", err)
101113
}
102114

115+
// Create registry client options
116+
registryOpts := []registry.ClientOption{
117+
registry.WithTransport(options.transport),
118+
registry.WithUserAgent(options.userAgent),
119+
}
120+
121+
// Add auth if credentials are provided
122+
if options.username != "" && options.password != "" {
123+
registryOpts = append(registryOpts, registry.WithAuthConfig(options.username, options.password))
124+
}
125+
103126
options.logger.Infoln("Successfully initialized store")
104127
return &Client{
105-
store: s,
106-
log: options.logger,
107-
registry: registry.NewClient(
108-
registry.WithTransport(options.transport),
109-
registry.WithUserAgent(options.userAgent),
110-
),
128+
store: s,
129+
log: options.logger,
130+
registry: registry.NewClient(registryOpts...),
111131
}, nil
112132
}
113133

pkg/distribution/registry/client.go

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Client struct {
2626
transport http.RoundTripper
2727
userAgent string
2828
keychain authn.Keychain
29+
auth authn.Authenticator
2930
}
3031

3132
type ClientOption func(*Client)
@@ -46,6 +47,17 @@ func WithUserAgent(userAgent string) ClientOption {
4647
}
4748
}
4849

50+
func WithAuthConfig(username, password string) ClientOption {
51+
return func(c *Client) {
52+
if username != "" && password != "" {
53+
c.auth = &authn.Basic{
54+
Username: username,
55+
Password: password,
56+
}
57+
}
58+
}
59+
}
60+
4961
func NewClient(opts ...ClientOption) *Client {
5062
client := &Client{
5163
transport: remote.DefaultTransport,
@@ -65,13 +77,22 @@ func (c *Client) Model(ctx context.Context, reference string) (types.ModelArtifa
6577
return nil, NewReferenceError(reference, err)
6678
}
6779

68-
// Return the artifact at the given reference
69-
remoteImg, err := remote.Image(ref,
80+
// Set up authentication options
81+
authOpts := []remote.Option{
7082
remote.WithContext(ctx),
71-
remote.WithAuthFromKeychain(c.keychain),
7283
remote.WithTransport(c.transport),
7384
remote.WithUserAgent(c.userAgent),
74-
)
85+
}
86+
87+
// Use direct auth if provided, otherwise fall back to keychain
88+
if c.auth != nil {
89+
authOpts = append(authOpts, remote.WithAuth(c.auth))
90+
} else {
91+
authOpts = append(authOpts, remote.WithAuthFromKeychain(c.keychain))
92+
}
93+
94+
// Return the artifact at the given reference
95+
remoteImg, err := remote.Image(ref, authOpts...)
7596
if err != nil {
7697
errStr := err.Error()
7798
if strings.Contains(errStr, "UNAUTHORIZED") {
@@ -93,6 +114,7 @@ type Target struct {
93114
transport http.RoundTripper
94115
userAgent string
95116
keychain authn.Keychain
117+
auth authn.Authenticator
96118
}
97119

98120
func (c *Client) NewTarget(tag string) (*Target, error) {
@@ -105,20 +127,30 @@ func (c *Client) NewTarget(tag string) (*Target, error) {
105127
transport: c.transport,
106128
userAgent: c.userAgent,
107129
keychain: c.keychain,
130+
auth: c.auth,
108131
}, nil
109132
}
110133

111134
func (t *Target) Write(ctx context.Context, model types.ModelArtifact, progressWriter io.Writer) error {
112135
pr := progress.NewProgressReporter(progressWriter, progress.PushMsg, nil)
113136
defer pr.Wait()
114137

115-
if err := remote.Write(t.reference, model,
138+
// Set up authentication options
139+
authOpts := []remote.Option{
116140
remote.WithContext(ctx),
117-
remote.WithAuthFromKeychain(t.keychain),
118141
remote.WithTransport(t.transport),
119142
remote.WithUserAgent(t.userAgent),
120143
remote.WithProgress(pr.Updates()),
121-
); err != nil {
144+
}
145+
146+
// Use direct auth if provided, otherwise fall back to keychain
147+
if t.auth != nil {
148+
authOpts = append(authOpts, remote.WithAuth(t.auth))
149+
} else {
150+
authOpts = append(authOpts, remote.WithAuthFromKeychain(t.keychain))
151+
}
152+
153+
if err := remote.Write(t.reference, model, authOpts...); err != nil {
122154
return fmt.Errorf("write to registry %q: %w", t.reference.String(), err)
123155
}
124156
return nil

0 commit comments

Comments
 (0)