github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/integration/push/docker_test.go (about)

     1  package push
     2  
     3  import (
     4  	"code.cloudfoundry.org/cli/integration/helpers"
     5  
     6  	. "github.com/onsi/ginkgo"
     7  	. "github.com/onsi/gomega"
     8  	. "github.com/onsi/gomega/gbytes"
     9  	. "github.com/onsi/gomega/gexec"
    10  )
    11  
    12  var _ = Describe("pushing a docker image", func() {
    13  	var (
    14  		appName               string
    15  		privateDockerImage    string
    16  		privateDockerUsername string
    17  		privateDockerPassword string
    18  	)
    19  
    20  	BeforeEach(func() {
    21  		appName = helpers.NewAppName()
    22  	})
    23  
    24  	Describe("when the docker image is provided via command line", func() {
    25  		Describe("a public docker image", func() {
    26  			Describe("app existence", func() {
    27  				Context("when the app does not exist", func() {
    28  					It("creates the app", func() {
    29  						session := helpers.CF(PushCommandName, appName, "-o", PublicDockerImage)
    30  						validateDockerPush(session, appName, PublicDockerImage)
    31  					})
    32  				})
    33  
    34  				Context("when the app exists", func() {
    35  					BeforeEach(func() {
    36  						Eventually(helpers.CF(PushCommandName, appName, "-o", PublicDockerImage)).Should(Exit(0))
    37  					})
    38  
    39  					It("updates the app", func() {
    40  						session := helpers.CF(PushCommandName, appName, "-o", PublicDockerImage)
    41  						Eventually(session).Should(Say("Updating app with these attributes\\.\\.\\."))
    42  						Eventually(session).Should(Exit(0))
    43  					})
    44  				})
    45  			})
    46  		})
    47  
    48  		Describe("private docker image with a username", func() {
    49  			BeforeEach(func() {
    50  				privateDockerImage, privateDockerUsername, privateDockerPassword = helpers.SkipIfPrivateDockerInfoNotSet()
    51  			})
    52  
    53  			Context("when CF_DOCKER_PASSWORD is set", func() {
    54  				It("push the docker image with those credentials", func() {
    55  					session := helpers.CustomCF(
    56  						helpers.CFEnv{
    57  							EnvVars: map[string]string{"CF_DOCKER_PASSWORD": privateDockerPassword},
    58  						},
    59  						PushCommandName,
    60  						appName,
    61  						"--docker-username", privateDockerUsername,
    62  						"--docker-image", privateDockerImage,
    63  					)
    64  					validateDockerPush(session, appName, privateDockerImage)
    65  				})
    66  			})
    67  
    68  			Context("when the CF_DOCKER_PASSWORD is not set", func() {
    69  				var buffer *Buffer
    70  
    71  				BeforeEach(func() {
    72  					buffer = NewBuffer()
    73  					_, err := buffer.Write([]byte(privateDockerPassword + "\n"))
    74  					Expect(err).NotTo(HaveOccurred())
    75  				})
    76  
    77  				It("prompts for the docker password", func() {
    78  					session := helpers.CFWithStdin(buffer,
    79  						PushCommandName,
    80  						appName,
    81  						"--docker-username", privateDockerUsername,
    82  						"--docker-image", privateDockerImage,
    83  					)
    84  
    85  					validateDockerPassword(session, true)
    86  					validateDockerPush(session, appName, privateDockerImage)
    87  				})
    88  			})
    89  		})
    90  	})
    91  
    92  	Describe("docker image in the manifest is provided", func() {
    93  		var appManifest map[string]interface{}
    94  
    95  		BeforeEach(func() {
    96  			appManifest = map[string]interface{}{
    97  				"applications": []map[string]interface{}{
    98  					{
    99  						"name": appName,
   100  						"docker": map[string]string{
   101  							"image": PublicDockerImage,
   102  						},
   103  					},
   104  				},
   105  			}
   106  		})
   107  
   108  		It("uses the docker image when pushing", func() {
   109  			helpers.WithManifest(appManifest, func(manifestDir string) {
   110  				session := helpers.CustomCF(
   111  					helpers.CFEnv{WorkingDirectory: manifestDir},
   112  					PushCommandName,
   113  				)
   114  
   115  				validateDockerPush(session, appName, PublicDockerImage)
   116  			})
   117  		})
   118  
   119  		Context("when buildpack is set", func() {
   120  			BeforeEach(func() {
   121  				appManifest = map[string]interface{}{
   122  					"applications": []map[string]interface{}{
   123  						{
   124  							"name":      appName,
   125  							"buildpack": "some-buildpack",
   126  							"docker": map[string]string{
   127  								"image": PublicDockerImage,
   128  							},
   129  						},
   130  					},
   131  				}
   132  			})
   133  
   134  			It("returns an error", func() {
   135  				helpers.WithManifest(appManifest, func(manifestDir string) {
   136  					session := helpers.CustomCF(
   137  						helpers.CFEnv{WorkingDirectory: manifestDir},
   138  						PushCommandName,
   139  					)
   140  
   141  					Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: docker, buildpack", appName))
   142  					Eventually(session).Should(Exit(1))
   143  				})
   144  			})
   145  		})
   146  
   147  		Context("when path is set", func() {
   148  			BeforeEach(func() {
   149  				appManifest = map[string]interface{}{
   150  					"applications": []map[string]interface{}{
   151  						{
   152  							"name": appName,
   153  							"docker": map[string]string{
   154  								"image": PublicDockerImage,
   155  							},
   156  							"path": "some-path",
   157  						},
   158  					},
   159  				}
   160  			})
   161  
   162  			It("returns an error", func() {
   163  				helpers.WithManifest(appManifest, func(manifestDir string) {
   164  					session := helpers.CustomCF(
   165  						helpers.CFEnv{WorkingDirectory: manifestDir},
   166  						PushCommandName,
   167  					)
   168  
   169  					Eventually(session.Err).Should(Say("Application %s cannot use the combination of properties: docker, path", appName))
   170  					Eventually(session).Should(Exit(1))
   171  				})
   172  			})
   173  		})
   174  
   175  		Context("when user is provided in the manifest", func() {
   176  			BeforeEach(func() {
   177  				privateDockerImage, privateDockerUsername, privateDockerPassword = helpers.SkipIfPrivateDockerInfoNotSet()
   178  
   179  				appManifest = map[string]interface{}{
   180  					"applications": []map[string]interface{}{
   181  						{
   182  							"name": appName,
   183  							"docker": map[string]string{
   184  								"image":    privateDockerImage,
   185  								"username": privateDockerUsername,
   186  							},
   187  						},
   188  					},
   189  				}
   190  			})
   191  
   192  			Context("when password is provided in the enviornment", func() {
   193  				It("uses the docker image and credentials when pushing", func() {
   194  					helpers.WithManifest(appManifest, func(manifestDir string) {
   195  						session := helpers.CustomCF(
   196  							helpers.CFEnv{
   197  								WorkingDirectory: manifestDir,
   198  								EnvVars:          map[string]string{"CF_DOCKER_PASSWORD": privateDockerPassword},
   199  							},
   200  							PushCommandName,
   201  						)
   202  
   203  						validateDockerPassword(session, false)
   204  						validateDockerPush(session, appName, privateDockerImage)
   205  					})
   206  				})
   207  			})
   208  
   209  			Context("when password is not provided in the enviornment", func() {
   210  				It("errors out", func() {
   211  					helpers.WithManifest(appManifest, func(manifestDir string) {
   212  						session := helpers.CustomCF(
   213  							helpers.CFEnv{WorkingDirectory: manifestDir},
   214  							PushCommandName,
   215  						)
   216  
   217  						Eventually(session.Err).Should(Say("Environment variable CF_DOCKER_PASSWORD not set\\."))
   218  						Eventually(session).Should(Exit(1))
   219  					})
   220  				})
   221  			})
   222  		})
   223  	})
   224  
   225  	Describe("command line and manifest interaction", func() {
   226  		var appManifest map[string]interface{}
   227  
   228  		Context("when the image and username are provided by both manifest and command line", func() {
   229  			BeforeEach(func() {
   230  				privateDockerImage, privateDockerUsername, privateDockerPassword = helpers.SkipIfPrivateDockerInfoNotSet()
   231  
   232  				appManifest = map[string]interface{}{
   233  					"applications": []map[string]interface{}{
   234  						{
   235  							"name": appName,
   236  							"docker": map[string]string{
   237  								"image":    "junk",
   238  								"username": "junk",
   239  							},
   240  						},
   241  					},
   242  				}
   243  			})
   244  
   245  			It("command line takes precidence", func() {
   246  				helpers.WithManifest(appManifest, func(manifestDir string) {
   247  					session := helpers.CustomCF(
   248  						helpers.CFEnv{
   249  							WorkingDirectory: manifestDir,
   250  							EnvVars:          map[string]string{"CF_DOCKER_PASSWORD": privateDockerPassword},
   251  						},
   252  						PushCommandName,
   253  						"--docker-username", privateDockerUsername,
   254  						"--docker-image", privateDockerImage,
   255  					)
   256  
   257  					validateDockerPassword(session, false)
   258  					validateDockerPush(session, appName, privateDockerImage)
   259  				})
   260  			})
   261  		})
   262  	})
   263  })
   264  
   265  func validateDockerPassword(session *Session, passwordFromPrompt bool) {
   266  	if passwordFromPrompt {
   267  		Eventually(session).Should(Say("Environment variable CF_DOCKER_PASSWORD not set."))
   268  		Eventually(session).Should(Say("Docker password"))
   269  	} else {
   270  		Eventually(session).Should(Say("Using docker repository password from environment variable CF_DOCKER_PASSWORD."))
   271  	}
   272  }
   273  
   274  func validateDockerPush(session *Session, appName string, dockerImage string) {
   275  	Eventually(session).Should(Say("Getting app info\\.\\.\\."))
   276  	Eventually(session).Should(Say("Creating app with these attributes\\.\\.\\."))
   277  	Eventually(session).Should(Say("\\+\\s+name:\\s+%s", appName))
   278  	Eventually(session).Should(Say("\\s+docker image:\\s+%s", dockerImage))
   279  	helpers.ConfirmStagingLogs(session)
   280  	Eventually(session).Should(Say("Waiting for app to start\\.\\.\\."))
   281  	Eventually(session).Should(Say("requested state:\\s+started"))
   282  	Eventually(session).Should(Exit(0))
   283  
   284  	session = helpers.CF("app", appName)
   285  	Eventually(session).Should(Say("name:\\s+%s", appName))
   286  	Eventually(session).Should(Exit(0))
   287  }