Your first Go application

Programming in GO is quick and fun. You can write a working, compiled application with a few lines of code.

Write your first Go application

  • Create a directory of your application, let’s call it my-app
  • Open a terminal window in the my-app directory
  • To create two sub-directories, execute
    mkdir cmd
    mkdir pkg
  • Start the Atom text editor in the my-app directory with the command (include a dot at the end of the command)
    atom .
  • In Atom right-click the cmd directory and select New File
  • Name the file my-app.go

  • Copy the following code into the file
    package main

    import "fmt"

    func main() {
    fmt.Println("Hello World!!!")
    }
  • Save the file
  • To run the application execute the command in the terminal window
    go run cmd/my-app.go
  • The output should be
    Hello World!!!
 

Create a Git repository

  • Create a Git repository for the application and push the code to GitHub

Create a module for your application

In the main directory of your application execute

go mod init github.com/MY_GIT_ACCOUNT_NAME/MY_REPOSITORY_NAME.git

 

Set directory access in Windows

When you use SetAccessRule() to set access rights on a Windows directory, the user who will get the permission has to be a member of the Administrators group. If the user is not a member of the Administrators group PowerShell shows the error message

Exception calling “SetAccessRule” with “1” argument(s): “Some or all identity references could not be translated.”

Go language notes

Differences between Go and the “C” type languages

Variable declaration

int i;        // C#
var i int = 5 // Go
i := 5 // Go

Function declaration

private int AddNumbers (int a, int b) {...}  // C#
func addNumbers(a int, b int) int {...} // Go

Loops

for

for (int i = 0; i < 5; i++) {...}  // C#
for i := 0; i < 5; i++ {...} // Go

while

// "while" loop in C#
int i = 0;
while (i < 5) {
i++;
}

// "while" loop in Go (the init and post statements are optional, so "for" can be used as "while")
i := 0
for i < 5 {
i++
}

infinite loop

while (true) {...}  // C#
for {...} // Go

if

if (a == b ) {... } // C#
if a == b {...}     // Go

switch

No “break” is needed after every “case”

defer

Wait with the function call until the surrounding function completes
deferred function calls are pushed into a last-in first-out stack

Arrays

var a [5]int   // Go (array with 5 integer elements)

Lists

Use “slices” with the “append” function to dynamically add elements to a slice and the underlying array.

Classes

There are no classes in Go, use “methods” that are functions with receivers (attributes). The receiver has to be specified in the same package as the function.

func (v MyStruct) MyFunction() int {...}

Use pointer receivers to modify the original reference of the receiver in the function.

func (v *MyStruct) MyFunction() int {
  v.X = 5
}

Functions with a receiver can take a value or pointer. It is recommended to use pointer receivers to be able to modify the passed-in argument and avoid copying it.

Private and public (exported) names

  • Exported (public) names start with an upper case letter
    math.Pi
  • Not exported (private) names start with lower case letter
    mypackage.private
  •  

Variables

  • When declaring variables, the name comes first, the type comes last
    var i int
  • We can declare multiple variables with the same type, and specify the type only once for the last one in one statement
    var a, b, c bool
  •  Inside functions the short variable variable declaration uses the implicit type
    d := 5
  •  We can declare and assign values to multiple variables with one statement
    e, f, g := true, false, "yes!"
  •  The basic types are
    bool

    string

    int (32 bit on 32 bit systems, 64 bit on 64 bit systems)
    int8 int16 int32 int64
    uint (32 bit on 32 bit systems, 64 bit on 64 bit systems)
    uint8 uint16 uint32 uint64
    uintptr (32 bit on 32 bit systems, 64 bit on 64 bit systems)

    byte // alias for uint8

    rune // alias for int32
    // represents a Unicode code point

    float32 float64

    complex64 complex128
  •  To print the type and value of a variable use %T and %v
    a := 8
    fmt.Printf("Type: %T Value: %v", a, a)
    Type: int Value 8
  •  Explicit type conversions with a NewType(value) syntax are required for assignments between different types
    var i int = 5
    var f float32 = float32(i)
  •  

