<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xml" href="http://dchua.com//feed.xslt.xml"?><feed xmlns="http://www.w3.org/2005/Atom"><generator uri="http://jekyllrb.com" version="2.1.1">Jekyll</generator><link href="http://dchua.com//feed/index.xml" rel="self" type="application/atom+xml" /><link href="http://dchua.com//" rel="alternate" type="text/html" /><updated>2017-06-28T22:42:19+08:00</updated><id>http://dchua.com//</id><title type="html">David Chua | Dev Notes for a Ruby Server Geek</title><subtitle>Development Notes of a Ruby Server Geek</subtitle><author><name>David Chua</name></author><entry><title type="html">The Signal Pattern</title><link href="http://dchua.com//2017/06/28/the-signal-pattern" rel="alternate" type="text/html" title="The Signal Pattern" /><published>2017-06-28T00:00:00+08:00</published><updated>2017-06-28T22:42:15+08:00</updated><id>http://dchua.com//2017/06/28/the-signal-pattern</id><content type="html" xml:base="http://dchua.com//2017/06/28/the-signal-pattern">&lt;p&gt;The signal pattern can be used to ensure your long-lived processes (ie. servers) are able to handle signals being sent to the process.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
import ...

type Handler struct {
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  w.Write([]byte(`{}`))
}

