github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/worker/uniter/runner/debug/client.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package debug
     5  
     6  import (
     7  	"encoding/base64"
     8  	"strings"
     9  
    10  	goyaml "gopkg.in/yaml.v1"
    11  )
    12  
    13  type hookArgs struct {
    14  	Hooks []string `yaml:"hooks,omitempty"`
    15  }
    16  
    17  // ClientScript returns a bash script suitable for executing
    18  // on the unit system to intercept hooks via tmux shell.
    19  func ClientScript(c *HooksContext, hooks []string) string {
    20  	// If any hook is "*", then the client is interested in all.
    21  	for _, hook := range hooks {
    22  		if hook == "*" {
    23  			hooks = nil
    24  			break
    25  		}
    26  	}
    27  
    28  	s := strings.Replace(debugHooksClientScript, "{unit_name}", c.Unit, -1)
    29  	s = strings.Replace(s, "{tmux_conf}", tmuxConf, 1)
    30  	s = strings.Replace(s, "{entry_flock}", c.ClientFileLock(), -1)
    31  	s = strings.Replace(s, "{exit_flock}", c.ClientExitFileLock(), -1)
    32  
    33  	yamlArgs := encodeArgs(hooks)
    34  	base64Args := base64.StdEncoding.EncodeToString(yamlArgs)
    35  	s = strings.Replace(s, "{hook_args}", base64Args, 1)
    36  	return s
    37  }
    38  
    39  func encodeArgs(hooks []string) []byte {
    40  	// Marshal to YAML, then encode in base64 to avoid shell escapes.
    41  	yamlArgs, err := goyaml.Marshal(hookArgs{Hooks: hooks})
    42  	if err != nil {
    43  		// This should not happen: we're in full control.
    44  		panic(err)
    45  	}
    46  	return yamlArgs
    47  }
    48  
    49  const debugHooksClientScript = `#!/bin/bash
    50  (
    51  # Lock the juju-<unit>-debug lockfile.
    52  flock -n 8 || (echo "Failed to acquire {entry_flock}: unit is already being debugged" 2>&1; exit 1)
    53  (
    54  # Close the inherited lock FD, or tmux will keep it open.
    55  exec 8>&-
    56  
    57  # Write out the debug-hooks args.
    58  echo "{hook_args}" | base64 -d > {entry_flock}
    59  
    60  # Lock the juju-<unit>-debug-exit lockfile.
    61  flock -n 9 || exit 1
    62  
    63  # Wait for tmux to be installed.
    64  while [ ! -f /usr/bin/tmux ]; do
    65      sleep 1
    66  done
    67  
    68  if [ ! -f ~/.tmux.conf ]; then
    69          if [ -f /usr/share/byobu/profiles/tmux ]; then
    70                  # Use byobu/tmux profile for familiar keybindings and branding
    71                  echo "source-file /usr/share/byobu/profiles/tmux" > ~/.tmux.conf
    72          else
    73                  # Otherwise, use the legacy juju/tmux configuration
    74                  cat > ~/.tmux.conf <<END
    75                  {tmux_conf}
    76  END
    77          fi
    78  fi
    79  
    80  (
    81      # Close the inherited lock FD, or tmux will keep it open.
    82      exec 9>&-
    83      exec tmux new-session -s {unit_name}
    84  )
    85  ) 9>{exit_flock}
    86  ) 8>{entry_flock}
    87  exit $?
    88  `
    89  
    90  const tmuxConf = `
    91  # Status bar
    92  set-option -g status-bg black
    93  set-option -g status-fg white
    94  
    95  set-window-option -g window-status-current-bg red
    96  set-window-option -g window-status-current-attr bright
    97  
    98  set-option -g status-right ''
    99  
   100  # Panes
   101  set-option -g pane-border-fg white
   102  set-option -g pane-active-border-fg white
   103  
   104  # Monitor activity on windows
   105  set-window-option -g monitor-activity on
   106  
   107  # Screen bindings, since people are more familiar with that.
   108  set-option -g prefix C-a
   109  bind C-a last-window
   110  bind a send-key C-a
   111  
   112  bind | split-window -h
   113  bind - split-window -v
   114  
   115  # Fix CTRL-PGUP/PGDOWN for vim
   116  set-window-option -g xterm-keys on
   117  
   118  # Prevent ESC key from adding delay and breaking Vim's ESC > arrow key
   119  set-option -s escape-time 0
   120  `