Functions

  • If a function returns multiple values, enclose the return declaration in parentheses
    func myfunc(x, y string) (string, string) {
    return y, x
    }
  •  

Slices

 Dynamic view into an array. array[first:last+1] (the element specified by the second argument is not part of the slice)

var s []int = array[0:6]

Create a slice and the underlying array with “make([]type, length of the slice, capacity of the array)”

b := make([]int, 0, 5) // len(b)=0, cap(b)=5

To dynamically add elements to the slice and the underlying array use the “append” function

var s []int
s = append(s, 1)
// Appends an element with the value of 1 to the slice and the array

To iterate through an array or slice use the “for range” expression. It returns the index and the value of the current element

for i, v := range my_array{}

Maps

// key is string, value is integer (here we use "make" to create it)
m := make(map[string]int)

// key is string, value is a struct
type MyStruct struct {
x, y int
}
var m map[string]MyStruct

Install and set up Go

Set up the Go development environment

Install Git

Install the Go Programming Language

Test the Go installation

  • Open a new terminal window, so the new PATH settings are imported, and execute
go version

Download a remote sample package

To download the package, in a terminal window execute

go get github.com/golang/example/hello

Navigate to the directory of the downloaded application

cd ~/go/bin

To run the package, execute

hello

Install the Go IDE

The Atom editor is a great IDE for Go. To enable the IDE features in Atom

    • Start Atom
    • Open the settings window
      • On the Mac select the Preferences item in the Atom menu
      • On Windows select the Settings item in the File menu
  • On the left side select Install
  • Search for atom-ide-ui and install the package
  • Search for ide-go and install the package
  • Restart Atom

Install Git on Macintosh

  • Navigate to https://git-scm.com/download/mac to download Git for the Macintosh. The page automatically downloads the installer for the operating system you use.
  • This app is not trusted by Apple, so to install it
    • Control-click (right-click) the downloaded file and select Open
    • Click the Open button to confirm the action

Configure Git

To configure Git see Git configuration.

How to duplicate a Windows server that is attached to the Windows Domain

When a Windows server is attached to a Domain only one instance of it can run at a time. To be able to duplicate the server and start a second instance of it

Create an image of the server

  1. Remote into the server
  2. Make sure there is a local administrator account that you can log in with
  3. Remove it from the domain
  4. Reboot the server
  5. In the AWS console create an image of it
  6. Add the server back to the domain with the same username and password that was used to originally add it to the domain

Launch a new instance

  1. In the AWS console launch a new instance with the saved image
  2. Log into the new instance with the local administrator account
  3. Change the server name (only one server can be added to the domain with the same name)
  4. Add the server to the domain
  5. Reboot the server

Bootstrap the new instance in the Chef server

If you configured the original server with Chef, attach the new instance to the Chef server with a new Node Name

  1. Open a terminal window in the cookbooks directory (below the .kitchen directory, so the Chef kitchen command can find the Chef server configuration)
  2. Execute the bootstrap command. See Bootstrap Chef nodes to connect them to the Chef server for the details on the bootstrapping process. Don’t forget to use a double backslash (\\) in front of the username.
knife bootstrap windows winrm MY_NODE_IP -x MY_USERNAME -P MY_PASSWORD --node-name THE_NODE_NAME --environment THE_ENVIRONMENT --run-list 'recipe[MY_COOKBOOK1::default],recipe[MY_COOKBOOK2::default]' --json-attributes '{"MY_ATTRIB1":"MY_VALUE1","MY_ATTRIB2":"MY_VALUE2"}' -V

Unable to insert the virtual optical disk in an Ubuntu virtual machine

When you try to install a new version of the VirtualBox Guest Addition on an Ubuntu virtual machine you may get the error message

Unable to insert the virtual optical disk C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso into the machine Ubuntu 64.

Could not mount the media/drive ‘C:\Program Files\Oracle\VirtualBox\VBoxGuestAdditions.iso’ (VERR_PDM_MEDIA_LOCKED).

