Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/steps embeds a Dockerfile inside a image resource field #55

Closed
wants to merge 23 commits into from

Conversation

cescoferraro
Copy link
Contributor

Still needs to resolve env var inside the dobifile. But its working.
implements idea from #51

@@ -106,3 +114,51 @@ func buildArgs(args map[string]string) []docker.BuildArg {
}
return out
}

func DobiDocker(dobifile []map[string]string, dockerfile string) (string, error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You dog!

config/image.go Outdated
@@ -35,6 +35,9 @@ type ImageConfig struct {
// Dockerfile The path to the ``Dockerfile`` used to build the image. This
// path is relative to the **context**.
Dockerfile string
// Dobifile is a in house version of a dockerfile
// type: mapping ``[Valid Docker command]: value``
Dobifile []map[string]string
Copy link
Owner

@dnephin dnephin Nov 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we need some other name for this, but I think dobifile is going to be confused with the dobi.yaml.

I'm thinking maybe content: is a better name, since it's the "content" of the Dockerfile.

config/image.go Outdated
return fmt.Errorf("one of dockerfile, dobifile, context, or pull is required")
}
if c.Dockerfile != "" && len(c.Dobifile) != 0 {
return fmt.Errorf("Either use a dockerfile or a dobifile")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't right, they could use pull: without either of these, and that would be valid.

dobi.yaml Outdated
- RUN: ls
- RUN: mkdir {env.HOME:}
- RUN: env
- CMD: pwd
Copy link
Owner

@dnephin dnephin Nov 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking it might be better to make this a []string instead, so that people can copy/pate out of a Dockerfile much easier. What's the reason for making it a []map[string]string ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I though it would be easier to validade if a key matches a existing Docker command and supply custom ones. Plus it keeps the yaml with nice colors, and a slice would still require the initial dash anyway, so it would never be that a straight foward copy/paste. Its your call
dobi

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, let's not change it yet. I know there have been a couple other projects that have created builders with a yaml config. I'd like to look at them to see what they did. I'll link the projects here when I find them again.

if err != nil {
return "", err
}
defer tempfile.Close()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, the python client allows for a way to pass in a Dockerfile without it being a real file. It lets you just pass something like an io.Writer. I wonder if go-dockerclient supports that, or if we could get it added.

It would be really great to now have to write to a temp file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have not looked a lot into this, but I wonder the same thing.

Copy link
Owner

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of this feature.

I hadn't considered that we could make use of the dobifile templating itself for the Dockerfile, I think that's a great idea.

return false
}

func (t *Task) WriteContentToBuffer(inputbuf bytes.Buffer) error{

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

exported method Task.WriteContentToBuffer should have comment or be unexported

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, if you want to catch these before pushing, there are a couple options:

  1. install http://pre-commit.com/ and run pre-commit install from the project directory. This will install pre-commit hooks for you and run static checks like this
  2. or, run dobi lint which runs the same checks, but in a container.

I think you could also just add a pre-commit hook that ran dobi lint, I haven't tried that yet

Copy link
Contributor Author

@cescoferraro cescoferraro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docker itself call each line of a dockerfile Step, so our slice of Steps should be called Steps.

cescoferraro@desktop: ~/code/go/src/github.com/dnephin/dobi on feature/dobifile [!?]
$ docker build -t test .
Sending build context to Docker daemon 227.1 MB
Step 1 : FROM busybox

tr.WriteHeader(&tar.Header{Name: "Dockerfile", Size: 10, ModTime: timee, AccessTime: timee, ChangeTime: timee})
for _, val := range t.config.Content {
for key, value := range val {
tr.Write([]byte(key + " " + value + "\n"))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a problem here. The bytes are too short. They are slicing FROM busybox to FROM busyb.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ go run main.go dobi
2016/11/04 15:22:03 is content
2016/11/04 15:22:03 FROM busybox
2016/11/04 15:22:03 RUN ls
2016/11/04 15:22:03 RUN mkdir /home/cescoferraro
2016/11/04 15:22:03 RUN env
2016/11/04 15:22:03 CMD pwd
Step 1 : FROM busyb
Pulling repository docker.io/library/busyb
[ERROR] Failed to execute task "dobi:build": Error: image library/busyb:latest not found

inputbuf, _ := bytes.NewBuffer([]byte{}), bytes.NewBuffer(nil)
timee := time.Now()
tr := tar.NewWriter(inputbuf)
tr.WriteHeader(&tar.Header{Name: "Dockerfile", Size: 10, ModTime: timee, AccessTime: timee, ChangeTime: timee})
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the ideal size we should? with 20 it seems to work now even with really big lines

tr.Write([]byte(key + " " + value + "\n"))
log.Printf(key + " " + value + "\n")
}
inputbuf := bytes.NewBuffer(nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should probably return this from the writeContentToBuffer

return inputbuf, nil
}

func (t *Task) runContainerFromDockerfile(ctx *context.ExecuteContext) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no the best name here. buildImageFromDockerfile sounds better

return nil
}

func (t *Task) runContainerFromTarBall(ctx *context.ExecuteContext) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildImageFromTar

@@ -135,25 +104,69 @@ func buildArgs(args map[string]string) []docker.BuildArg {
return out
}

func isDobi(t *Task) (bool) {
func (t *Task) hasContent() bool {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i dont think we need to check this t.config.Dockerfile == "Dockerfile"

config/image.go Outdated
if len(c.Content) == 0 && c.Dockerfile == "" {
return fmt.Errorf("dockerfile or content have to be present")
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have simplified this a little bit. Have I missed anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! A lot!

config/image.go Outdated
c.Dockerfile = "Dockerfile"
case c.Context == "" && c.Dockerfile != "":
case c.Context == "":
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is completly useless. fsouza does it automatically. If you pass a empty string it tries to build a Dockerfile anyway.

@cescoferraro cescoferraro mentioned this pull request Nov 5, 2016
"GLIDE": "{{ .GLIDE }}",
"GO-GET": "{{ .GOGET }}",
"GO-BIN": "{{.GOBIN}}",
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to hold off on adding any custom steps for the first version of this. This can potentially grow quite a bit. We would need some way to allow users to define these without having to add patches to dobi.

config/image.go Outdated
@@ -35,6 +35,9 @@ type ImageConfig struct {
// Dockerfile The path to the ``Dockerfile`` used to build the image. This
// path is relative to the **context**.
Dockerfile string
// Dobifile is a in house version of a dockerfile
// type: mapping ``[Valid Docker command]: value``
Steps []map[string]string
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, Steps sounds like a good name for this. The comment just needs to be updated.

"Steps Inline Dockerfile steps to use instead of a Dockerfile"

Copy link
Owner

@dnephin dnephin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is looking like it's on the right track.

This is already going to be a big change just using the existing steps, so I don't think we should add any custom ones yet.

config/image.go Outdated
return fmt.Errorf("is pull is set, you cannot specifie a dockerfile or a content")
}
case len(c.Steps) == 0 && c.Dockerfile == "":
return fmt.Errorf("use either a dockerfile or set you commands in the content")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"use either a dockerfile or steps"

config/image.go Outdated
return &conf, err
}
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure about the []map[string]string. It's true you get syntax highlighting, but not everyone uses that for yaml. It seems like a strange structure to store what is really a []string.

We could always add syntax highlighting later by creating a custom highlighter for dobi files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call me crazy, but I like colors. It's your call.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Syntax highlighting is definitely a nice feature, but I think having the correct data structure is more important. We can always improve syntax highlighting later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How are you planning to tell all editors to know about this?

return out
}

func (t *Task) hasContent() bool {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should be hasSteps() now

case true:
err = t.runContainerFromTarBall(ctx)
default:
err = t.runContainerFromDockerfile(ctx)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya I agree, these should be buildImageFrom...

ModTime: rightNow,
AccessTime: rightNow,
ChangeTime: rightNow,
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the problem. The tarball needs to contain all the files in the Context directory, not just the Dockerfile.

We should try to re-use some code from docker/docker for this, so that it honors the .dockerignore file correctly.

The content size should come from the tarball size, not the size of the steps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you point me to witch package 📦?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dnephin dnephin added this to the 0.9 milestone Nov 9, 2016
@cescoferraro cescoferraro mentioned this pull request Nov 10, 2016
@cescoferraro
Copy link
Contributor Author

This is still failing to write hidden files to the tarball

@cescoferraro cescoferraro changed the title dockerfile inside dobi is called dobifile Feature/steps embeeds a Dockerfile inside a image resource field Nov 25, 2016
@cescoferraro cescoferraro changed the title Feature/steps embeeds a Dockerfile inside a image resource field Feature/steps embeds a Dockerfile inside a image resource field Nov 25, 2016
@dnephin dnephin modified the milestones: 0.10, 0.9 Feb 1, 2017
@cescoferraro
Copy link
Contributor Author

@dnephin Can you take a look at this? Let me know if there is anything I improve upon.

@dnephin
Copy link
Owner

dnephin commented Apr 4, 2017

Yes, I'd like to get this merged, but I'm still not really liking the []map[string[string.

I'd like to use just a string, like this 8f0c5b3

I'm waiting for moby/moby#31236 to get merged, so that we can re-use a lot of the same code.

@cescoferraro
Copy link
Contributor Author

Cool, I think I have already fixed this

Steps []string

I will take a look a the upstream PR!

@dnephin
Copy link
Owner

dnephin commented Jun 5, 2017

Thank you again for starting this work! This is a really cool feature.

I opened #94 which includes your commits (squashed). I updated it to use the code from docker/cli for reading a dockerfile from stdin, and reading the dockerignore file.

@dnephin dnephin closed this Jun 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants