|
9 | 9 | jsonrpc
|
10 | 10 | [jsonrpc.logger :as logger]
|
11 | 11 | logging
|
| 12 | + repl |
12 | 13 | schema
|
13 | 14 | shutdown)
|
14 | 15 | (:import
|
|
339 | 340 | (injected-entrypoint {:a "A"} ["BLAH=whatever"] "my command")
|
340 | 341 | (injected-entrypoint nil nil "my command")
|
341 | 342 | (injected-entrypoint {:a "A"} nil "my command")
|
342 |
| - (injected-entrypoint nil nil nil) |
343 |
| - ) |
| 343 | + (injected-entrypoint nil nil nil)) |
344 | 344 |
|
345 | 345 | (defn inject-secret-transform [container-definition]
|
346 | 346 | (check-then-pull container-definition)
|
|
350 | 350 | (-> (images {"reference" [(:image container-definition)]})
|
351 | 351 | first))
|
352 | 352 | :Config)
|
353 |
| - real-entrypoint (string/join " " (concat |
354 |
| - (or (:entrypoint container-definition) Entrypoint) |
355 |
| - (or (:command container-definition) Cmd)))] |
| 353 | + real-entrypoint (string/join " " (concat |
| 354 | + (or (:entrypoint container-definition) Entrypoint) |
| 355 | + (or (:command container-definition) Cmd)))] |
356 | 356 | (-> container-definition
|
357 |
| - (assoc :entrypoint ["/bin/sh" "-c" (injected-entrypoint |
358 |
| - (:secrets container-definition) |
359 |
| - (concat |
360 |
| - Env |
361 |
| - (->> (:environment container-definition) |
362 |
| - (map (fn [[k v]] (format "%s=%s" k v))) |
363 |
| - (into []))) |
364 |
| - real-entrypoint)]) |
| 357 | + (assoc :entrypoint ["/bin/sh" "-c" (injected-entrypoint |
| 358 | + (:secrets container-definition) |
| 359 | + (concat |
| 360 | + Env |
| 361 | + (->> (:environment container-definition) |
| 362 | + (map (fn [[k v]] (format "%s=%s" (if (keyword? k) (name k) k) v))) |
| 363 | + (into []))) |
| 364 | + real-entrypoint)]) |
365 | 365 | (dissoc :command))))
|
366 | 366 |
|
367 | 367 | (defn run-streaming-function-with-no-stdin
|
|
604 | 604 | (start x)
|
605 | 605 | (assoc x :socket (write-stdin (:Id x) (:content m)))))
|
606 | 606 |
|
| 607 | +(defn function-call-with-attached-socket |
| 608 | + "create and start a container with an attached socket |
| 609 | + this does not wait for the container to finish |
| 610 | + returns a map with an |
| 611 | + :output-channel for stdout/stderr/:stopped/:timeout/:closed messages |
| 612 | + :write function to write to the stdin of the container" |
| 613 | + [container] |
| 614 | + (check-then-pull container) |
| 615 | + (let [x (docker/create (assoc container |
| 616 | + :opts {:StdinOnce true |
| 617 | + :OpenStdin true |
| 618 | + :AttachStding true})) |
| 619 | + socket-channel (attach-socket (:Id x)) |
| 620 | + c (async/chan) |
| 621 | + output-channel (async/chan)] |
| 622 | + (start x) |
| 623 | + (async/thread (read-loop socket-channel c)) |
| 624 | + (async/go |
| 625 | + (docker/wait x) |
| 626 | + (async/>! c :stopped) |
| 627 | + #_(delete x)) |
| 628 | + (async/go-loop |
| 629 | + [block (async/<! c)] |
| 630 | + (logger/info "background socket read loop " block) |
| 631 | + (cond |
| 632 | + (#{:stopped :timeout} block) |
| 633 | + (do |
| 634 | + (logger/info "socket read loop " block) |
| 635 | + (async/put! output-channel block)) |
| 636 | + (nil? block) |
| 637 | + (async/put! output-channel :closed) |
| 638 | + :else |
| 639 | + (do |
| 640 | + (async/put! output-channel block) |
| 641 | + (recur (async/<! c))))) |
| 642 | + (assoc |
| 643 | + x |
| 644 | + :output-channel output-channel |
| 645 | + :write (fn [s] (write-to-stdin socket-channel s))))) |
| 646 | + |
607 | 647 | (defn finish-call
|
608 | 648 | "This is a blocking call that waits for the container to finish and then returns the output and exit code."
|
609 | 649 | [{:keys [timeout] :or {timeout 10000} :as x}]
|
|
638 | 678 | (delete x)
|
639 | 679 | {}))))
|
640 | 680 |
|
| 681 | +(defn run-in-background-with-one-message [m] |
| 682 | + (let [{:keys [output-channel]} (function-call-with-attached-socket m)] |
| 683 | + (async/go-loop |
| 684 | + [] |
| 685 | + (let [m (async/<! output-channel)] |
| 686 | + (cond |
| 687 | + (#{:timeout} m) |
| 688 | + {:done :timeout :timeout "timeout waiting for message"} |
| 689 | + (#{:stopped :closed} m) |
| 690 | + {:done :exited :pty-output "tool stopped before responding on stdout" :exit-code 1} |
| 691 | + (and (map? m) (contains? m :stdout)) |
| 692 | + {:pty-output (:stdout m) |
| 693 | + :done :running} |
| 694 | + :else |
| 695 | + (do |
| 696 | + (logger/info "background stderr " m) |
| 697 | + (recur))))))) |
| 698 | + |
641 | 699 | (defn run-with-stdin-content
|
642 | 700 | "run container with stdin read from file or from string
|
643 | 701 | this is several engine calls
|
|
665 | 723 | (run-with-stdin-content m)
|
666 | 724 | (true? (:background m))
|
667 | 725 | (run-background-function m)
|
| 726 | + (true? (:background-callback m)) |
| 727 | + (async/<!! (run-in-background-with-one-message m)) |
668 | 728 | :else
|
669 | 729 | (run-function m)))
|
670 | 730 |
|
| 731 | +(comment |
| 732 | + (repl/setup-stdout-logger) |
| 733 | + (run-container |
| 734 | + {:image "vonwig/gdrive:latest" |
| 735 | + :background-callback true |
| 736 | + :workdir "/app" |
| 737 | + :ports ["3000:3000"] |
| 738 | + :volumes ["mcp-gdrive:/gdrive-server"] |
| 739 | + :environment {"GDRIVE_CREDENTIALS_PATH" "/gdrive-server/credentials.json" |
| 740 | + "GDRIVE_OAUTH_PATH" "/secret/google.gcp-oauth.keys.json"} |
| 741 | + :secrets {:google.gcp-oauth.keys.json "GDRIVE"} |
| 742 | + :command ["auth"]})) |
| 743 | + |
671 | 744 | (defn get-login-info-from-desktop-backend
|
672 | 745 | "returns token or nil if not logged in or backend.sock is not available"
|
673 | 746 | []
|
|
0 commit comments