One place for hosting & domains

      Version

      Cómo usar ldflags para configurar la información de versión de aplicaciones de Go


      Introducción

      Al implementar aplicaciones en un entorno de producción, la creación de binarios con información de versión y otros metadatos mejorará sus procesos de monitoreo, registro y depuración al agregar información de identificación para ayudar a realizar un seguimiento de sus compilaciones con el tiempo. Esta información de versión, a menudo, puede incluir datos muy dinámicos, como el tiempo de compilación, la máquina o el usuario que compiló el binario y el sistema de control de versiones (VCS) con el que se creó, entre otros. Debido a que estos valores cambian constantemente, codificar estos datos directamente en el código fuente y modificarlos antes de cada compilación nueva es tedioso y está expuesto errores: los archivos de código fuente se pueden mover y las variables y constantes pueden cambiar los archivos a lo largo del desarrollo, lo que interrumpe el proceso de compilación.

      Una manera de resolver esto en Go es usar -ldflags con el comando go build para insertar información dinámica en el binario en el tiempo de compilación, sin necesidad de modificar el código fuente. En este indicador, ld significa enlazador, que es el programa que vincula las diferentes piezas del código fuente compilado en el binario final. Por lo tanto, ldflags quiere decir indicadores de enlazador. Se denomina de esta manera porque pasa un indicador al enlazador subyacente de la cadena de herramientas de Go, cmd/link, que le permite cambiar los valores de los paquetes importados en el tiempo de compilación desde la línea de comandos.

      En este tutorial, usará -ldflags para cambiar el valor de las variables en el tiempo de compilación e introducir su propia información dinámica en un binario usando una aplicación de muestra que imprime información de versión en la pantalla.

      Requisitos previos

      Para seguir el ejemplo de este artículo, necesitará lo siguiente:

      Crear su aplicación de muestra

      Antes de usar ldflags para introducir datos dinámicos, primero, necesita una aplicación para insertar la información. En este paso, creará esta aplicación, que, en esta etapa, solo imprimirá información de control de versiones estática. Crearemos esa aplicación ahora.

      En su directorio src, cree un directorio que lleve el nombre de su aplicación. En ese tutorial, se usará el nombre de aplicaciónapp:

      Cambie su directorio de trabajo a esta carpeta:

      A continuación, usando el editor de texto que prefiera, cree el punto de entrada de su programa, main.go:

      Ahora, haga que su aplicación imprima información de versión añadiendo el siguiente contenido:

      app/main.go

      package main
      
      import (
          "fmt"
      )
      
      var Version = "development"
      
      func main() {
          fmt.Println("Version:t", Version)
      }
      

      Dentro de la función main(), declaró la variable Version, luego imprimió la cadena Version: seguida de un carácter de tabulación, t, y por último la variable declarada.

      En este punto, la variable Version se define como development, que será la versión predeterminada de esta aplicación. Posteriormente, cambiará este valor para que sea un número de versión oficial, que se dispondrá conforme al formato de control de versiones semántico.

      Guarde el archivo y ciérrelo. Una vez hecho esto, cree y ejecute la aplicación para confirmar que imprima la versión correcta:

      Verá lo siguiente:

      Output

      Ahora, dispondrá de una aplicación que imprime información de versión predeterminada, pero todavía no cuenta con una forma de transmitir información de versión actual en el tiempo de compilación. En el siguiente paso, usará -ldflags y go build para resolver este problema.

      Usar ldflags con go build

      Como se mencionó anteriormente, ldflags significa *indicadores de enlazador *y se utiliza para pasar indicadores al enlazador subyacente de la cadena de herramientas de Go. Esto funciona de acuerdo con la siguiente sintaxis:

      • go build -ldflags="-flag"

      En este ejemplo, pasamos flag al comando go tool link subyacente que se ejecuta como parte de go build. En este comando, se utilizan comillas dobles alrededor del contenido que se pasa a ldflags para evitar romper sus caracteres o la presencia de caracteres que la línea de comandos podría interpretar como algo distinto de lo que deseamos. Desde aquí, podría pasar muchos indicadores link diferentes. A los efectos de este tutorial, usaremos el indicador -X para escribir información en la variable en el tiempo de enlace, seguido de la ruta del paquete a la variable y su nuevo valor:

      • go build -ldflags="-X 'package_path.variable_name=new_value'"

      Dentro de las comillas, ahora se encuentran la opción -X y un par clave-valor que representa la variable que se debe cambiar y su nuevo valor. El carácter . separa la ruta del paquete y el nombre de la variable, y se utilizan comillas simples para evitar la ruptura de los caracteres en el par clave-valor.

      Para sustituir la variable Version en su aplicación de ejemplo, utilice la sintaxis del último bloque de comandos a fin de establecer un nuevo valor y compilar el nuevo binario:

      • go build -ldflags="-X 'main.Version=v1.0.0'"

      En este comando, main es la ruta del paquete de la variable Version, dado que esta variable se encuentra en el archivo main.go. Version es la variable en la que escribe y v1.0.0 es el nuevo valor.

      Para usar ldflags, el valor que desea cambiar debe existir y ser una variable de nivel de paquetes de tipo string. Esta variable puede ser exportada o no exportada. El valor no puede ser const y el resultado de la invocación de una función no puede fijarlo. Afortunadamente, Version cumple todos estos requisitos: ya se declaró como variable en el archivo main.go, y tanto el valor actual (development) como el valor deseado (v1.0.0) son cadenas.

      Una vez compilado su nuevo binario app, ejecute la aplicación:

      Recibirá el siguiente resultado:

      Output

      Con -ldflags, cambió de forma exitosa la variable Version de development a v1.0.0.

      De esta manera, modificó una variable string dentro de una aplicación simple en el tiempo de compilación. Con ldflags, puede insertar detalles de versión, información de licenciamiento y otros datos en un binario listo para la distribución usando solo la línea de comandos.

      En este ejemplo, la variable que cambió se encontraba en el programa main, lo que redujo la dificultad de determinar el nombre de la ruta. Sin embargo, a veces la ruta hacia estas variables es más difícil de encontrar. En el siguiente paso, escribirá valores en variables dentro de subpaquetes para demostrar la mejor manera de determinar rutas de paquetes más complejas.

      Proporcionar orientación hacia variables de subpaquetes

      En la última sección, manipuló la variable Version que se encontraba en el paquete de nivel superior de la aplicación. Sin embargo, esto no siempre es así. Suele ser más práctico disponer estas variables en otro paquete, ya que el paquete main no se puede importar. Para simular esto en su aplicación de muestra, creará un nuevo subpaquete, app/build, que almacenará información sobre el momento en que se compiló el binario y el nombre del usuario que ejecutó el comando de compilación.

      Para añadir un nuevo subpaquete, primero agregue a su proyecto un nuevo directorio denominado build:

      A continuación, cree un nuevo archivo llamado build.go para contener las variables nuevas:

      En su editor de texto, añada nuevas variables para Time y User:

      app/build/build.go

      package build
      
      var Time string
      
      var User string
      

      La variable Time contendrá una representación de cadena del momento en que se compiló el binario. La variable User contendrá el nombre del usuario que compiló el binario. Dado que estas dos variables siempre tendrán valores, no es necesario inicializarlas con valores predeterminados, como lo hizo para Version.

      Guarde el archivo y ciérrelo.

      A continuación, abra main.go para añadir estas variables a su aplicación:

      Dentro de main.go, agregue las siguientes líneas resaltadas:

      main.go

      package main
      
      import (
          "app/build"
          "fmt"
      )
      
      var Version = "development"
      
      func main() {
          fmt.Println("Version:t", Version)
          fmt.Println("build.Time:t", build.Time)
          fmt.Println("build.User:t", build.User)
      }
      

      En estas líneas, primero importó el paquete app/build y luego imprimió build.Time y build.User de la misma manera en que imprimió Version.

      Guarde el archivo y cierre su editor de texto.

      A continuación, para brindar orientación a estas variables con ldflags podría usar la ruta de importación app/build seguida de .User o .Time, dado que ya conoce la ruta de importación. Sin embargo, para simular una situación más compleja en la cual la ruta hacia la variable no sea tan evidente, usaremos el comando nm de la cadena de herramientas de Go.

      Con el comando go tool nm se mostrarán los símbolos presentes en un ejecutable, un objeto o un archivo. En este caso, “símbolo” se refiere a un objeto en el código, como una variable o función definida o importada. Generando una tabla de símbolos con nm y usando grep para buscar una variable, puede obtener rápidamente información sobre su ruta.

      Nota: El comando nm no lo ayudará a encontrar la ruta de su variable si el nombre del paquete tiene caracteres no ASCII, o bien los caracteres " o %, ya que es una limitación de la herramienta.

      Para usar este comando, primero, compile el binario para app:

      Ahora que se compiló app, oriente la herramienta nm hacia ella y realice una búsqueda en el resultado:

      • go tool nm ./app | grep app

      Cuando se ejecute, la herramienta nm mostrará muchos datos. Debido a esto, el comando anterior utilizó | para canalizar el resultado al comando grep, que luego buscó términos con la app de nivel superior en el título.

      Recibirá un resultado similar a este:

      Output

      55d2c0 D app/build.Time 55d2d0 D app/build.User 4069a0 T runtime.appendIntStr 462580 T strconv.appendEscapedRune . . .

      En este caso, las primeras dos líneas del resultado establecido contienen las rutas de las dos variables que busca: app/build.Time y app/build.Time.

      Ahora que conoce las rutas, compile la aplicación de nuevo, pero, esta vez, cambie Version, User y Time en el tiempo de compilación. Para hacerlo, pase varios indicadores -X a -ldflags:

      • go build -v -ldflags="-X 'main.Version=v1.0.0' -X 'app/build.User=$(id -u -n)' -X 'app/build.Time=$(date)'"

      Aquí, pasó el comando Bash id -u -n para mostrar el usuario actual y el comando date para mostrar la fecha actual.

      Una vez compilado el ejecutable, ejecute el programa:

      Este comando, cuando se ejecuta en un sistema Unix, genera un resultado similar al siguiente:

      Output

      Version: v1.0.0 build.Time: Fri Oct 4 19:49:19 UTC 2019 build.User: sammy

      Ahora, dispondrá de un binario que contiene información de control de versiones y de compilación, y que puede proporcionar ayuda fundamental para la producción a la hora de resolver problemas.

      Conclusión

      En este tutorial, se demostró que ldflags, cuando se aplica correctamente, puede ser una potente herramienta para introducir información valiosa en binarios en el tiempo de compilación. De esta manera, puede controlar indicadores de características, información de entorno, información de control de versiones y otros elementos sin introducir cambios en su código fuente. Agregando ldflags a su flujo de trabajo de compilación actual, puede maximizar los beneficios del formato de distribución binaria autónoma de Go.

      Si desea obtener más información acerca del lenguaje de programación Go, consulte toda la serie Cómo programar en Go. Si busca más soluciones para el control de versiones, consulte nuestra guía de referencia Cómo usar Git.



      Source link

      Cómo instalar la versión más reciente de MySQL en Debian 9


      Introducción

      MySQL es un destacado sistema de administración de bases de datos de código abierto que se usa para almacenar y recuperar datos para una gran variedad de aplicaciones populares. MySQL está representado por la letra M en la sigla de la pila LAMP, un conjunto de software de código abierto de uso común, en la que también se incluyen Linux, el servidor web Apache y el lenguaje de programación de PHP.

      En Debian 9, MariaDB, una ramificación de la comunidad del proyecto MySQL se incluye como la variante predeterminada de MySQL. Aunque MariaDB funciona correctamente en la mayoría de los casos, si necesita las funciones que solo encontrará en MySQL de Oracle puede instalar y usar paquetes desde un repositorio de cuyo mantenimiento se encargan los desarrolladores de MySQL.

      Para instalar la última versión de MySQL, añadiremos este repositorio, instalaremos el propio software de MySQL, protegeremos la instalación y, por último, probaremos que MySQL funcione y responda a los comandos.

      Requisitos previos

      Antes de comenzar con este tutorial, necesitará lo siguiente:

      Paso 1: Añadir el repositorio de software de MySQL

      Los desarrolladores de MySQL proporcionan un paquete .deb que gestiona la configuración e instalación de los repositorios de software oficiales de MySQL. Una vez configurados los repositorios, podremos usar el comando estándar apt de Ubuntu para instalar el software. Descargaremos este archivo .deb con wget y luego lo instalaremos con el comando dpkg.

      Primero, cargue la página de descarga de MySQL en su navegador web. Busque el botón Descargar en la esquina inferior derecha y haga clic para llegar a la página siguiente. En esta página se solicitará que inicie sesión o se registre para crear una cuenta web Oracle. Podemos omitir esto y en vez de eso buscar el enlace que dice No thanks, just start my download (no, gracias, simplemente quiero iniciar mi descarga). Haga clic con el botón secundario del ratón y seleccione Copiar dirección de enlace (la redacción de esta opción puede diferir según su navegador).

      Ahora, descargaremos el archivo. En su servidor, diríjase a un directorio en el que pueda realizar tareas de escritura. Descargue el archivo usando wget; recuerde pegar la dirección que acaba de copiar en lugar de la parte resaltada a continuación:

      • cd /tmp
      • wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb

      El archivo debería descargarse en el directorio actual. Enumere los archivos para asegurarse:

      Debería poder ver el nombre del archivo que se indica:

      Output

      mysql-apt-config_0.8.10-1_all.deb . . .

      Ahora estamos listos para la instalación:

      • sudo dpkg -i mysql-apt-config*

      dpkg se utiliza para instalar, eliminar e inspeccionar paquetes de software .deb. El indicador -i muestra que deseamos realizar la instalación con el archivo especificado.

      Durante la instalación, se le presentarán una pantalla de configuración en la que podrá especificar la versión de MySQL que prefiere y una opción de instalación de repositorios para otras herramientas relacionadas con MySQL. Los valores predeterminados no añadirán más que la información sobre repositorios para la última versión estable de MySQL. Esto es lo que deseamos. Por ello, utilice la flecha hacia abajo para buscar la opción de menú Ok y pulse ENTER.

      Con esto, el paquete terminará de añadir el repositorio. Actualice su caché de paquetes apt para que estén disponibles los nuevos paquetes de software:

      Ahora que agregamos los repositorios de MySQL, estamos listos para instalar el propio software de servidor de MySQL. Si alguna vez necesita actualizar la configuración de estos repositorios, ejecute sudo dpkg-reconfigure mysql-apt-config, seleccione las nuevas opciones y luego use sudo apt-get update para actualizar la caché de su paquete.

      Paso 2: Instalar MySQL

      Una vez agregado el repositorio, y con nuestra caché de paquetes recién actualizada, podremos usar apt para instalar el último paquete de servidor de MySQL:

      • sudo apt install mysql-server

      apt analizará todos los paquetes mysql-server disponibles y determinará que el paquete MySQL proporcionado es el más nuevo y adecuado. Luego, la herramienta calculará las dependencias del paquete y solicitará que apruebe la instalación. Escriba Y y luego pulse ENTER. Con esto, se instalará el software.

      Se le solicitará establecer una contraseña de root durante la etapa de configuración de la instalación. Seleccione y confirme una contraseña segura para continuar. A continuación, aparecerá una solicitud para que seleccione un complemento de autenticación predeterminado. Lea el contenido para comprender las opciones. Si tiene dudas, la opción Use Strong Password Encrypt (usar cifrado de contraseña segura) ofrece más protección.

      Con esto, MySQL debería quedar instalado y activo. Haremos una comprobación usando systemctl:

      • sudo systemctl status mysql

      Output

      ● mysql.service - MySQL Community Server Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled) Active: active (running) since Wed 2018-09-05 15:58:21 UTC; 30s ago Docs: man:mysqld(8) http://dev.mysql.com/doc/refman/en/using-systemd.html Main PID: 12805 (mysqld) Status: "SERVER_OPERATING" CGroup: /system.slice/mysql.service └─12805 /usr/sbin/mysqld Sep 05 15:58:15 mysql1 systemd[1]: Starting MySQL Community Server... Sep 05 15:58:21 mysql1 systemd[1]: Started MySQL Community Server.

      La línea Active: active (running) indica que MySQL está instalado y en ejecución. A continuación, haremos que la instalación sea un poco más segura.

      Paso 3: Proteger MySQL

      MySQL cuenta con un comando que podemos usar para realizar algunas actualizaciones de seguridad en nuestra nueva instalación. Lo ejecutaremos:

      • mysql_secure_installation

      Con esto, se solicitará la contraseña de root de MySQL que estableció durante la instalación. Escríbala y pulse ENTER. A continuación, responderemos a una serie de solicitudes con respuestas “Sí” o “No”. Vamos a verlas:

      Primero, se nos hará una pregunta sobre el complemento de validación de contraseña, un complemento que puede imponer de forma automática determinadas reglas de seguridad de contraseñas para sus usuarios de MySQL. Habilitar esto es una decisión que deberá tomar según sus necesidades de seguridad particulares. Escriba y y luego pulse ENTER para habilitarlo, o simplemente pulse ENTER para omitirlo. Si el parámetro se habilita, también se le solicitará elegir un nivel de 0 a 2 para establecer cuán estricta será la validación de la contraseña. Seleccione un número y pulse ENTER para continuar.

      A continuación, se le preguntará si desea cambiar la contraseña de root. Debido a que acabamos de crear la contraseña cuando instalamos MySQL, podemos omitir esto de forma segura. Pulse ENTER para continuar sin actualizar la contraseña.

      Puede responder el resto de las preguntas con la opción Yes. Se le preguntará si desea eliminar el usuario MySQL anónimo, deshabilitar el inicio de sesión de root remoto, eliminar la base de datos de prueba y volver a cargar las tablas de privilegios para garantizar que los cambios anteriores se apliquen correctamente. Todo esto es recomendable. Escriba y y pulse ENTER para cada pregunta.

      La secuencia de comandos se cerrará una vez que responda todas las preguntas. Con esto, nuestra instalación de MySQL tendrá un nivel de protección razonable. Haremos otra prueba ejecutando un cliente que se conecte al servidor y muestre información.

      Paso 4: Probar MySQL

      mysqladmin es un cliente administrativo de línea de comandos para MySQL. Lo usaremos para establecer conexión con el servidor y extraer información sobre la versión y el estado:

      • mysqladmin -u root -p version

      La parte -u root indica a mysqladmin que inicie sesión como el usuario root de MySQL, -p indica al cliente que solicite una contraseña, y version es el comando que queremos ejecutar.

      El resultado nos permitirá conocer la versión del servidor MySQL que está en ejecución, su tiempo de conexión y otros datos sobre el estado:

      Output

      mysqladmin Ver 8.0.12 for Linux on x86_64 (MySQL Community Server - GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Server version 8.0.12 Protocol version 10 Connection Localhost via UNIX socket UNIX socket /var/run/mysqld/mysqld.sock Uptime: 6 min 42 sec Threads: 2 Questions: 12 Slow queries: 0 Opens: 123 Flush tables: 2 Open tables: 99 Queries per second avg: 0.029

      Si recibió un resultado similar, ¡felicitaciones! Habrá instalado y protegido de forma correcta el servidor más reciente de MySQL.

      Conclusión

      De esta manera, completó una instalación básica de la versión más reciente de MySQL, que debería funcionar para muchas aplicaciones populares:



      Source link

      Using ldflags to Set Version Information for Go Applications


      Introduction

      When deploying applications into a production environment, building binaries with version information and other metadata will improve your monitoring, logging, and debugging processes by adding identifying information to help track your builds over time. This version information can often include highly dynamic data, such as build time, the machine or user building the binary, the Version Control System (VCS) commit ID it was built against, and more. Because these values are constantly changing, coding this data directly into the source code and modifying it before every new build is tedious and prone to error: Source files can move around and variables/constants may switch files throughout development, breaking the build process.

      One way to solve this in Go is to use -ldflags with the go build command to insert dynamic information into the binary at build time, without the need for source code modification. In this flag, ld stands for linker, the program that links together the different pieces of the compiled source code into the final binary. ldflags, then, stands for linker flags. It is called this because it passes a flag to the underlying Go toolchain linker, cmd/link, that allows you to change the values of imported packages at build time from the command line.

      In this tutorial, you will use -ldflags to change the value of variables at build time and introduce your own dynamic information into a binary, using a sample application that prints version information to the screen.

      Prerequisites

      To follow the example in this article, you will need:

      Building Your Sample Application

      Before you can use ldflags to introduce dynamic data, you first need an application to insert the information into. In this step, you will make this application, which will at this stage only print static versioning information. Let’s create that application now.

      In your src directory, make a directory named after your application. This tutorial will use the application name app:

      Change your working directory to this folder:

      Next, using the text editor of your choice, create the entry point of your program, main.go:

      Now, make your application print out version information by adding the following contents:

      app/main.go

      package main
      
      import (
          "fmt"
      )
      
      var Version = "development"
      
      func main() {
          fmt.Println("Version:t", Version)
      }
      

      Inside of the main() function, you declared the Version variable, then printed the string Version:, followed by a tab character, t, and then the declared variable.

      At this point, the variable Version is defined as development, which will be the default version for this app. Later on, you will change this value to be an official version number, arranged according to semantic versioning format.

      Save and exit the file. Once this is done, build and run the application to confirm that it prints the correct version:

      You will see the following output:

      Output

      You now have an application that prints default version information, but you do not yet have a way to pass in current version information at build time. In the next step, you will use -ldflags and go build to solve this problem.

      Using ldflags with go build

      As mentioned before, ldflags stands for linker flags, and is used to pass in flags to the underlying linker in the Go toolchain. This works according to the following syntax:

      • go build -ldflags="-flag"

      In this example, we passed in flag to the underlying go tool link command that runs as a part of go build. This command uses double quotes around the contents passed to ldflags to avoid breaking characters in it, or characters that the command line might interpret as something other than what we want. From here, you could pass in many different link flags. For the purposes of this tutorial, we will use the -X flag to write information into the variable at link time, followed by the package path to the variable and its new value:

      • go build -ldflags="-X 'package_path.variable_name=new_value'"

      Inside the quotes, there is now the -X option and a key-value pair that represents the variable to be changed and its new value. The . character separates the package path and the variable name, and single quotes are used to avoid breaking characters in the key-value pair.

      To replace the Version variable in your example application, use the syntax in the last command block to pass in a new value and build the new binary:

      • go build -ldflags="-X 'main.Version=v1.0.0'"

      In this command, main is the package path of the Version variable, since this variable is in the main.go file. Version is the variable that you are writing to, and v1.0.0 is the new value.

      In order to use ldflags, the value you want to change must exist and be a package level variable of type string. This variable can be either exported or unexported. The value cannot be a const or have its value set by the result of a function call. Fortunately, Version fits all of these requirements: It was already declared as a variable in the main.go file, and the current value (development) and the desired value (v1.0.0) are both strings.

      Once your new app binary is built, run the application:

      You will receive the following output:

      Output

      Using -ldflags, you have succesfully changed the Version variable from development to v1.0.0.

      You have now modified a string variable inside of a simple application at build time. Using ldflags, you can embed version details, licensing information, and more into a binary ready for distribution, using only the command line.

      In this example, the variable you changed was in the main program, reducing the difficulty of determining the path name. But sometimes the path to these variables is more complicated to find. In the next step, you will write values to variables in sub-packages to demonstrate the best way to determine more complex package paths.

      Targeting Sub-Package Variables

      In the last section, you manipulated the Version variable, which was at the top-level package of the application. But this is not always the case. Often it is more practical to place these variables in another package, since main is not an importable package. To simulate this in your example application, you will create a new sub-package, app/build, that will store information about the time the binary was built and the name of the user that issued the build command.

      To add a new sub-package, first add a new directory to your project named build:

      Then create a new file named build.go to hold the new variables:

      In your text editor, add new variables for Time and User:

      app/build/build.go

      package build
      
      var Time string
      
      var User string
      

      The Time variable will hold a string representation of the time when the binary was built. The User variable will hold the name of the user who built the binary. Since these two variables will always have values, you don’t need to initialize these variables with default values like you did for Version.

      Save and exit the file.

      Next, open main.go to add these variables to your application:

      Inside of main.go, add the following highlighted lines:

      main.go

      package main
      
      import (
          "app/build"
          "fmt"
      )
      
      var Version = "development"
      
      func main() {
          fmt.Println("Version:t", Version)
          fmt.Println("build.Time:t", build.Time)
          fmt.Println("build.User:t", build.User)
      }
      

      In these lines, you first imported the app/build package, then printed build.Time and build.User in the same way you printed Version.

      Save the file, then exit from your text editor.

      Next, to target these variables with ldflags, you could use the import path app/build followed by .User or .Time, since you already know the import path. However, to simulate a more complex situation in which the path to the variable is not evident, let’s instead use the nm command in the Go tool chain.

      The go tool nm command will output the symbols involved in a given executable, object file, or archive. In this case, a symbol refers to an object in the code, such as a defined or imported variable or function. By generating a symbol table with nm and using grep to search for a variable, you can quickly find information about its path.

      Note: The nm command will not help you find the path of your variable if the package name has any non-ASCII characters, or a " or % character, as that is a limitation of the tool itself.

      To use this command, first build the binary for app:

      Now that app is built, point the nm tool at it and search through the output:

      • go tool nm ./app | grep app

      When run, the nm tool will output a lot of data. Because of this, the preceding command used | to pipe the output to the grep command, which then searched for terms that had the top-level app in the title.

      You will receive output similar to this:

      Output

      55d2c0 D app/build.Time 55d2d0 D app/build.User 4069a0 T runtime.appendIntStr 462580 T strconv.appendEscapedRune . . .

      In this case, the first two lines of the result set contain the paths to the two variables you are looking for: app/build.Time and app/build.User.

      Now that you know the paths, build the application again, this time changing Version, User, and Time at build time. To do this, pass multiple -X flags to -ldflags:

      • go build -v -ldflags="-X 'main.Version=v1.0.0' -X 'app/build.User=$(id -u -n)' -X 'app/build.Time=$(date)'"

      Here you passed in the id -u -n Bash command to list the current user, and the date command to list the current date.

      Once the executable is built, run the program:

      This command, when run on a Unix system, will generate similar output to the following:

      Output

      Version: v1.0.0 build.Time: Fri Oct 4 19:49:19 UTC 2019 build.User: sammy

      Now you have a binary that contains versioning and build information that can provide vital assistance in production when resolving issues.

      Conclusion

      This tutorial showed how, when applied correctly, ldflags can be a powerful tool for injecting valuable information into binaries at build time. This way, you can control feature flags, environment information, versioning information, and more without introducing changes to your source code. By adding ldflags to your current build workflow you can maximize the benefits of Go’s self-contained binary distribution format.

      If you would like to learn more about the Go programming language, check out our full How To Code in Go series. If you are looking for more solutions for version control, try our How To Use Git reference guide.



      Source link