Module: Xolo::Server::Helpers::FileTransfers
- Defined in:
- lib/xolo/server/helpers/file_transfers.rb
Class Method Summary collapse
-
.included(includer) ⇒ Object
when this module is included.
Instance Method Summary collapse
-
#pkg_is_distribution?(pkg_file) ⇒ Boolean
Check if a package is a Distribution package, if not, it is a component package and can’t be used for MDM deployment.
-
#process_incoming_pkg ⇒ Object
Handle an uploaded pkg installer TODO: wrap this in a thread, it might be very slow for large pkgs.
-
#process_incoming_ssvc_icon ⇒ Object
Store an uploaded self service icon in the title’s directory.
-
#process_incoming_testfile ⇒ Object
upload a file for testing …
-
#upload_to_dist_point(jpkg, pkg_file) ⇒ void
upload a staged pkg to the dist point(s) This will also update the checksum and manifest.
-
#upload_via_tool(jpkg, pkg_file) ⇒ void
upload the pkg with the uploader tool defined in config.
-
#validate_uploaded_pkg(filename) ⇒ String
Confirm and return the extension of the originally uplaoded file, either .pkg or .zip.
Class Method Details
.included(includer) ⇒ Object
when this module is included
28 29 30 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 28 def self.included(includer) Xolo.verbose_include includer, self end |
Instance Method Details
#pkg_is_distribution?(pkg_file) ⇒ Boolean
Check if a package is a Distribution package, if not, it is a component package and can’t be used for MDM deployment.
181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 181 def pkg_is_distribution?(pkg_file) pkg_file = Pathname.new(pkg_file) raise ArgumentError, "pkg_file does not exist or not a file: #{pkg_file}" unless pkg_file.file? tmpdir = Pathname.new(Dir.mktmpdir) workdir = tmpdir + "#{pkg_file.basename}-expanded" system "/usr/sbin/pkgutil --expand #{pkg_file.to_s.shellescape} #{workdir.to_s.shellescape}" workdir.children.map(&:basename).map(&:to_s).include? 'Distribution' ensure tmpdir.rmtree end |
#process_incoming_pkg ⇒ Object
Handle an uploaded pkg installer TODO: wrap this in a thread, it might be very slow for large pkgs. TODO: Also, when threaded, how to report errors? TODO: Split this into smaller methods
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 77 def process_incoming_pkg log_info "Processing uploaded installer package for version '#{params[:version]}' of title '#{params[:title]}'" # the Xolo::Server::Version that owns this pkg version = instantiate_version title: params[:title], version: params[:version] version.lock # is this a re-upload? True if upload_date as any value in it if version.upload_date.pix_empty? action = 'Uploading' re_uploading = false else re_uploading = true action = 'Re-uploading' version.log_change msg: 'Re-uploading pkg file' end # the original uploaded filename orig_filename = params[:file][:filename] log_debug "Incoming pkg file '#{orig_filename}' " file_extname = validate_uploaded_pkg(orig_filename) # Set the jamf_pkg_file, now that we know the extension uploaded_pkg_name = "#{version.jamf_pkg_name}#{file_extname}" log_debug "Jamf: Package filename will be '#{uploaded_pkg_name}'" version.jamf_pkg_file = uploaded_pkg_name # The tempfile created by Sinatra when the pkg was uploaded from xadm tempfile = Pathname.new params[:file][:tempfile].path # The uploaded tmpfile will be staged here before uploading again to # the Jamf Dist Point(s) staged_pkg = Xolo::Server::Title.title_dir(params[:title]) + uploaded_pkg_name # remove any old one that might be there staged_pkg.delete if staged_pkg.file? if need_to_sign?(tempfile) # This will put the signed pkg into the staged_pkg location sign_uploaded_pkg(tempfile, staged_pkg) log_debug "Signing complete, deleting temp file '#{tempfile}'" tempfile.delete if tempfile.file? else log_debug "Uploaded .pkg file doesn't need signing, moving tempfile to '#{staged_pkg.basename}'" # Put the signed pkg into the staged_pkg location tempfile.rename staged_pkg end # upload the pkg with the uploader tool defined in config # This will set the checksum and manifest in the JPackage object upload_to_dist_point(version.jamf_package, staged_pkg) if re_uploading # These must be set before calling wait_to_enable_reinstall_policy version.reupload_date = Time.now version.reuploaded_by = session[:admin] # This will make the version start a thread # that will wait some period of time (to allow for pkg uploads # to complete) before enabling the reinstall policy version.wait_to_enable_reinstall_policy else version.upload_date = Time.now version.uploaded_by = session[:admin] end # make note if the pkg is a Distribution package version.dist_pkg = pkg_is_distribution?(staged_pkg) # save the manifest just in case version.manifest_file.pix_atomic_write(version.jamf_package.manifest) # save the checksum just in case version.sha_512 = version.jamf_package.checksum # don't save the admins local path to the pkg, just the filename they uploaded version.pkg_to_upload = orig_filename # save/update the local data file, since we've done stuff to update it version.save_local_data # log the upload version.log_change msg: "#{action} pkg file '#{staged_pkg.basename}'" # remove the staged pkg and the tempfile staged_pkg.delete tempfile.delete if tempfile.file? rescue => e msg = "#{e.class}: #{e}" log_error msg e.backtrace.each { |line| log_error "..#{line}" } halt 400, { status: 400, error: msg } ensure version.unlock end |
#process_incoming_ssvc_icon ⇒ Object
Store an uploaded self service icon in the title’s directory. It’ll be added to Policies and Patch Policies as needed (increasing the bloat in the database, of course)
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 56 def process_incoming_ssvc_icon filename = params[:file][:filename] tempfile = Pathname.new params[:file][:tempfile].path log_info "Processing uploaded SelfService icon for #{params[:title]}" title = instantiate_title params[:title] title.save_ssvc_icon(tempfile, filename) title.configure_pol_for_self_service if title.self_service rescue => e msg = "#{e.class}: #{e}" log_error msg e.backtrace.each { |line| log_error "..#{line}" } halt 400, { status: 400, error: msg } end |
#process_incoming_testfile ⇒ Object
upload a file for testing … anything
38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 38 def process_incoming_testfile progress 'starting test file upload', log: :debug params[:file][:filename] tempfile = Pathname.new params[:file][:tempfile].path progress "1/3 TempFile is #{tempfile} size is #{tempfile.size}... is it still uploading?", log: :debug sleep 2 progress "2/3 TempFile is #{tempfile} size is #{tempfile.size}... is it still uploading?", log: :debug sleep 2 progress "3/3 TempFile is #{tempfile} size is #{tempfile.size}... is it still uploading?", log: :debug progress 'all done', log: :debug end |
#upload_to_dist_point(jpkg, pkg_file) ⇒ void
This method returns an undefined value.
upload a staged pkg to the dist point(s) This will also update the checksum and manifest.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 203 def upload_to_dist_point(jpkg, pkg_file) if Xolo::Server.config.upload_tool.to_s.downcase == 'api' jpkg.upload pkg_file # this will update the checksum and manifest automatically, and save back to the server log_info "Jamf: Uploaded #{pkg_file.basename} to primary dist point via API, with new checksum and manifest" else log_debug "Jamf: Regenerating manifest for package '#{jpkg.packageName}' from #{pkg_file.basename}" jpkg.generate_manifest(pkg_file) log_debug "Jamf: Recalculating checksum for package '#{jpkg.packageName}' from #{pkg_file.basename}" jpkg.recalculate_checksum(pkg_file) log_info "Jamf: Saving package '#{jpkg.packageName}' with new checksum and manifest" jpkg.save upload_via_tool(jpkg, pkg_file) end end |
#upload_via_tool(jpkg, pkg_file) ⇒ void
This method returns an undefined value.
upload the pkg with the uploader tool defined in config
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 227 def upload_via_tool(jpkg, pkg_file) log_info "Jamf: Uploading #{pkg_file.basename} to dist point(s) via upload tool" tool = Shellwords.escape Xolo::Server.config.upload_tool.to_s jpkg_name = Shellwords.escape jpkg.packageName pkg = Shellwords.escape pkg_file.to_s cmd = "#{tool} #{jpkg_name} #{pkg}" stdouterr, exit_status = Open3.capture2e(cmd) return if exit_status.success? msg = "Uploader tool failed to upload #{pkg_file.basename} to dist point(s): #{stdouterr}" log_error msg raise msg end |
#validate_uploaded_pkg(filename) ⇒ String
Confirm and return the extension of the originally uplaoded file, either .pkg or .zip
250 251 252 253 254 255 256 257 |
# File 'lib/xolo/server/helpers/file_transfers.rb', line 250 def validate_uploaded_pkg(filename) log_debug "Validating pkg file ext for '#{filename}'" file_extname = Pathname.new(filename).extname return file_extname if Xolo::OK_PKG_EXTS.include? file_extname raise "Bad filename '#{filename}'. Package files must end in .pkg or .zip (for old-style bundle packages)" end |