Complete Computing Environment: Shell and Operations Configurations

Table of Contents

(provide 'cce-operations)

Reproducable Assistance

At work, I've been around a long enough time to have a pile of random facts, locations, etc, locked away inside of my head and inside of my Org-Mode, which I have been trying to pull out in ways that are digestable for other folks and other teams.

One of the ways I have found that is super helpful for this, is by simply sharing my terminal sessions that I use to answer questions, since they usually contain neat little tricks, random useful commands and inexplicably complex jq commands that I'll never easily be able to recreate, along with the data that goes with them.

This is a sort of minor form of the reproducible research stuff which I am a big fan of. Indeed, for larger spelunkings, I would like to start just using an org-mode document which I can intersperse links and other information in to.

(setq comint-buffer-maximum-size 1024)
(defcustom cce/answer-shell-hostname nil "Hostname to copy the finalized answer shell to")
(defcustom cce/answer-shell-domain-name nil "Domain which exposes [`cce/answer-shell-hostnames']'s public_html")

(defun cce/answer-shell (topic)
  (interactive "sTopic? ")
  (let ((buffer (get-buffer-create (format "*shell %s-%s*" (format-time-string "%s") topic))))
    (shell buffer)
    (with-current-buffer buffer
      (sit-for 0.5)
      (insert "as-ussh bash")
      (comint-send-input)
      (sit-for 0.5)
      (shell-copy-environment-variable "SSH_AUTH_SOCK"))))

(defun cce/finalize-answer-shell (buffer)
  (interactive "bBuffer? ")
  (let* ((dirname (format "answers/%s.html"
                          (replace-regexp-in-string "\\*shell \\(.*\\)\\*" "\\1"
                                                    (buffer-name (get-buffer buffer)))))
         (file (concat "/ssh:" cce/answer-shell-hostname ":/home/rrix/public_html/" dirname))
         (url (concat "https://" cce/answer-shell-domain-name "/~rrix/" dirname)))
    (with-current-buffer (htmlize-buffer buffer)
      (write-file file))
    (browse-url url)
    (kill-new url)
    (kill-buffer)))

(evil-leader/set-key-for-mode 'shell-mode "f" #'cce/finalize-answer-shell)

EShell

At the end of my day, despite my best intentions I spend a lot of time rooting around on production or production-like environments. At work we make heavy use of production-like development servers for building and testing our code without the need for running 100s of services on developer laptops, mostly macbooks 1, and my workflow needs to incorporate that. Right now I bump between using TMUX 2 for managing terminal sessions but want to move entirely towards using TRAMP 3 and eshell 4 to manage my systems. This means building in some sort of multiplexing system to my eshell workflow as well as setting up easy aliases that make my life less painful.

TRAMP, in particular, is a wonderful piece of kit. I've always been enamored with network transparent file access systems, first with weird FUSE filesystems, then with KDE's KIO 5 system, and TRAMP is the spirit-animal of KIO in many ways. It does a wonderful, if a bit anachronistic, job of managing remote files and integrating flawlessly with the system as a whole. Magit 6, for example, will nlet me feed it /ssh:rrix@rrix.dev:/home/rrix/service as a git repository and it'll treat it exactly as a local one, running the git commands on the remote entirely. In this way, I could actually get my work done on a read-only Chromebook install or something insane like that, with all state held on a devserver. The one major failure of TRAMP is that for large files, such as daily logs, it requires the entire file be slurped down so that it can be inserted in to a buffer. Fixing this or working around it will be necessary for any TRAMP and eshell centric workflows. In the long term, this need is obviated by the move towards more easily searchable log systems, such as ElasticSearch's ELKStack 7, but I should still have a way to view files on remote machines without TRAMP.

Basically, my workflow should make it easy for me to inspect and introspect servers; Things like proced 8 should be working out of the box on any of the hundreds of servers that I maintain on a daily basis.

Core Requirements:

  • remote ssh
  • powerful shell
  • universal aliases and processes
  • Network transparency
(eval-after-load 'eshell (lambda ()
                           (require 'em-smart)

                           (setq eshell-where-to-jump 'begin)
                           (setq eshell-review-quick-commands nil)

                           (setq eshell-smart-space-goes-to-end t)
                           (add-hook 'eshell-mode-hook 'eshell-smart-initialize)

                           (setq eshell-visual-commands '("vi" "screen" "top" "less" "more"
                                                          "lynx" "ncftp" "pine" "tin" "trn"
                                                          "elm" "vim" "nmtui" "alsamixer"
                                                          "ansible-doc"))
                           (setq eshell-visual-subcommands '(("git" "log" "diff" "show")))))
(install-pkgs '(ansible-doc))

Helpful bindings

Browse man page for word at point:

(defun cce/man-at-point ()
  (interactive)
  (man
   (substring-no-properties
    (thing-at-point 'word))))

(global-set-key (kbd "C-h j") 'cce/man-at-point)

Required Tooling

I have some base-expected tooling to be able to do my job, I install those here:

- name: tray items installed
  dnf:
    name: "{{item}}"
    state: installed
  when: ansible_pkg_mgr == "dnf"
  with_items:
  - htop
  - nmap

- name: tray items installed
  apt:
    name: "{{item}}"
    state: installed
  when: ansible_pkg_mgr == "apt"
  with_items:
  - htop
  - nmap

Footnotes:

Author: Ryan Rix

Created: 2017-10-03 Tue 10:06

Validate XHTML 1.0