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

Distgen - support for image generation #38

Merged
merged 2 commits into from
Feb 27, 2018
Merged

Conversation

dhodovsk
Copy link
Contributor

@dhodovsk dhodovsk commented Nov 21, 2017

This PR was created as reaction to suggestions in sclorg/postgresql-container#203. It should be an initial effort in using distgen in image repositories.

Notes:

  • The image repository that uses make distgen should contain:
    • specs/multispec.yml file
    • manifest.sh - lists of files to generate, files to copy (including desired mode) and list of symlinks
  • Results are stored in current directory when not specified in DESTDIR in manifest

distgen.sh Outdated
cd templates
OUTPUT_DIR=$(mktemp -d ${WORKDIR}/${OS}-${VERSION}-XXXX)
echo "Copying files to ${OUTPUT_DIR}:"
for file in ${FILES_TO_COPY}; do
Copy link
Contributor

Choose a reason for hiding this comment

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

I would really prefer having this solved properly through Makefile targets, so
everything is fully parallelized (even this cp && chmod thingy, but especially
the $FILES_TO_GEN bellow).

Thanks for the chmod call btw.! Could we made that "optional" with some sane
default (say 644)? Btw., this could solve #3 pretty nicely :-).

distgen.sh Outdated
# FILES_TO_GEN in form similar to FILES_TO_COPY
# INTERNAL_SYMLINKS in form "name1->target1 name1->target1..."
if [ -f "./dg_manifest" ]; then
source ./dg_manifest
Copy link
Contributor

Choose a reason for hiding this comment

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

