guix-containerize 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #!guile \
  2. --no-auto-compile -s
  3. !#
  4. ;; This is an example Guix containerization wrapper.
  5. (use-modules (srfi srfi-1)
  6. (ice-9 receive))
  7. (define program-command "unrar")
  8. (define program-package "unrar")
  9. (define empty-dir "/tmp/empty")
  10. (define user "foo")
  11. (define (usage)
  12. (display
  13. (format #f "Usage: ~a COMMAND [OPTIONS] ARCHIVE [FILES...]
  14. [@LISTFILES...] [OUTPUT-DIR/]
  15. Run program in a container. Within the container, the archive is read-only and
  16. the OUTPUT-DIR is shared read-write.
  17. OUTPUT-DIR must end with a '/'. If unspecified, current directory is used.
  18. See below for the original program options:
  19. "
  20. (first (command-line))))
  21. (let ((command-line `("guix" "environment"
  22. "--pure"
  23. ,(string-append "--user=" user)
  24. "--container"
  25. "--ad-hoc" program-package
  26. "--"
  27. program-command "h")))
  28. (run-command-line command-line)))
  29. (define (parse-args)
  30. (let ((args (command-line))
  31. (command "")
  32. (switches '())
  33. (archive "")
  34. (files '())
  35. (output-directory (getcwd)))
  36. ;; Skip caller.
  37. (set! args (cdr args))
  38. ;; Check for help.
  39. (when (and (not (null? args))
  40. (or (string=? (first args) "-h")
  41. (string=? (first args) "--help")))
  42. (usage)
  43. (exit #t))
  44. ;; Command.
  45. (unless (null? args)
  46. (set! command (first args))
  47. (set! args (cdr args)))
  48. ;; Switches.
  49. (while (and (not (null? args))
  50. (string=? (string-take (first args) 1) "-"))
  51. (set! switches (append (list (first args)) files))
  52. (set! args (cdr args)))
  53. (set! switches (reverse! switches))
  54. ;; Archive.
  55. (unless (null? args)
  56. (set! archive (first args))
  57. (set! args (cdr args)))
  58. ;; Files and filelists.
  59. (while (and (not (null? args))
  60. (not (string=? (string-take-right (first args) 1) "/")))
  61. (set! files (append (list (first args)) files))
  62. (set! args (cdr args)))
  63. (set! files (reverse! files))
  64. ;; Output dir.
  65. (unless (null? args)
  66. (set! output-directory (first args))
  67. (set! args (cdr args)))
  68. ;; Handy error checking while we are at it.
  69. (unless (null? args)
  70. (warn "Possible extraneous arguments:" args))
  71. (values command switches archive files output-directory)))
  72. (define (expose file)
  73. (string-append "--expose=" file "=" (basename file)))
  74. (define (run-command-line command-line)
  75. ;; TODO: Use guix' mkdir-p?
  76. (unless (file-exists? empty-dir)
  77. (mkdir empty-dir))
  78. (apply system* command-line)
  79. (rmdir empty-dir))
  80. (define (main)
  81. (receive (command switches archive files output-directory)
  82. (parse-args)
  83. (when (or (string=? command "")
  84. (string=? archive ""))
  85. (display "Both COMMAND and ARCHIVE arguments are required")
  86. (newline)
  87. (usage)
  88. (exit #f))
  89. (let ((command-line `("guix" "environment"
  90. "--pure"
  91. ,(string-append "--user=" user)
  92. "--container"
  93. ,(expose archive)
  94. ,@(map expose files)
  95. ,(string-append "--share=" output-directory "=" (basename output-directory))
  96. "--ad-hoc" program-package
  97. "--"
  98. program-command
  99. ,command
  100. ,@switches
  101. ,(basename archive)
  102. ,@(map basename files)
  103. ;; TODO: This is not the right
  104. ,(string-append (basename output-directory) "/")
  105. )))
  106. (display (format #f "Running command: ~a" command-line))
  107. (newline)
  108. (newline)
  109. (run-command-line command-line))))
  110. (main)