Result Code: E_FAIL (0x80004005)
Component: ConsoleWrap
Interface: IConsole {872da645-4a9b-1727-bee2-5585105b9eed}
Callee: IMachine {85cd948e-a71f-4289-281e-0ca7ad48cd89}

To mount the new CD, first eject the currently mounted virtual CD

  1. Click the CD icon on the left side of the screen
  2. Click the eject icon next of the currently mounted Guest Addition CD

Raw-mode is unavailable courtesy of Hyper-V error in VirtualBox

For VirtualBox to be able to start virtual machines, Hyper-V has to be turned off in Windows 10.

If you get the error message when you try to launch a virtual machine in VirtualBox

Raw-mode is unavailable courtesy of Hyper-V

Check the Hyper-V setting

  1. Open a command prompt as an administrator,
  2. Execute the command:
    bcdedit

    The default value of the hypervisorlaunchtype is “Auto”

    For VirtualBox to be able to launch virtual machines, we have to turn off hypervisorlaunchtype

Disable Hyper-V

To disable Hyper-V

  1. Open a command prompt as an administrator
  2. Execute the command
    bcdedit /set hypervisorlaunchtype off
  3. Restart the computer. Do not shut down and start the computer, that does not work.

Enable Hyper-V

Docker for Windows needs the hardware virtualization that Hyper-V provides. To enbale Hyper-V again

  1. Open a command prompt as an administrator
  2. Execute the command
    bcdedit /set hypervisorlaunchtype auto
  3. Restart the computer for the change to take effect.

Windows application installation error codes

To enable logging of .msi packages open a command prompt as an administrator and execute

MY_APPLICATION.msi /l*vx install.log

Error Code

Explanation

2 ?
1603 Error message from the operating system

  • dll can not register
  • msi installation failed
    • required version of the .NET framework missing
1605 Nothing to uninstall ?
1618 ?
1619 The source directory does not exist?
1622 File not found or access denied
1638

Stop multiple untagged AWS EC2 instances with a Bash script

 List all EC2 instances without a specific tag

One day we have found 499 instances running in our account without any tags. Most likely someone accidentally started a process to launch those, so we needed a way to find them and stop them. Later we will terminate them with the same script below when we can make sure those are not needed.

For simplicity, place the appropriate aws_access_key_id and aws_secret_access_key into the [default] section of the “~/.aws/credentials” file or use the –profile option in every command below.

List all instances

To list all EC2 instances, execute

aws ec2 describe-instances

List all instances missing a specific tag

I have found the command to list those instances that are missing the “Name” tag at https://www.onica.com/blog/using-aws-cli-to-find-untagged-instances/

I have directed the output to a text file with the additional last line.

To get all info on the instances with no “Name” tag into a JSON file

aws ec2 describe-instances \
--query 'Reservations[].Instances[?!not_null(Tags[?Key == `Name`].Value)]' \
> instances-no-name-tag.json

To output multiple properties into a tab-separated file for reporting in Excel.

aws ec2 describe-instances \
--output text \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[?!not_null(Tags[?Key == `Name`].Value)] | [].[InstanceId,ImageId,InstanceType,Platform,LaunchTime,SubnetId,KeyName]' \
> instance-info-no-name-tag.csv

Get the list of instance IDs into a text file for batch processing

aws ec2 describe-instances \
--output text \
--filters Name=instance-state-name,Values=running \
--query 'Reservations[].Instances[?!not_null(Tags[?Key == `Name`].Value)] | [].[InstanceId]' \
> instance-ids-no-name-tag.txt

Stop an instance with the instance Id

aws ec2 stop-instances --instance-ids MY_INSTANCE_ID

Stop multiple instances

To stop all instances listed in the “instance-ids-no-name-tag.txt” file created above, create and execute this Bash script:

#!/bin/bash

# The file with the instance IDs
filname=instance-ids-no-name-tag.txt

# Iterate through the lines
while read p; do
  echo "Stopping $p"
  aws ec2 stop-instances --instance-ids $p
done <$filname