Since manifest file is shell script, could we rename it to dg_manifest.sh (or rather remove the dg_ prefix, as that's not related to distgen) and generate some Makefile snippet from this automatically? The snippet could be then included.

I sort of miss the possibility to relocate the file (e.g you can not copy/symlink one source file onto two places), note that the quite old proposal here https://github.com/devexp-db/cont-postgresql/blob/master/cl-manifest allows this to be specified.

distgen.sh Outdated
# expecting file dg_manifest that contains variables:
# FILES_TO_COPY in form "path1:mode1 path2:mode2..."
# FILES_TO_GEN in form similar to FILES_TO_COPY
# INTERNAL_SYMLINKS in form "name1->target1 name1->target1..."
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit, but wouldn't be better to use colon as a separator, too?

distgen.sh Outdated

echo "Generating files:"
for file in ${FILES_TO_GEN}; do
split=(${file//:/ })
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not safe for spaces, better would be "old_IFS=$IFS ; IFS=: ; set -- $file; ... use $1/$2 ... IFS=$old_IFS.

distgen.sh Outdated
mode=${split[1]}

if [ ! -d $(dirname ${OUTPUT_DIR}/$path) ]; then
mkdir -p dirname ${OUTPUT_DIR}/$path
Copy link
Contributor

Choose a reason for hiding this comment

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

shell quotes missing

distgen.sh Outdated

# With max-passes > 1 is this directive non-effective
if grep "{%- raw %}" $path > /dev/null; then
max_passes=1
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate on this :-), I don't understand much what you try to achieve here.... The grep eats another fork, and is incomplete (one could use {% raw %} or {%- raw -%}).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Problem description:

  • some template files could contain some chars that are in fact jinja directives - e.g bash variable length vs. jinja comment - ${#myvar}
  • the directive {% raw %}/{% endraw %} fixes this problem, but the file can't be processed more than once
  • while using make distgen we don't know whether template needs to be processed multiple times or just once.

Possible solutions
1,Add max-passes to manifest in form

# path:max-passes:mode
./Dockerfile:2:644
./script.sh::755
  • with 1 as default - this could add complexity to UX

2, Expect jinja2.exceptions.TemplateSyntaxError - could be problem when there is an actual error

3, ... (please add your suggestion)

@praiskup @bkabrda what do you think?

Copy link

Choose a reason for hiding this comment

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

I actually already changed the mechanism of rerendering to not rerender the whole template, but just the spec values [1], which means this shouldn't be an issue going forward. I can do the release today and that would effectively make this problem go away, IIUC. @dhodovsk WDYT?

[1] devexp-db/distgen#63

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bkabrda I think it is great, would solve this issue nicely and also speed up the generation.

Copy link

Choose a reason for hiding this comment

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

I released distgen 0.20 which should fix this.

@praiskup
Copy link
Contributor

praiskup commented Dec 1, 2017

[test]

@dhodovsk dhodovsk force-pushed the distgen branch 3 times, most recently from dfa60ca to 38b12b8 Compare December 8, 2017 14:42
@dhodovsk
Copy link
Contributor Author

dhodovsk commented Dec 8, 2017

@praiskup After our discussion I changed a bit the desired look of manifest file, so it is more readable. Please, let me know if you think it is ok.
Example can be found here: https://github.com/dhodovsk/postgresql-container/blob/ecd036610006bf9af4b0878e145273bfee51a15d/manifest.sh

@hhorak
Copy link
Member

hhorak commented Jan 4, 2018

@praiskup I don't see any other issues with the current status, but I never paid big attention into this distgen, so I'll keep this to you.. WDYT?

@praiskup
Copy link
Contributor

praiskup commented Jan 4, 2018

IMO we got much more talkative version of the manifest file than originally proposed variant https://github.com/devexp-db/cont-postgresql/blob/master/cl-manifest, but I don't mind in particular - hopefully that manifest format can be attractive enough, and we don't know until we try that..

So more importantly - as this particular PR is just implementation detail - could we vote in sclorg/postgresql-container#203 whether the format is generally OK?

common.mk Outdated
else ifeq ($(TARGET),fedora)
OS := fedora
DOCKERFILE ?= Dockerfile.fedora
DG_CONF := fedora-26-x86_64.yaml
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Fedora 27 would be lovely as a start

@hhorak
Copy link
Member

hhorak commented Jan 17, 2018

I've taken a look again and found nothing suspicious. So, I'd say let's give it a try and see how it flies.

@dhodovsk
Copy link
Contributor Author

The implementation generates Dockerfile for desired TARGET without postfix. There has been requirement to generate Dockerfiles for all targets (Dockerfile, Dockerfile.rhel, Dockerfile.fedora) no matter what is in TARGET. That would also fix incorrect behaviour with two subsequent generations and change of target:

$ make generate TARGET=centos7 -> correctly generates centos7 Dockerfile
$ make generate TARGET=rhel7 -> doesn't do anything due to Dockerfile created in previous run (and no change in manifest or source files)

I postponed working on this due to change of priorities. In case of need I can change it back.

@praiskup
Copy link
Contributor

[test]

@pkubatrh
Copy link
Member

pkubatrh commented Jan 19, 2018

There has been requirement to generate Dockerfiles for all targets (Dockerfile, Dockerfile.rhel, Dockerfile.fedora) no matter what is in TARGET.

I say keep the functionality of generating only a single version of Dockerfile when TARGET is set. Adding a new makefile target (generate-all?) that creates all versions (TARGETs) available would be nice.

Both use cases still need the postfixed Dockerfiles though.

@pkubatrh
Copy link
Member

[test]

for version in ${VERSIONS}; do
# copy targets
rules="$COPY_RULES"
core="cp \$< \$@ ; \\"
Copy link
Contributor

Choose a reason for hiding this comment

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

So it won't be possible to copy directories?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@omron93 It is not possible now, one has to specify all files that are being generated.

@dhodovsk
Copy link
Contributor Author

@pkubatrh Can we expect that all files in directories except of Dockerfile are not affected by distribution change? When running generate-all for one version, one directory with all Dockerfiles would be present?

@omron93
Copy link
Contributor

omron93 commented Feb 14, 2018

Can we expect that all files in directories except of Dockerfile are not affected by distribution change? When running generate-all for one version, one directory with all Dockerfiles would be present?

README ?

@dhodovsk
Copy link
Contributor Author

@omron93 I am asking because AFAIK e.g for posgres there is one set of files for every version and they are os agnostic. Based on your reaction there are distro specific files. How do you handle these kinds of files, do you have specific directories for version and distro, e.g rhel-nginx-1.2?

@omron93
Copy link
Contributor

omron93 commented Feb 15, 2018

Based on your reaction there are distro specific files. How do you handle these kinds of files, do you have specific directories for version and distro, e.g rhel-nginx-1.2?

Name of the image is distro specific. So for examples in README could be distro specific...

Currently we don't do this. So rhel based names are used in examples... But it would be useful to be able to generate right names. But it is nothing which have to be implemented now.

@dhodovsk
Copy link
Contributor Author

So now the desired state is for example in postgres:

  • make generate VERSIONS=9.6 TARGET=rhel7 -> generates one directory: 9.6 with one Dockerfile, called Dockerfile.rhel (+ all other files)
  • make generate -> generates 3 directories and in each of them is one Dockerfile without postfix - since the target is default - centos
  • make generate-all VERSIONS=9.6 -> generates one directory containing Dockerfile, Dockerfile.rhel and Dockerfile.fedora

Is that correct, @omron93, @pkubatrh ?

@pkubatrh
Copy link
Member

Also make generate-all should generate directories for all versions containing all Dockerfiles.

It should be easy to configure which suffix each of the Dockerfiles will have. For example right now we are using rhel7 for our rhel images (since they are based on rhel7) but we might want to have a different extension for future rhel images.

@dhodovsk
Copy link
Contributor Author

Requested changes are now applied. What has been changed for image repository maintainer is that desired distro specific Dockerfile dest needs to be added to manifest.

Before:

...
DISTGEN_RULES="
    src=src/Dockerfile
    dest=Dockerfile;

    src=src/cccp.yml
    ...

After:

...
DISTGEN_RULES="
    src=src/Dockerfile
    dest=Dockerfile;

    src=src/Dockerfile
    dest=Dockerfile.rhel7;

    src=src/cccp.yml
    ...

The Dockerfile dest will be generated only when related TARGET is provided or by using generate-all.

@dhodovsk dhodovsk force-pushed the distgen branch 2 times, most recently from d9ded5b to 683bfec Compare February 20, 2018 15:09
@praiskup
Copy link
Contributor

[test]

@phracek
Copy link
Member

phracek commented Feb 22, 2018

thx, please merge it. CI will be setup by the other issue, so we do not block the issue.

common.mk Outdated
@@ -41,6 +44,7 @@ script_env = \
OPENSHIFT_NAMESPACES="$(OPENSHIFT_NAMESPACES)" \
CUSTOM_REPO="$(CUSTOM_REPO)"


Copy link
Member

Choose a reason for hiding this comment

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

Formatting change, just saying....

rm auto_targets.mk


auto_targets.mk: $(generator) $(MANIFEST_FILE)
Copy link
Member

Choose a reason for hiding this comment

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

Why this one has .mk at the end? Please forgive my ignorance...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Np, auto_targets.mk is generated makefile containing rules for all targets to be created.

Copy link
Member

Choose a reason for hiding this comment

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

In this case it's not referring the file though, right? Sure, it gets included, but where this is called from?

Copy link
Member

Choose a reason for hiding this comment

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

It is. gen depends on auto_targets.mk which in turn depends on generator.sh in which the actual file is generated.

@pkubatrh
Copy link
Member

Would it be possible to remove the auto_targets.mk file in case of a failure? Or maybe just clean it up inside make clean.

@dhodovsk
Copy link
Contributor Author

@pkubatrh ofc, on it :)

gen.mk Outdated
endif

generator = $(common_dir)/generate.sh
DISTGEN_BIN ?= /usr/bin/dg
Copy link
Member

Choose a reason for hiding this comment

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

Could you somewhere fail, or warn at least if user does not have this binary? Where does one install it from?

Copy link
Contributor

Choose a reason for hiding this comment

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

dnf install distgen :D

else ifeq ($(TARGET),fedora)
OS := fedora
DOCKERFILE ?= Dockerfile.fedora
DG_CONF := fedora-27-x86_64.yaml
Copy link
Member

Choose a reason for hiding this comment

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

Whe is there := when in other cases we use ?= ?
Same for rhel7.

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 are right, this should be consistent.

@pvalena
Copy link
Member

pvalena commented Feb 22, 2018

Otherwise LGTM :). Good job.

@dhodovsk
Copy link
Contributor Author

[test]

@TomasTomecek
Copy link
Contributor

Hm, tests are failing :/ is the failure related to this PR?

@pkubatrh
Copy link
Member

Hm, tests are failing :/ is the failure related to this PR?

Looks like the fail happens during checking for an expected failure, so does not seem related.

@pkubatrh
Copy link
Member

Actually, it does not fail on the expected failure but on make clean when it tests for the existence of the auto_targets.mk file ...

common.mk Outdated
@@ -79,9 +82,17 @@ tag: build

.PHONY: clean
clean:
test -f auto_targets.mk && rm auto_targets.mk
Copy link
Member

Choose a reason for hiding this comment

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

@dhodovsk Moving this line directly into the clean.sh script should get rid of the test failures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeas, sorry about that :)

@dhodovsk
Copy link
Contributor Author

[test]

@dhodovsk
Copy link
Contributor Author

[test]

@omron93
Copy link
Contributor

omron93 commented Feb 27, 2018

LGTM. Thanks for this PR.

@praiskup
Copy link
Contributor

Thanks!

@praiskup praiskup merged commit cef6837 into sclorg:master Feb 27, 2018
@TomasTomecek
Copy link
Contributor

Party!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants