diff --git a/distro-build-client/installer-exe.rkt b/distro-build-client/installer-exe.rkt index 961cc8a..e47fe1d 100644 --- a/distro-build-client/installer-exe.rkt +++ b/distro-build-client/installer-exe.rkt @@ -3,6 +3,7 @@ racket/list racket/system racket/path + racket/file racket/runtime-path setup/getinfo setup/cross-system) @@ -411,7 +412,7 @@ SectionEnd "-V3")) (system* makensis verbose "installer.nsi"))) -(define (installer-exe human-name base-name versionless? dist-suffix readme) +(define (installer-exe human-name base-name versionless? dist-suffix readme osslsigncode-args) (define makensis (or (case (system-type) [(windows) (or (find-executable-path "makensis.exe") @@ -437,4 +438,19 @@ SectionEnd #:extension-registers (get-extreg "bundle/racket") #:start-menus (get-startmenu "bundle/racket") #:auto-launch (get-auto-launch "bundle/racket")) + (unless (null? osslsigncode-args) + (define unsigned-exe-path (let-values ([(base name dir?) (split-path exe-path)]) + (build-path base "unsigned" name))) + (make-directory* "bundle/unsigned") + (rename-file-or-directory exe-path unsigned-exe-path #t) + (unless (apply system* + (or (find-executable-path (case (system-type) + [(windows) "osslsigncode.exe"] + [else "osslsigncode"])) + (error "cannot find `osslsigncode`")) + (append osslsigncode-args + (list "-n" human-name + "-t" "http://timestamp.verisign.com/scripts/timstamp.dll" + "-in" unsigned-exe-path "-out" exe-path))) + (error "signing failed"))) exe-path) diff --git a/distro-build-client/installer-tgz.rkt b/distro-build-client/installer-tgz.rkt index 5e813e7..b88a61d 100644 --- a/distro-build-client/installer-tgz.rkt +++ b/distro-build-client/installer-tgz.rkt @@ -2,7 +2,8 @@ (require racket/system racket/file racket/format - file/tar) + file/tar + setup/cross-system) (provide installer-tgz) @@ -25,11 +26,22 @@ (parameterize ([current-directory src-dir]) (apply tar-gzip dest #:path-prefix target-dir-name (directory-list)))) -(define (installer-tgz base-name dir-name dist-suffix readme) - (define tgz-path (format "bundle/~a-src~a.tgz" - base-name +(define (installer-tgz source? base-name dir-name dist-suffix readme) + (define tgz-path (format "bundle/~a-~a~a.tgz" + base-name + (if source? + "src" + (get-platform-name)) dist-suffix)) (generate-tgz "bundle/racket" tgz-path dir-name readme) tgz-path) + +(define (get-platform-name) + (case (cross-system-type) + [(windows) + (define-values (base name dir?) (split-path (cross-system-library-subpath #f))) + (format "~a-win32" (bytes->string/utf-8 (path-element->bytes name)))] + [else + (format "~a" (cross-system-library-subpath #f))])) diff --git a/distro-build-client/installer.rkt b/distro-build-client/installer.rkt index c355e0a..aa18689 100644 --- a/distro-build-client/installer.rkt +++ b/distro-build-client/installer.rkt @@ -9,6 +9,7 @@ racket/file racket/path racket/port + net/base64 setup/cross-system "display-time.rkt") @@ -17,12 +18,14 @@ (define release? #f) (define source? #f) (define versionless? #f) +(define tgz? #f) (define mac-pkg? #f) (define upload-to #f) (define upload-desc "") (define download-readme #f) -(define-values (short-human-name human-name base-name dir-name dist-suffix sign-identity) +(define-values (short-human-name human-name base-name dir-name dist-suffix + sign-identity osslsigncode-args-base64) (command-line #:once-each [("--release") "Create a release installer" @@ -31,6 +34,8 @@ (set! source? #t)] [("--versionless") "Avoid version number in names and paths" (set! versionless? #t)] + [("--tgz") "Create a \".tgz\" archive instead of an installer" + (set! tgz? #t)] [("--mac-pkg") "Create a \".pkg\" installer on Mac OS X" (set! mac-pkg? #t)] [("--upload") url "Upload installer" @@ -42,7 +47,7 @@ (unless (string=? readme "") (set! download-readme readme))] #:args - (human-name base-name dir-name dist-suffix sign-identity) + (human-name base-name dir-name dist-suffix sign-identity osslsigncode-args-base64) (values human-name (format "~a v~a" human-name (version)) (if versionless? @@ -55,7 +60,7 @@ (if (string=? dist-suffix "") "" (string-append "-" dist-suffix)) - sign-identity))) + sign-identity osslsigncode-args-base64))) (display-time) @@ -68,22 +73,39 @@ (port->string i) (close-input-port i))))) +(define (unpack-base64-arguments str) + (define p (open-input-bytes (base64-decode (string->bytes/utf-8 str)))) + (define l (read p)) + (unless (and (list? l) + (andmap string? l) + (eof-object? (read p))) + (error 'unpack-base64-arguments + "encoded arguments didn't decode and `read` as a list of strings: ~e" str)) + l) + (define installer-file - (if source? - (installer-tgz base-name dir-name dist-suffix readme) + (if (or source? tgz?) + (installer-tgz source? base-name dir-name dist-suffix readme) (case (cross-system-type) - [(unix) (installer-sh human-name base-name dir-name release? dist-suffix readme)] - [(macosx) (if mac-pkg? - (installer-pkg (if (or release? versionless?) - short-human-name - human-name) - base-name dist-suffix readme sign-identity) - (installer-dmg (if versionless? - short-human-name - human-name) - base-name dist-suffix readme sign-identity))] - [(windows) (installer-exe short-human-name base-name (or release? versionless?) - dist-suffix readme)]))) + [(unix) + (installer-sh human-name base-name dir-name release? dist-suffix readme)] + [(macosx) + (if mac-pkg? + (installer-pkg (if (or release? versionless?) + short-human-name + human-name) + base-name dist-suffix readme sign-identity) + (installer-dmg (if versionless? + short-human-name + human-name) + base-name dist-suffix readme sign-identity))] + [(windows) + (define osslsigncode-args + (and (not (equal? osslsigncode-args-base64 "")) + (unpack-base64-arguments osslsigncode-args-base64))) + (installer-exe short-human-name base-name (or release? versionless?) + dist-suffix readme + osslsigncode-args)]))) (call-with-output-file* (build-path "bundle" "installer.txt") diff --git a/distro-build-doc/distro-build.scrbl b/distro-build-doc/distro-build.scrbl index 7fbb2ca..c5b22e6 100644 --- a/distro-build-doc/distro-build.scrbl +++ b/distro-build-doc/distro-build.scrbl @@ -352,9 +352,14 @@ spaces, etc.): on the value of @racket[#:bits]} @item{@racket[#:sign-identity _string] --- provides an identity to - be passed to @exec{codesign} for code signing on Mac OS X (for all - executables in a distribution), where an empty string disables - signing; the default is @racket[""]} + be passed to @exec{codesign} for code signing on Mac OS X (for a + package or all executables in a distribution), where an empty + string disables signing; the default is @racket[""]} + + @item{@racket[#:osslsigncode-args (list _string ...)] --- provides + arguments for signing a Windows executable using + @exec{osslsigncode}, where @Flag{n}, @Flag{t}, @Flag{in}, and + @Flag{-out} arguments are supplied automatically.} @item{@racket[#:j _integer] --- parallelism for @tt{make} on Unix and Mac OS X and for @exec{raco setup} on all platforms; defaults @@ -408,6 +413,10 @@ spaces, etc.): @filepath{.pkg} for Mac OS X (in single-file format) instead of a @filepath{.dmg}; the default is @racket[#f]} + @item{@racket[#:tgz? _boolean] --- if true, creates a + @filepath{.tgz} archive instead of an installer; the default is + @racket[#f]} + @item{@racket[#:pause-before _nonnegative-real] --- a pause in seconds to wait before starting a machine, which may help a virtual machine avoid confusion from being stopped and started too diff --git a/distro-build-server/config.rkt b/distro-build-server/config.rkt index 1142dd6..1ecf810 100644 --- a/distro-build-server/config.rkt +++ b/distro-build-server/config.rkt @@ -146,6 +146,7 @@ [(#:bits) (or (equal? val 32) (equal? val 64))] [(#:vc) (string? val)] [(#:sign-identity) (string? val)] + [(#:osslsigncode-args) (and (list? val) (andmap string? val))] [(#:timeout) (real? val)] [(#:j) (exact-positive-integer? val)] [(#:repo) (string? val)] @@ -157,6 +158,7 @@ [(#:source-pkgs?) (boolean? val)] [(#:versionless?) (boolean? val)] [(#:mac-pkg?) (boolean? val)] + [(#:tgz?) (boolean? val)] [(#:site-dest) (path-string? val)] [(#:site-help) (hash? val)] [(#:site-title) (string? val)] diff --git a/distro-build-server/drive-clients.rkt b/distro-build-server/drive-clients.rkt index 096f3eb..7df126e 100644 --- a/distro-build-server/drive-clients.rkt +++ b/distro-build-server/drive-clients.rkt @@ -6,6 +6,7 @@ racket/file racket/string racket/path + net/base64 (only-in distro-build/config current-mode site-config? @@ -233,6 +234,10 @@ "\"\\&\\&\"")] [else s])) +(define (pack-base64-arguments args) + (bytes->string/utf-8 (base64-encode (string->bytes/utf-8 (format "~s" args)) + #""))) + (define (client-args c server server-port kind readme) (define desc (client-name c)) (define pkgs (let ([l (get-opt c '#:pkgs)]) @@ -250,12 +255,14 @@ (define dist-suffix (get-opt c '#:dist-suffix "")) (define dist-catalogs (choose-catalogs c '(""))) (define sign-identity (get-opt c '#:sign-identity "")) + (define osslsigncode-args (get-opt c '#:osslsigncode-args)) (define release? (get-opt c '#:release? default-release?)) (define source? (get-opt c '#:source? default-source?)) (define versionless? (get-opt c '#:versionless? default-versionless?)) (define source-pkgs? (get-opt c '#:source-pkgs? source?)) (define source-runtime? (get-opt c '#:source-runtime? source?)) (define mac-pkg? (get-opt c '#:mac-pkg? #f)) + (define tgz? (get-opt c '#:tgz? #f)) (define install-name (get-opt c '#:install-name (if release? "" snapshot-install-name))) @@ -276,6 +283,9 @@ " DIST_SUFFIX=" (q dist-suffix) " DIST_CATALOGS_q=" (qq dist-catalogs kind) " SIGN_IDENTITY=" (q sign-identity) + " OSSLSIGNCODE_ARGS_BASE64=" (q (if osslsigncode-args + (pack-base64-arguments osslsigncode-args) + "")) " INSTALL_NAME=" (q install-name) " BUILD_STAMP=" (q build-stamp) " RELEASE_MODE=" (if release? "--release" (q "")) @@ -285,6 +295,7 @@ (q "--source --no-setup") (q "")) " MAC_PKG_MODE=" (if mac-pkg? "--mac-pkg" (q "")) + " TGZ_MODE=" (if tgz? "--tgz" (q "")) " UPLOAD=http://" server ":" server-port "/upload/" " README=http://" server ":" server-port "/" (q (file-name-from-path readme))))