66 "os"
77 "path"
88 "strconv"
9+ "time"
910
1011 "al.essio.dev/pkg/shellescape"
1112 "github.com/k0sproject/k0sctl/pkg/apis/k0sctl.k0sproject.io/v1beta1"
@@ -124,12 +125,14 @@ func (p *UploadFiles) uploadFile(h *cluster.Host, f *cluster.UploadFile) error {
124125 return err
125126 }
126127
128+ var stat os.FileInfo
129+ var err error
127130 if h .FileChanged (src , dest ) {
128- err := p . Wet ( h , fmt . Sprintf ( "upload file %s => %s" , src , dest ), func () error {
129- stat , err := os . Stat ( src )
130- if err != nil {
131- return fmt . Errorf ( "failed to stat local file %s: %w" , src , err )
132- }
131+ stat , err = os . Stat ( src )
132+ if err != nil {
133+ return fmt . Errorf ( "failed to stat local file %s: %w" , src , err )
134+ }
135+ err = p . Wet ( h , fmt . Sprintf ( "upload file %s => %s" , src , dest ), func () error {
133136 return h .Upload (path .Join (f .Base , s .Path ), dest , stat .Mode (), exec .Sudo (h ), exec .LogError (true ))
134137 })
135138 if err != nil {
@@ -139,33 +142,16 @@ func (p *UploadFiles) uploadFile(h *cluster.Host, f *cluster.UploadFile) error {
139142 log .Infof ("%s: file already exists and hasn't been changed, skipping upload" , h )
140143 }
141144
142- if owner != "" {
143- err := p .Wet (h , fmt .Sprintf ("set owner for %s to %s" , dest , owner ), func () error {
144- log .Debugf ("%s: setting owner %s for %s" , h , owner , dest )
145- return h .Execf (`chown %s %s` , shellescape .Quote (owner ), shellescape .Quote (dest ), exec .Sudo (h ))
146- })
145+ if stat == nil {
146+ stat , err = os .Stat (src )
147147 if err != nil {
148- return err
148+ return fmt . Errorf ( "failed to stat %s: %w" , src , err )
149149 }
150150 }
151- err := p .Wet (h , fmt .Sprintf ("set permissions for %s to %s" , dest , s .PermMode ), func () error {
152- log .Debugf ("%s: setting permissions %s for %s" , h , s .PermMode , dest )
153- return h .Configurer .Chmod (h , dest , s .PermMode , exec .Sudo (h ))
154- })
155- if err != nil {
151+ modTime := stat .ModTime ()
152+ if err := p .applyFileMetadata (h , dest , owner , s .PermMode , & modTime ); err != nil {
156153 return err
157154 }
158- stat , err := os .Stat (src )
159- if err != nil {
160- return fmt .Errorf ("failed to stat %s: %s" , src , err )
161- }
162- err = p .Wet (h , fmt .Sprintf ("set timestamp for %s to %s" , dest , stat .ModTime ()), func () error {
163- log .Debugf ("%s: touching %s" , h , dest )
164- return h .Configurer .Touch (h , dest , stat .ModTime (), exec .Sudo (h ))
165- })
166- if err != nil {
167- return fmt .Errorf ("failed to touch %s: %w" , dest , err )
168- }
169155 }
170156
171157 return nil
@@ -209,17 +195,7 @@ func (p *UploadFiles) uploadData(h *cluster.Host, f *cluster.UploadFile) error {
209195 return err
210196 }
211197
212- if owner != "" {
213- err := p .Wet (h , fmt .Sprintf ("set owner for %s to %s" , dest , owner ), func () error {
214- log .Debugf ("%s: setting owner %s for %s" , h , owner , dest )
215- return h .Execf (`chown %s %s` , shellescape .Quote (owner ), shellescape .Quote (dest ), exec .Sudo (h ))
216- })
217- if err != nil {
218- return err
219- }
220- }
221-
222- return nil
198+ return p .applyFileMetadata (h , dest , owner , "" , nil )
223199}
224200
225201func (p * UploadFiles ) uploadURL (h * cluster.Host , f * cluster.UploadFile ) error {
@@ -238,24 +214,44 @@ func (p *UploadFiles) uploadURL(h *cluster.Host, f *cluster.UploadFile) error {
238214 return err
239215 }
240216
217+ perm := ""
241218 if f .PermString != "" {
242- err := p .Wet (h , fmt .Sprintf ("set permissions for %s to %s" , f .DestinationFile , f .PermString ), func () error {
243- return h .Configurer .Chmod (h , f .DestinationFile , f .PermString , exec .Sudo (h ))
219+ perm = f .PermString
220+ }
221+
222+ return p .applyFileMetadata (h , f .DestinationFile , owner , perm , nil )
223+ }
224+
225+ func (p * UploadFiles ) applyFileMetadata (h * cluster.Host , dest , owner , perm string , timestamp * time.Time ) error {
226+ if owner != "" {
227+ err := p .Wet (h , fmt .Sprintf ("set owner for %s to %s" , dest , owner ), func () error {
228+ log .Debugf ("%s: setting owner %s for %s" , h , owner , dest )
229+ return h .Execf (`chown %s %s` , shellescape .Quote (owner ), shellescape .Quote (dest ), exec .Sudo (h ))
244230 })
245231 if err != nil {
246232 return err
247233 }
248234 }
249235
250- if owner != "" {
251- err := p .Wet (h , fmt .Sprintf ("set owner for %s to %s" , f . DestinationFile , owner ), func () error {
252- log .Debugf ("%s: setting owner %s for %s" , h , owner , f . DestinationFile )
253- return h .Execf ( `chown %s %s` , shellescape . Quote ( owner ), shellescape . Quote ( f . DestinationFile ) , exec .Sudo (h ))
236+ if perm != "" {
237+ err := p .Wet (h , fmt .Sprintf ("set permissions for %s to %s" , dest , perm ), func () error {
238+ log .Debugf ("%s: setting permissions %s for %s" , h , perm , dest )
239+ return h .Configurer . Chmod ( h , dest , perm , exec .Sudo (h ))
254240 })
255241 if err != nil {
256242 return err
257243 }
258244 }
259245
246+ if timestamp != nil {
247+ err := p .Wet (h , fmt .Sprintf ("set timestamp for %s to %s" , dest , timestamp .String ()), func () error {
248+ log .Debugf ("%s: touching %s" , h , dest )
249+ return h .Configurer .Touch (h , dest , * timestamp , exec .Sudo (h ))
250+ })
251+ if err != nil {
252+ return fmt .Errorf ("failed to touch %s: %w" , dest , err )
253+ }
254+ }
255+
260256 return nil
261257}
0 commit comments