Upload
hiroyuki-komagata
View
148
Download
2
Embed Size (px)
Citation preview
A Tour of cf-resourceHiroyuki Komagata (@idahobean_)
A Tour of cf-resource (how to implement concourse
resource dependent by cli)Hiroyuki Komagata (@idahobean_)
About Me t : @idahobean_ g: https://github.com/idahobean q: http://qiita.com/idahobean t : Novice
Recent FAILs
My Motivation
I want more people to create concourse resources!
(Because it means the scope of my product will expand)
How to achieve it?
By sharing about what i read and understood from the code.
• I’ve implemented below, based on cf-resource https://github.com/idahobean/cf-docker-resource https://github.com/idahobean/cf-service-resource
Overview of resource
See at: Implementing a Resource
http://concourse.ci/implementing-resources.html
Overview of resource
• /opt/resource/check
• /opt/resource/in
• /opt/resource/out ( )
Overview of resourceresource kick
concourse/atc
https://github.com/concourse/atc/tree/master/resource
type outRequest struct { Source atc.Source `json:"source"` Params atc.Params `json:"params,omitempty"` }
func (resource *resource) Put( ioConfig IOConfig, source atc.Source, params atc.Params, artifactSource ArtifactSource, signals <-chan os.Signal, ready chan<- struct{}, ) (VersionedSource, error) { resourceDir := ResourcesDir("put")
vs := &putVersionedSource{ container: resource.container, resourceDir: resourceDir, }
runner := resource.runScript( "/opt/resource/out", []string{resourceDir}, outRequest{ Params: params, Source: source, }, &vs.versionResult, ioConfig.Stderr, artifactSource, vs, true, )
err := runner.Run(signals, ready) if err != nil { return nil, err }
return vs, nil }
In the case of cf-resource
overview of cf-resourcecf-resource ├── Dockerfile ├── Godeps ├── LICENSE ├── NOTICE.md ├── README.md ├── build.yml ├── check │ └── cmd │ ├── check │ │ └── main.go │ ├── check.go │ ├── check_suite_test.go │ └── check_test.go ├── in │ ├── cmd │ │ └── in │ │ └── main.go │ ├── in_suite_test.go │ ├── integration_test.go │ └── models.go ├── models.go ├── out │ ├── assets │ │ ├── cf │ │ ├── invalidManifest.yml │ │ └── manifest.yml │ ├── cloud_foundry.go │ ├── cmd │ │ └── out │ │ └── main.go │ ├── command.go │ ├── command_test.go │ ├── fakes │ │ └── fake_paas.go │ ├── integration_test.go │ ├── manifest.go │ ├── manifest_test.go │ ├── models.go │ └── out_suite_test.go └── scripts └── ci
55 directories, 265 files
/opt/resource/check
https://github.com/concourse/cf-resource/blob/master/check/cmd/check/main.go
package main
import ( "fmt" "os" )
func main() { fmt.Fprintf(os.Stdout, "[]") }
/opt/resource/in
https://github.com/concourse/cf-resource/blob/master/in/cmd/in/main.go
func main() { var request in.Request if err := json.NewDecoder(os.Stdin).Decode(&request); err != nil { fatal("reading request from stdin", err) }
timestamp := request.Version.Timestamp if timestamp.IsZero() { timestamp = time.Now() }
response := in.Response{ Version: resource.Version{ Timestamp: timestamp, }, }
if err := json.NewEncoder(os.Stdout).Encode(response); err != nil { fatal("writing response", err) } }
version?
> When new versions of banana are detected, a new build of banana-unit will be scheduled, because we've set trigger: true.
http://concourse.ci/build-plans.html
pipeline trigger
version /
/opt/resource/out
overview of /opt/resource/out
cf-resource ├── out │ ├── assets │ │ ├── cf │ │ ├── invalidManifest.yml │ │ └── manifest.yml │ ├── cloud_foundry.go │ ├── cmd │ │ └── out │ │ └── main.go │ ├── command.go │ ├── command_test.go │ ├── fakes │ │ └── fake_paas.go │ ├── integration_test.go │ ├── manifest.go │ ├── manifest_test.go │ ├── models.go │ └── out_suite_test.go
cloud_foundry.go( )
https://github.com/concourse/cf-resource/blob/master/out/cloud_foundry.go
func (cf *CloudFoundry) Login(api string, username string, password string, insecure bool) error { args := []string{"api", api} if insecure { args = append(args, "--skip-ssl-validation") }
err := cf.cf(args...).Run() if err != nil { return err }
return cf.cf("auth", username, password).Run() }
func (cf *CloudFoundry) Target(organization string, space string) error { return cf.cf("target", "-o", organization, "-s", space).Run() }
func (cf *CloudFoundry) PushApp(manifest string, path string, currentAppName string) error { args := []string{}
if currentAppName == "" { args = append(args, "push", "-f", manifest) } else { args = append(args, "zero-downtime-push", currentAppName, "-f", manifest) }
if path != "" { stat, err := os.Stat(path) if err != nil { return err } if stat.IsDir() { return chdir(path, cf.cf(args...).Run) }
// path is a zip file, add it to the args args = append(args, "-p", path) }
command.go( )
https://github.com/concourse/cf-resource/blob/master/out/command.go
func (command *Command) Run(request Request) (Response, error) { err := command.paas.Login( request.Source.API, request.Source.Username, request.Source.Password, request.Source.SkipCertCheck, ) if err != nil { return Response{}, err }
err = command.paas.Target( request.Source.Organization, request.Source.Space, ) if err != nil { return Response{}, err }
if err := command.setEnvironmentVariables(request); err != nil { return Response{}, err }
err = command.paas.PushApp( request.Params.ManifestPath, request.Params.Path, request.Params.CurrentAppName, ) if err != nil { return Response{}, err }
return Response{ Version: resource.Version{ Timestamp: time.Now(), }, Metadata: []resource.MetadataPair{ { Name: "organization", Value: request.Source.Organization, }, {
test
test
build & publish
build & publishcf-resource ├── Dockerfile ├── Godeps ├── LICENSE ├── NOTICE.md ├── README.md ├── build.yml ├── check │ └── cmd │ ├── check │ │ └── main.go │ ├── check.go │ ├── check_suite_test.go │ └── check_test.go ├── in │ ├── cmd │ │ └── in │ │ └── main.go │ ├── in_suite_test.go │ ├── integration_test.go │ └── models.go ├── models.go ├── out │ ├── assets │ │ ├── cf │ │ ├── invalidManifest.yml │ │ └── manifest.yml │ ├── cloud_foundry.go │ ├── cmd │ │ └── out │ │ └── main.go │ ├── command.go │ ├── command_test.go │ ├── fakes │ │ └── fake_paas.go │ ├── integration_test.go │ ├── manifest.go │ ├── manifest_test.go │ ├── models.go │ └── out_suite_test.go └── scripts └── ci
55 directories, 265 files
resource concourse
build & publish
build & publish
build & publish
build & publish
https://github.com/concourse/concourse/blob/master/ci/pipelines/resources.yml
build & publish( )
https://github.com/concourse/concourse/blob/master/ci/pipelines/resources.yml
resources: - name: cf-resource type: git source: uri: https://github.com/concourse/cf-resource.git branch: master - name: cf-resource-image type: docker-image source: username: {{docker-username}} email: {{docker-email}} password: {{docker-password}} repository: concourse/cf-resource
jobs: - name: cf-resource serial: true public: true plan: - aggregate: - get: buildroot-base-image params: {save: true} passed: [buildroot-base] trigger: true - get: cf-resource trigger: true - get: cf-cli trigger: true - get: autopilot trigger: true - aggregate: - task: autopilot-unit file: autopilot/build.yml - task: resource-unit file: cf-resource/build.yml - put: cf-resource-image params: load_base: buildroot-base-image build: built-resource
build & publish
Thank you!Any feedback is welcome!