func main() {

  h := &amp;amp;Handler{}

  sigCh := make(chan os.Signal, 1)
  errCh := make(chan error, 1)

  signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT, syscall.SIGHUP)

  go func() {
    err := http.ListenAndServe(&quot;:3000&quot;, h)
    errCh &amp;lt;- err
  }()

  for {
    select {
    case sig := &amp;lt;-sigCh:
      switch sig {
      case syscall.SIGHUP:
        log.Println(&quot;woot woot sighup &quot;, sig)
        os.Exit(0)
      case syscall.SIGTERM:
        log.Println(&quot;sigterm &quot;, sig)
        os.Exit(0)
      case syscall.SIGINT:
        log.Println(&quot;sig interrupt &quot;, sig)
      }

    case err := &amp;lt;-errCh:
      log.Println(err)
      os.Exit(1)

    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Many thanks to &lt;a href=&quot;http://twitter.com/chuyeow&quot;&gt;@chuyeow&lt;/a&gt; for introducing this pattern to me.&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://golang.org/pkg/os/#Signal&quot;&gt;golang.org - os/signals&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="golang" /><category term="guides" /><category term="pattern" /><category term="signals" /><category term="unix" /><summary type="html">The signal pattern can be used to ensure your long-lived processes (ie. servers) are able to handle signals being sent to the process.</summary></entry><entry><title type="html">Sending your Structs across the wire (tcp connection)</title><link href="http://dchua.com//2017/06/23/sending-your-structs-across-the-wire-(tcp-connection)" rel="alternate" type="text/html" title="Sending your Structs across the wire (tcp connection)" /><published>2017-06-23T00:00:00+08:00</published><updated>2017-06-23T14:56:34+08:00</updated><id>http://dchua.com//2017/06/23/sending-your-structs-across-the-wire-(tcp-connection)</id><content type="html" xml:base="http://dchua.com//2017/06/23/sending-your-structs-across-the-wire-(tcp-connection)">&lt;p&gt;Sending your structs across the wire and receiving them on the other side. Using &lt;code class=&quot;highlighter-rouge&quot;&gt;encoding/gob&lt;/code&gt; can help ensure your data structures can receive it on the other side.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// server.go

package main

import ...

// Create your custom data struct
type Message struct {
  ID   string
  Data string
}

func main() {
  // for purpose of verbosity, I will be removing error handling from this
  // sample code

  server, err  := net.Listen(&quot;tcp&quot;, &quot;:12345&quot;)
  conn, err = server.Accept()

  // create a temp buffer
  tmp := make([]byte, 500)

  // loop through the connection to read incoming connections. If you&#39;re doing by
  // directional, you might want to make this into a seperate go routine
  for {

    _, err = conn.Read(tmp)
    
    // convert bytes into Buffer (which implements io.Reader/io.Writer)
    tmpbuff := bytes.NewBuffer(tmp)

    tmpstruct := new(Message)

    // creates a decoder object
    gobobj := gob.NewDecoder(tmpbuffer)

    // decodes buffer and unmarshals it into a Message struct
    gobobj.decode(tmpstruct)

    // lets print out!
    fmt.Println(tmpstruct) // reflects.TypeOf(tmpstruct) == Message{}

  }

}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// client.go

import ...

type Message struct {
  ID   string
  Data string
}

func main(){
  // lets create the message we want to send accross
  msg := Message{ID: &quot;Yo&quot;, Data: &quot;Hello&quot;}
  bin_buf := new(bytes.Buffer)

  // error handling still truncated
  conn, err

  // create a encoder object
  gobobj := gob.NewEncoder(bin_buf)

  // encode buffer and marshal it into a gob object
  gobobj.Encode(msg)

  conn.Write(bin_buf.Bytes())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://blog.golang.org/gobs-of-data&quot;&gt;Gobs of Data - golang.org&lt;/a&gt;&lt;/strong&gt;*&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://andrewskotzko.com/network-fundamentals-how-messages-flow-through-sockets/&quot;&gt;Network Fundamentals&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="golang" /><category term="guides" /><category term="golang" /><category term="structs" /><category term="encoding" /><summary type="html">Sending your structs across the wire and receiving them on the other side. Using encoding/gob can help ensure your data structures can receive it on the other side.</summary></entry><entry><title type="html">Using S2i like buildpacks to deploy apps</title><link href="http://dchua.com//2017/06/21/using-s2i-like-buildpacks-to-deploy-apps" rel="alternate" type="text/html" title="Using S2i like buildpacks to deploy apps" /><published>2017-06-21T00:00:00+08:00</published><updated>2017-06-22T00:02:39+08:00</updated><id>http://dchua.com//2017/06/21/using-s2i-like-buildpacks-to-deploy-apps</id><content type="html" xml:base="http://dchua.com//2017/06/21/using-s2i-like-buildpacks-to-deploy-apps">&lt;p&gt;Openshift’s S2i (Source-2-image) is a pretty cool replacement to buildpacks using Dockerfiles and &lt;a href=&quot;http://openshift.org&quot;&gt;Openshift&lt;/a&gt;&lt;/p&gt;

&lt;h1 id=&quot;objective&quot;&gt;Objective&lt;/h1&gt;

&lt;p&gt;The goal is to be able to create a container image that contains the necessary application dependencies just by uploading the application code without having to write Dockerfiles.&lt;/p&gt;

&lt;h1 id=&quot;creating-s2i-builder-images&quot;&gt;Creating S2i builder images&lt;/h1&gt;

&lt;p&gt;S2i builder images are the base images that your deploying application will be injected its code/binary into to create a new deployment image.&lt;/p&gt;

&lt;p&gt;An easy way to think about S2i builder images is that it is analogous to Buildpacks in which they set the environment for applications.&lt;/p&gt;

&lt;h2 id=&quot;directory-structure&quot;&gt;Directory Structure&lt;/h2&gt;

&lt;p&gt;S2i builder images have the following directory structure:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/
/s2i/
/s2i/assemble
/s2i/usage
/s2i/run
Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Key details to note is that when you create a new build that uses an s2i builder image as its base layer, your source code will be injected into &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp/src&lt;/code&gt; of the builder image. You will need to keep this in mind when you write your &lt;code class=&quot;highlighter-rouge&quot;&gt;assemble&lt;/code&gt; scripts.&lt;/p&gt;

&lt;h2 id=&quot;s2i-builder-image-default-files&quot;&gt;S2i Builder Image Default Files&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/s2i/assemble&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a bash script that contains instructions that will be run right after your deploying app source code is injected into &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp/src&lt;/code&gt; of the S2i builder image.&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; -ex

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;---&amp;gt; Preparing source...&quot;&lt;/span&gt;

mkdir -p /tmp/myapp

cp -Rf /tmp/src/src/. /tmp/myapp
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/s2i/usage&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This script is run when the &lt;strong&gt;builder image&lt;/strong&gt; is run w/o any additional commands. Its sole responsibility is to print out the usage of the builder image in text form.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;/s2i/run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This script is run during runtime when the derived &lt;strong&gt;application image&lt;/strong&gt; runs. Should contain the actual running of a long-lived process.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; -e

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Running myapp...&quot;&lt;/span&gt;
cat /tmp/myapp/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Sleeping...
&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;sleep 1; &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; -n .;done
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h2 id=&quot;s2i-builder-image-dockerfile&quot;&gt;S2i Builder Image Dockerfile&lt;/h2&gt;

&lt;p&gt;A typical Dockerfile should contain at minimum the following steps:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
# This image creates a very simple s2i builder image
# We are basing our builder image on openshift base-centos7 image

FROM openshift/base-centos7

# Set labels used in OpenShift to describe the builder images

LABEL io.k8s.description=&quot;simple s2i builder example&quot; \
      io.k8s.display-name=&quot;simple s2i builder example&quot; \
      io.openshift.s2i.scripts-url=&quot;image:///usr/libexec/s2i&quot; \
      io.openshift.tags=&quot;builder&quot;

# Copy the example S2I scripts to the expected location
COPY ./s2i/ /usr/libexec/s2i

# Set the default user for the image
USER 1001

# Set the default CMD to print the usage of the image, if somebody does docker run
CMD /usr/libexec/s2i/usage
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: The &lt;code class=&quot;highlighter-rouge&quot;&gt;io.openshift.s2i&lt;/code&gt; annotations can provide you with more configurable settings to help you with your s2i image creation. For example, you can use &lt;code class=&quot;highlighter-rouge&quot;&gt;io.openshift.s2i.destination=&quot;/path/where/appcode/is/injected&quot;&lt;/code&gt;. If not your application code will be injected into &lt;code class=&quot;highlighter-rouge&quot;&gt;/tmp/src&lt;/code&gt; of the base image.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;cheat-code&quot;&gt;Cheat Code&lt;/h2&gt;

&lt;p&gt;To quickly generate the necessary files to get your S2i builder image started (including the above directory structure), you can actually cheap by using the &lt;code class=&quot;highlighter-rouge&quot;&gt;s2i&lt;/code&gt; cli. You can grab it at &lt;a href=&quot;http://github.com/openshift/source-to-image&quot;&gt;http://github.com/openshift/source-to-image&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ s2i create &amp;lt;image name&amp;gt; &amp;lt;relative path to name of directory to use to contain the files&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;h1 id=&quot;deploying-your-builder-image-onto-openshift&quot;&gt;Deploying your Builder Image onto Openshift&lt;/h1&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;oc new-build --name &amp;lt;name of builder image&amp;gt; --binary=true # Create the build configuration (using Docker build strategy)
oc start-build &amp;lt;name of builder image&amp;gt; --from-dir=.       # Start the build, using the current directory
oc logs bc/&amp;lt;name of builder image&amp;gt; -f                     # Check the build output for errors
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When this is complete, this creates an image called &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;name of builder image&amp;gt;&lt;/code&gt; into Openshift which you can then use as the source base image.&lt;/p&gt;

&lt;h1 id=&quot;deploying-your-app-onto-openshift&quot;&gt;Deploying your App onto Openshift&lt;/h1&gt;

&lt;p&gt;Now that you have your app, all you really need is to send an instruction to have your app baked into your builder image and return an output image which youc an then use to deploy.&lt;/p&gt;

&lt;p&gt;In the directory of your app source code, create a new &lt;code class=&quot;highlighter-rouge&quot;&gt;build configuration&lt;/code&gt;. Like the steps above, &lt;code class=&quot;highlighter-rouge&quot;&gt;oc new build&lt;/code&gt; creates a build instruction to tell what is the expected output image.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ oc new-build --binary=true -i &amp;lt;name of builder image&amp;gt; --name &amp;lt;name of output image/appname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;em&gt;binary=true&lt;/em&gt; just instructs Openshift to expect the incoming files to be from a tarball/raw files&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this stage, you should have a working build configuration. Now let’s start to &lt;strong&gt;build&lt;/strong&gt; an output image. The following command will push all the files in the current directory up start a build.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# make sure you&#39;re in your app source code directory
$ oc start-build &amp;lt;name of output image/appname&amp;gt; --from-dir=.
$ oc logs bc/&amp;lt;name of output image&amp;gt; -f
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;After this is completed, just do an &lt;code class=&quot;highlighter-rouge&quot;&gt;oc new-app &amp;lt;name of output image/appname&amp;gt;&lt;/code&gt; and your app is deployed!&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Bonus&lt;/strong&gt;: If you want your application to overwrite any of the &lt;code class=&quot;highlighter-rouge&quot;&gt;assemble/run/usage&lt;/code&gt; scripts in your builder image, you can add them in &lt;code class=&quot;highlighter-rouge&quot;&gt;.s2i/bin/&lt;/code&gt; of your &lt;code class=&quot;highlighter-rouge&quot;&gt;application root&lt;/code&gt;. The S2i process will find these file and inject them into the builder image during build time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://blog.openshift.com/create-s2i-builder-image/&quot;&gt;Create S2i Builder Image - Openshift Blog&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://blog.openshift.com/override-s2i-builder-scripts/&quot;&gt;Override S2i Builder Image - Openshift Blog&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/VeerMuchandi/building-s2i-image&quot;&gt;VeerMuchandi - Building S2i Image&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guides" /><category term="howto" /><category term="openshift" /><category term="s2i" /><category term="source2image" /><summary type="html">Openshift’s S2i (Source-2-image) is a pretty cool replacement to buildpacks using Dockerfiles and Openshift</summary></entry><entry><title type="html">Load env variables from ConfigMaps and Secrets upon Pod boot</title><link href="http://dchua.com//2017/04/21/load-env-variables-from-configmaps-and-secrets-upon-pod-boot" rel="alternate" type="text/html" title="Load env variables from ConfigMaps and Secrets upon Pod boot" /><published>2017-04-21T00:00:00+08:00</published><updated>2017-04-21T15:27:25+08:00</updated><id>http://dchua.com//2017/04/21/load-env-variables-from-configmaps-and-secrets-upon-pod-boot</id><content type="html" xml:base="http://dchua.com//2017/04/21/load-env-variables-from-configmaps-and-secrets-upon-pod-boot">&lt;p&gt;One of the coolest stuff I’ve picked up just today is that you can keep environment variables that you want to be loaded into every deployment pod in a neatly configured &lt;code class=&quot;highlighter-rouge&quot;&gt;ConfigMap&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;Secret&lt;/code&gt; which gets injected back into the Pod during deploys.&lt;/p&gt;

&lt;p&gt;Lets say you have a Secret that looks like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;And you want &lt;code class=&quot;highlighter-rouge&quot;&gt;username&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;password&lt;/code&gt; to be easily accessible in &lt;code class=&quot;highlighter-rouge&quot;&gt;ENV[&#39;username&#39;]&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;ENV[&#39;password&#39;]&lt;/code&gt; on your application pods, all you need is a &lt;code class=&quot;highlighter-rouge&quot;&gt;envFrom&lt;/code&gt; within your &lt;code class=&quot;highlighter-rouge&quot;&gt;TemplateSpec&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ie.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apiVersion: extension/v1beta1
kind: Deployment
spec:
  replicas:1
  template:
    spec:
      containers:
        - name: test-container
          image: gcr.io/google_containers/busybox
          command: [ &quot;/bin/sh&quot;, &quot;-c&quot;, &quot;env&quot; ]
          envFrom:
            - secretRef:
                name: mysecret
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Because &lt;code class=&quot;highlighter-rouge&quot;&gt;envFrom&lt;/code&gt; expects an array, you can do multiple references like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;envFrom:
  - secretRef:
      name: hello
  - configMapRef:
      name: hello2
  - configMapRef:
      name: hello3
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This will take all the data keys from the 2 &lt;code class=&quot;highlighter-rouge&quot;&gt;ConfigMaps&lt;/code&gt; and 1 &lt;code class=&quot;highlighter-rouge&quot;&gt;Secret&lt;/code&gt; and load it into your pod.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://kubernetes.io/docs/tasks/configure-pod-container/configmap/&quot;&gt;Kubernetes - Configmap&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guides" /><category term="howto" /><category term="configmaps" /><category term="kubernetes" /><category term="secrets" /><category term="envvar" /><category term="12factor" /><summary type="html">One of the coolest stuff I’ve picked up just today is that you can keep environment variables that you want to be loaded into every deployment pod in a neatly configured ConfigMap or Secret which gets injected back into the Pod during deploys.</summary></entry><entry><title type="html">How to access unexported embedded structs within composite literals in Golang</title><link href="http://dchua.com//2017/04/18/how-to-access-unexported-embedded-structs-within-composite-literals-in-golang" rel="alternate" type="text/html" title="How to access unexported embedded structs within composite literals in Golang" /><published>2017-04-18T00:00:00+08:00</published><updated>2017-04-18T13:01:00+08:00</updated><id>http://dchua.com//2017/04/18/how-to-access-unexported-embedded-structs-within-composite-literals-in-golang</id><content type="html" xml:base="http://dchua.com//2017/04/18/how-to-access-unexported-embedded-structs-within-composite-literals-in-golang">&lt;p&gt;Short Answer, you can’t. BUT you can still declare it.&lt;/p&gt;

&lt;p&gt;If you have two struct types which is embedded within one another but declared as an unexported type, you will not be able to declare it in a composite type. You can only declare it outside of an composite literal&lt;/p&gt;

&lt;p&gt;Came across this while attempting to make use of Kubernetes’ API to declare an &lt;code class=&quot;highlighter-rouge&quot;&gt;Deployment&lt;/code&gt; object.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;type Deployment struct {
  metav1.TypeMeta
  Spec  DeploymentSpec

}

# in the metav1 pacakge
type TypeMeta {
  Kind  string
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;With the above structure, when we try to declare &lt;code class=&quot;highlighter-rouge&quot;&gt;Kind&lt;/code&gt; from &lt;code class=&quot;highlighter-rouge&quot;&gt;TypeMeta&lt;/code&gt;  within &lt;code class=&quot;highlighter-rouge&quot;&gt;Deployment&lt;/code&gt;, we will get an error indicating an &lt;code class=&quot;highlighter-rouge&quot;&gt;unknown field&lt;/code&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;TypeMeta&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;test := Deployment{metav1.TypeMeta: {Kind: &quot;Test&quot;}, Spec: Spec{}}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is because &lt;code class=&quot;highlighter-rouge&quot;&gt;metav1.TypeMeta&lt;/code&gt; is declared as a unexported type within &lt;code class=&quot;highlighter-rouge&quot;&gt;Deployment&lt;/code&gt; with its lowercase reference.&lt;/p&gt;

&lt;p&gt;In order to declare a Kind, you have to declare it from outside.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;test := Deployment{Spec: Spec{}}
test.Kind = &quot;Hello&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is because exported fields (&lt;code class=&quot;highlighter-rouge&quot;&gt;Kind&lt;/code&gt;) keep their exported status when that type is embedded.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.goinggo.net/2014/03/exportedunexported-identifiers-in-go.html&quot;&gt;Exported/Unexported Identifiers in Go&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guides" /><category term="howto" /><category term="golang" /><category term="kubernetes" /><category term="structs" /><summary type="html">Short Answer, you can’t. BUT you can still declare it.</summary></entry><entry><title type="html">Forwarding Vault audit logs to a remote Syslog server (like Graylog)</title><link href="http://dchua.com//2017/03/06/forwarding-vault-audit-logs-to-a-remote-syslog-server" rel="alternate" type="text/html" title="Forwarding Vault audit logs to a remote Syslog server (like Graylog)" /><published>2017-03-06T00:00:00+08:00</published><updated>2017-03-06T15:26:23+08:00</updated><id>http://dchua.com//2017/03/06/forwarding-vault-audit-logs-to-a-remote-syslog-server</id><content type="html" xml:base="http://dchua.com//2017/03/06/forwarding-vault-audit-logs-to-a-remote-syslog-server">&lt;p&gt;Using Vault’s Audit Backend to send logs to a remote Syslog server.&lt;/p&gt;

&lt;h2 id=&quot;objective&quot;&gt;Objective&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Send audit_logs from Hashicorp’s Vault to an Graylog instance&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Setup a Syslog TCP/UDP Input on Graylog (if you’re using graylog)&lt;/li&gt;
  &lt;li&gt;Has a remote syslog server running&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;steps&quot;&gt;Steps&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Important Notice&lt;/strong&gt;: Vault has a Syslog Audit Backend as part of its suite but it currently does not allow remote forwarding.&lt;br /&gt;
In order to do that we will have to make use of rsyslog’s rules forwarding.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In your vault server instance,&lt;/p&gt;

&lt;p&gt;Setup your local syslog audit backend&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./vault audit-enable syslog tag=&quot;&amp;lt;TAG&amp;gt;&quot;

# TAG - A recognizable name that represents what this vault is for or where is it located. eg. mysupersecretserver.domain
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This audit backend sends all logs to your local syslog’s &lt;code class=&quot;highlighter-rouge&quot;&gt;auth&lt;/code&gt; facility with the tag that you specify&lt;/p&gt;

&lt;p&gt;Now, lets create a syslog configuration file to lookout for the logs.&lt;/p&gt;

&lt;p&gt;Create a new configuration file:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# /etc/rsyslog.d/30-vault.conf

if $syslogfacility-text == &quot;auth&quot; and $syslogtag startswith &quot;&amp;lt;tag&amp;gt;&quot; then @@&amp;lt;remote_syslog_host&amp;gt;:&amp;lt;remote_syslog_port&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;If you are running graylog, replace &lt;code class=&quot;highlighter-rouge&quot;&gt;remote_syslog_host&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;remote_syslog_port&lt;/code&gt; with your Graylog Syslog listening host and port.&lt;/p&gt;

&lt;p&gt;Restart your local syslog&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ systemctl restart rsyslog.service
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now when you do any vault activity, you should see the log appear in both &lt;code class=&quot;highlighter-rouge&quot;&gt;/var/log/auth.log&lt;/code&gt; and your &lt;code class=&quot;highlighter-rouge&quot;&gt;remote syslog server&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.vaultproject.io/docs/audit/syslog.html&quot;&gt;Vault Audit Backend - Syslog&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.rsyslog.com/sending-messages-to-a-remote-syslog-server/&quot;&gt;Sending Messages to a Remote Syslog Server&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.rsyslog.com/doc/v8-stable/configuration/filters.html&quot;&gt;Rsyslog configuration filter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guide" /><category term="vault" /><category term="hashicorp" /><category term="howto" /><category term="vault" /><category term="audit backend" /><category term="syslog" /><category term="linux" /><category term="devnotes" /><summary type="html">Using Vault’s Audit Backend to send logs to a remote Syslog server.</summary></entry><entry><title type="html">Alerting with Prometheus and AlertManager</title><link href="http://dchua.com//2017/02/28/alerting-with-prometheus-and-alertmanager" rel="alternate" type="text/html" title="Alerting with Prometheus and AlertManager" /><published>2017-02-28T00:00:00+08:00</published><updated>2017-02-28T14:12:18+08:00</updated><id>http://dchua.com//2017/02/28/alerting-with-prometheus-and-alertmanager</id><content type="html" xml:base="http://dchua.com//2017/02/28/alerting-with-prometheus-and-alertmanager">&lt;p&gt;How to setup Prometheus AlertManager and get a whole alerting pipeline setup.&lt;/p&gt;

&lt;h2 id=&quot;objectives-and-goals&quot;&gt;Objectives and Goals&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Write and Deploy Prometheus Alert Rules&lt;/li&gt;
  &lt;li&gt;Configure Prometheus to send Alerts to Alert Manager&lt;/li&gt;
  &lt;li&gt;Setup AlertManager to receive Prometheus Alert&lt;/li&gt;
  &lt;li&gt;Send a Slack message on Alert&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;prerequisite&quot;&gt;Prerequisite&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Prometheus is already setup and running&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;alert-rules&quot;&gt;Alert Rules&lt;/h2&gt;

&lt;p&gt;To begin writing and deploying alerts, you’ll need to modify your prometheus config file. Usually, its located at &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/prometheus/prometheus.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If there’s no &lt;code class=&quot;highlighter-rouge&quot;&gt;rule_files&lt;/code&gt; key in root, add it. It should look something like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rule_files:
  - &quot;alert.rules&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;This tells prometheus that there’s a rules file that’s located at &lt;code class=&quot;highlighter-rouge&quot;&gt;alert.rules&lt;/code&gt; in a path that’s relative to the location of the current config file.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Rules are basically instructions to Prometheus and can be used for &lt;a href=&quot;https://prometheus.io/docs/alerting/rules/&quot;&gt;Alerting&lt;/a&gt; or &lt;a href=&quot;https://prometheus.io/docs/querying/rules/&quot;&gt;Recording&lt;/a&gt;. Alerting is to tell Prometheus to raise an alert if certain conditions are met and Recording rules is used to precompute/process time-series as they come in. For example, to rewrite labels into a new time_series.&lt;/p&gt;

&lt;p&gt;With your &lt;code class=&quot;highlighter-rouge&quot;&gt;alert.rules&lt;/code&gt; file, now you can start writing ALERTING expressions to monitor a Prometheus Metrics and its value.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Alert Rules

ALERT AppCrash
  IF firehost_value_metric_bbs_crashed_actual_lr_ps &amp;gt; 10
  FOR 15s
  LABELS { severity=&quot;critical&quot; }
  ANNOTATIONS {
   summary = &quot;Number of consecutive crashes in the past 30 seconds&quot;
   description = &quot;The number of consecutive crashes in the past 30 seconds is at: . This is dangerous and rectified immediately&quot;
  }
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;The &lt;strong&gt;FOR&lt;/strong&gt; indicates the duration to wait before firing an alert out. This is important if you want to prevent false positives. By adding a higher duration, it allows the failure to resolve itself before sending out a message.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, let’s reload your Prometheus by sending a &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHUP&lt;/code&gt; to the process.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ps auwx | grep prometheus
$ kill -1 &amp;lt;prometheus_pid&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;When you access http://&lt;prometheus&gt;:&lt;port&gt;, you should see your alert appear in the &quot;ALERT&quot; tab. If you don&#39;t, check that your rules and prometheus configuration are not malformed.&lt;/port&gt;&lt;/prometheus&gt;&lt;/p&gt;

&lt;h2 id=&quot;setup-alertmanager&quot;&gt;Setup AlertManager&lt;/h2&gt;

&lt;p&gt;When a alert is triggered, Prometheus sends a &lt;a href=&quot;https://prometheus.io/docs/alerting/clients/&quot;&gt;payload&lt;/a&gt; to the urls defined in Prometheus’ &lt;code class=&quot;highlighter-rouge&quot;&gt;/api/v1/alertmanagers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It might be possible to build your own AlertManagers but in the meantime, let’s use the &lt;a href=&quot;https://github.com/prometheus/alertmanager&quot;&gt;one provided&lt;/a&gt; by Prometheus.&lt;/p&gt;

&lt;p&gt;Download the &lt;a href=&quot;https://github.com/prometheus/alertmanager/releases&quot;&gt;binaries here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Download it onto a VM which you want to run, un-tar it and you should see two files here. One &lt;code class=&quot;highlighter-rouge&quot;&gt;simple.yml&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;alertmanager&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lets keep it simple for now and get alertmanager hooked up.&lt;/p&gt;

&lt;p&gt;Run the binary on a server that is internet accessible. I would place it in the same server as Prometheus to start off.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ./alertmanager -config.file=simple.yml
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Remember to note the port that its listening to.&lt;/p&gt;

&lt;p&gt;Now on your Prometheus startup script, re-run Prometheus with an &lt;code class=&quot;highlighter-rouge&quot;&gt;-alertmanager.url http://&amp;lt;server with prometheus&amp;gt;:&amp;lt;port&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If everything is ok, when you curl Prometheus’ alertmanagers endpoint, you should see a new URL under &lt;code class=&quot;highlighter-rouge&quot;&gt;activeAlertmanagers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;curl http://localhost:900/api/v1/alertmanagers&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;configure-alertmanager-to-send-a-slack-alert&quot;&gt;Configure AlertManager to send a Slack Alert&lt;/h2&gt;

&lt;p&gt;Moving back to AlertManager, right now if an alert is triggered, you’ll probably be unaware. Lets hook it into something that’s more visible. Like a Slack Channel.&lt;/p&gt;

&lt;p&gt;First thing to do is to get your Incoming Webhooks url ready. It should look something like &lt;code class=&quot;highlighter-rouge&quot;&gt;https://hooks.slack.com/services/T1Ydfdsfab/B31uy2389/Edfsdfdsfsdf&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Add\Modify the following fields in your &lt;code class=&quot;highlighter-rouge&quot;&gt;simple.yml&lt;/code&gt; file in your &lt;em&gt;AlertManager&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;global:
  ...
  slack_api_url: &quot;https://hooks.slack.com/services/sdfsfdsf...&quot;

route:
  receiver: slack-alert # replace this field

receivers:
- name: &quot;slack-alert&quot; # you can name this anything you want
  slack_configs:
  - channel: &quot;#channel&quot;
    username: &quot;The Watchmen&quot;
    text: &quot;&quot;
    send_resolved: true
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Do a &lt;code class=&quot;highlighter-rouge&quot;&gt;SIGHUP&lt;/code&gt; (&lt;code class=&quot;highlighter-rouge&quot;&gt;kill -1 &amp;lt;pid&amp;gt;&lt;/code&gt;) on the AlertManager process.&lt;/p&gt;

&lt;p&gt;And you’re done!&lt;/p&gt;

&lt;p&gt;You should see something like:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/prometheus-alertmanager-slack.png&quot; alt=&quot;Screenshot&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/prometheus/alertmanager&quot;&gt;AlertManager&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://prometheus.io/docs/alerting/configuration/&quot;&gt;AlertManager - Configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guides" /><category term="prometheus" /><category term="alertmanager" /><category term="alerting" /><category term="howto" /><category term="guide" /><category term="devops" /><summary type="html">How to setup Prometheus AlertManager and get a whole alerting pipeline setup.</summary></entry><entry><title type="html">Deleting files and getting your diskspace back without rebooting</title><link href="http://dchua.com//2017/02/03/deleting-files-and-getting-your-diskspace-back-without-rebooting" rel="alternate" type="text/html" title="Deleting files and getting your diskspace back without rebooting" /><published>2017-02-03T00:00:00+08:00</published><updated>2017-02-03T16:10:33+08:00</updated><id>http://dchua.com//2017/02/03/deleting-files-and-getting-your-diskspace-back-without-rebooting</id><content type="html" xml:base="http://dchua.com//2017/02/03/deleting-files-and-getting-your-diskspace-back-without-rebooting">&lt;p&gt;When you run out of diskspaces and need to delete files quickly to recover them, most of the time, your deleted files will not free up the diskspace until the process that is using it is restarted or deleted.&lt;/p&gt;

&lt;p&gt;To force the filesystem to free up the lock to the file so that the files can be cleared up, you’d need to find the process that is using the file and truncate it.&lt;/p&gt;

&lt;h4 id=&quot;finding-and-deleting-the-file&quot;&gt;Finding and deleting the file&lt;/h4&gt;

&lt;p&gt;First, find the process PID that is using it and look out for deleted files that the process has a lock on.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ ls -l /proc/&amp;lt;PID&amp;gt;/fd

lr-x------ 1 tmp tmp 64 lut  1 00:06 3 -&amp;gt; /home/tmp/x (deleted)
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Once you’ve found out which is the fd that the deleted file is linked to, in the above example its, &lt;code class=&quot;highlighter-rouge&quot;&gt;3&lt;/code&gt;, you can immediately truncate it to release the file lock and allow the filesystem to release the diskspace.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ :&amp;gt;/proc/&amp;lt;PID&amp;gt;/fd/3
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;You should immediately see your file diskspace released after the above command.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: It should be emphasized that this might cause some unintended consequences to your running process. Please use this with caution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://unix.stackexchange.com/questions/182077/best-way-to-free-disk-space-from-deleted-files-that-are-held-open&quot;&gt;Stack Overflow - Best way to free disk space from deleted files&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guides" /><category term="howto" /><category term="linux" /><category term="filesystem" /><category term="diskspace" /><category term="sysadmin" /><summary type="html">When you run out of diskspaces and need to delete files quickly to recover them, most of the time, your deleted files will not free up the diskspace until the process that is using it is restarted or deleted.</summary></entry><entry><title type="html">Using Multiple Buildpacks in Deis</title><link href="http://dchua.com//2017/01/22/using-multiple-buildpacks-in-deis" rel="alternate" type="text/html" title="Using Multiple Buildpacks in Deis" /><published>2017-01-22T00:00:00+08:00</published><updated>2017-01-22T00:55:01+08:00</updated><id>http://dchua.com//2017/01/22/using-multiple-buildpacks-in-deis</id><content type="html" xml:base="http://dchua.com//2017/01/22/using-multiple-buildpacks-in-deis">&lt;p&gt;To use multiple buildpacks with your Application Deployment on &lt;a href=&quot;https://deis.com/docs/workflow/quickstart/&quot;&gt;Deis Workflow&lt;/a&gt;, is pretty straight forward.&lt;/p&gt;

&lt;p&gt;As &lt;a href=&quot;https://github.com/heroku/heroku-buildpack-multi&quot;&gt;heroku-buildpack-multi&lt;/a&gt; is already built into &lt;a href=&quot;https://github.com/deis/slugbuilder&quot;&gt;deis’ slugbuilder&lt;/a&gt;, all you need to do is to create a &lt;code class=&quot;highlighter-rouge&quot;&gt;.buildpacks&lt;/code&gt; file in your repository, insert your required buildpacks, commit and push away.&lt;/p&gt;

&lt;p&gt;An example &lt;code class=&quot;highlighter-rouge&quot;&gt;.buildpack&lt;/code&gt; could look like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# .buildpacks
https://github.com/cloudfoundry/heroku-buildpack-ruby.git
https://github.com/gaumire/heroku-buildpack-mysql
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Enjoy.&lt;/p&gt;

&lt;h4 id=&quot;references&quot;&gt;References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/deis/slugbuilder/issues/51&quot;&gt;Github - multi-buildpacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="guide" /><category term="guide" /><category term="deis" /><category term="howto" /><category term="buildpacks" /><category term="multiple buildpacks" /><summary type="html">To use multiple buildpacks with your Application Deployment on Deis Workflow, is pretty straight forward.</summary></entry><entry><title type="html">Fixing OmniAuth Redirecting to a URI with Port</title><link href="http://dchua.com//2017/01/16/fixing-omniauth-redirecting-to-a-uri-with-port" rel="alternate" type="text/html" title="Fixing OmniAuth Redirecting to a URI with Port" /><published>2017-01-16T00:00:00+08:00</published><updated>2017-01-16T21:22:00+08:00</updated><id>http://dchua.com//2017/01/16/fixing-omniauth-redirecting-to-a-uri-with-port</id><content type="html" xml:base="http://dchua.com//2017/01/16/fixing-omniauth-redirecting-to-a-uri-with-port">&lt;p&gt;Came across this problem the other day when deploying a Rails application that is sitting behind &lt;a href=&quot;https://kubernetes.io&quot;&gt;Kubernetes&lt;/a&gt; and &lt;a href=&quot;https://deis.com/docs/workflow/quickstart/&quot;&gt;Deis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With my Rails application using OmniAuth and its &lt;a href=&quot;https://github.com/mkdynamic/omniauth-facebook&quot;&gt;Facebook strategy&lt;/a&gt;, after a user logins, hits Facebook and returns a redirection, the URL returned has its &lt;code class=&quot;highlighter-rouge&quot;&gt;port 80&lt;/code&gt; embedded in the return URI like: &lt;code class=&quot;highlighter-rouge&quot;&gt;https://domain.com:80&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In most cases, this wouldn’t be a problem but Facebook would return an error as the return URI (with the port 80) is not whitelisted hence creating a bad flow for your user.&lt;/p&gt;

&lt;p&gt;In order to fix this, you just need to tell OmniAuth where to redirect.&lt;/p&gt;

&lt;p&gt;Just add the following in either your &lt;code class=&quot;highlighter-rouge&quot;&gt;environments/*.rb&lt;/code&gt; file or create a new initializer file in your &lt;code class=&quot;highlighter-rouge&quot;&gt;config/initializers&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;OmniAuth.config.full_host = &quot;https://domain.com&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</content><category term="guide" /><category term="howto" /><category term="omniauth" /><category term="rails" /><summary type="html">Came across this problem the other day when deploying a Rails application that is sitting behind Kubernetes and Deis</summary></entry></feed>
