Chef install google-cloud-sdk without package manager

A tiny chef snipped to install gcloud without using a package manager (to get the latest version without waiting)

gcloud_version = node["foo"]["google-cloud-sdk_version"]
gcloud_file = "google-cloud-sdk-#{gcloud_version}-linux-x86_64.tar.gz"
gcloud_folder = "https://dl.google.com/dl/cloudsdk/channels/rapid/downloads"
gcloud_installer = "https://dl.google.com/dl/cloudsdk/channels/rapid/install_google_cloud_sdk.bash"
execute "gcloud_install" do
  # clean up ... download installer but select the version we want ... install ... link
  command "rm -rf $CLOUDSDK_INSTALL_DIR/google-cloud-sdk && curl #{gcloud_installer} | sed 's;__SDK_URL_DIR=.*;__SDK_URL_DIR=#{gcloud_folder};' | sed 's/__SDK_TGZ=.*/__SDK_TGZ=#{gcloud_file}/' | bash && ln -sf $CLOUDSDK_INSTALL_DIR/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud"
  env(
    "CLOUDSDK_CORE_DISABLE_PROMPTS" => "true",
    "CLOUDSDK_INSTALL_DIR" => "/opt", # prefix
  )
  not_if { `true && gcloud -v`.include?(gcloud_version) } # ~FC048
end

fast npm install check to ensure it is up to date

Ensures that everyone has npm up to date without running “npm install”
Ideally this should be wrapped as “npm check” command, but we use a ruby/rake based workflow anyway.

  desc 'make sure npm is installed'
  task :ensure_npm do
    expected = JSON.parse(File.read('package-lock.json')).fetch('dependencies')
    satisfied = expected.all? do |name, data|
      expected_version = data.fetch('version')
      pack = "node_modules/#{name}/package.json"
      next unless File.exist?(pack)
      resolved = JSON.parse(File.read(pack))
      resolved.fetch('version') == expected_version || # regular
        resolved.fetch('_resolved') == expected_version # git
    end
    sh "npm install" unless satisfied
  end

Digging into Ruby Hashes with dig_set and dig_fetch

Hash#dig is fun, but sometimes I want to be strict … so I use dig_fetch … and dig_set to set a value without running into nil / MethodMissing errors.

# before
hash.dig(:a, :b, :c) # any of these could be nil ...
hash.fetch(:a).fetch(:b).fetch(:a) # repetitive and only shows last key

# after
hash.dig_fetch(:a, :b, :a)


  Hash.class_eval do
    def dig_fetch(*keys, last, &block)
      block ||= ->(*) { raise KeyError, "key not found: #{(keys << last).inspect}" }
      before = (keys.any? ? dig(*keys) || {} : self)
      before.fetch(last, &block)
    end

    def dig_set(keys, value)
      raise ArgumentError, "No key given" if keys.empty?
      keys = keys.dup
      last = keys.pop
      failed = ->(*) { raise KeyError, "key not found: #{(keys << last).inspect}" }
      nested = keys.inject(self) { |h, k| h.fetch(k, &failed) }
      nested[last] = value
    end
  end

Monitor Dalli Connection Changes + Failures

Memcached servers changing leads to a tiny split-brain scenario since some servers might read from different caches then the others … good to keep an eye on it and alert when it happens too often. Here is a tiny snippet to report when it happens.

# config/initializers/dalli.rb
# Whenever the alive-ness of a server changes we read keys from a different server
# which leads to stale keys on the old server and cache-misses on the new servers
# so this should not happen often
# see lib/dalli/server.rb
#
# reproduce: rails c + Rails.cache.get + zdi memcached stop & start
Dalli::Server.prepend(Module.new do
  def down!
    $statsd.increment "dalli.connection_changed", tags: ["state:down"] unless @down_at
    super
  end

  def up!
    $statsd.increment "dalli.connection_changed", tags: ["state:up"] if @down_at
    super
  end

  def failure!(*)
    $statsd.increment "dalli.failed"
    super
  end
end)