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