diff --git a/VERSION-openeuler b/VERSION-openeuler index c55084d..33768ba 100644 --- a/VERSION-openeuler +++ b/VERSION-openeuler @@ -1 +1 @@ -0.9.4-5 +0.9.4-6 diff --git a/git-commit b/git-commit index 3c8070d..1df6c6c 100644 --- a/git-commit +++ b/git-commit @@ -1 +1 @@ -3959113b332bcbc4025c199faa385a18c1df4d30 +5d42104ebadef24b190e31f1a6ecf5ac549b42ab diff --git a/isula-build.spec b/isula-build.spec index 0331c59..a859880 100644 --- a/isula-build.spec +++ b/isula-build.spec @@ -2,7 +2,7 @@ Name: isula-build Version: 0.9.4 -Release: 5 +Release: 6 Summary: A tool to build container images License: Mulan PSL V2 URL: https://gitee.com/openeuler/isula-build @@ -41,19 +41,19 @@ sh ./apply-patches %install install -d %{buildroot}%{_bindir} # install binary -install -p -m 551 ./bin/isula-build %{buildroot}%{_bindir}/isula-build -install -p -m 550 ./bin/isula-builder %{buildroot}%{_bindir}/isula-builder +install -p ./bin/isula-build %{buildroot}%{_bindir}/isula-build +install -p ./bin/isula-builder %{buildroot}%{_bindir}/isula-builder # install service %if 0%{?is_systemd} install -d %{buildroot}%{_unitdir} -install -p -m 640 isula-build.service %{buildroot}%{_unitdir}/isula-build.service +install -p isula-build.service %{buildroot}%{_unitdir}/isula-build.service %endif # install config file -install -d -m 750 %{buildroot}%{_sysconfdir}/isula-build -install -p -m 600 ./cmd/daemon/config/configuration.toml %{buildroot}%{_sysconfdir}/isula-build/configuration.toml -install -p -m 600 ./cmd/daemon/config/storage.toml %{buildroot}%{_sysconfdir}/isula-build/storage.toml -install -p -m 600 ./cmd/daemon/config/registries.toml %{buildroot}%{_sysconfdir}/isula-build/registries.toml -install -p -m 400 ./cmd/daemon/config/policy.json %{buildroot}%{_sysconfdir}/isula-build/policy.json +install -d %{buildroot}%{_sysconfdir}/isula-build +install -p ./cmd/daemon/config/configuration.toml %{buildroot}%{_sysconfdir}/isula-build/configuration.toml +install -p ./cmd/daemon/config/storage.toml %{buildroot}%{_sysconfdir}/isula-build/storage.toml +install -p ./cmd/daemon/config/registries.toml %{buildroot}%{_sysconfdir}/isula-build/registries.toml +install -p ./cmd/daemon/config/policy.json %{buildroot}%{_sysconfdir}/isula-build/policy.json # install bash completion script install -d %{buildroot}/usr/share/bash-completion/completions install -p -m 600 __isula-build %{buildroot}/usr/share/bash-completion/completions/isula-build @@ -74,6 +74,8 @@ fi %endif %attr(551,root,root) %{_bindir}/isula-build %attr(550,root,root) %{_bindir}/isula-builder + +%dir %attr(650,root,root) %{_sysconfdir}/isula-build %config(noreplace) %attr(0600,root,root) %{_sysconfdir}/isula-build/configuration.toml %config(noreplace) %attr(0600,root,root) %{_sysconfdir}/isula-build/storage.toml %config(noreplace) %attr(0600,root,root) %{_sysconfdir}/isula-build/registries.toml @@ -81,6 +83,9 @@ fi /usr/share/bash-completion/completions/isula-build %changelog +* Thu Nov 19 2020 lixiang - 0.9.4-6 +- Support build Dockerfile only have FROM command + * Wed Nov 18 2020 lixiang - 0.9.4-5 - Delete patches no longer usefull diff --git a/patch/0068-isula-build-support-build-Dockerfile-only-have-FROM-.patch b/patch/0068-isula-build-support-build-Dockerfile-only-have-FROM-.patch new file mode 100644 index 0000000..ddd629b --- /dev/null +++ b/patch/0068-isula-build-support-build-Dockerfile-only-have-FROM-.patch @@ -0,0 +1,283 @@ +From 923ec55b36f0d3ec0065dc525e6a579b7b048663 Mon Sep 17 00:00:00 2001 +From: zvier +Date: Wed, 18 Nov 2020 14:56:08 +0800 +Subject: [PATCH] isula-build: support build Dockerfile only have FROM command + +Signed-off-by: liuzekun +--- + Makefile | 2 +- + builder/dockerfile/builder_test.go | 16 ++++----- + builder/dockerfile/cmd_builder.go | 1 + + builder/dockerfile/cmd_builder_test.go | 41 ++++++++++++------------ + builder/dockerfile/parser/parser.go | 8 ----- + builder/dockerfile/parser/parser_test.go | 2 -- + builder/dockerfile/stage_builder.go | 2 -- + 7 files changed, 31 insertions(+), 41 deletions(-) + +diff --git a/Makefile b/Makefile +index 11166cc2..7e268678 100644 +--- a/Makefile ++++ b/Makefile +@@ -97,7 +97,7 @@ proto: + install: + install -D -m0551 bin/isula-build $(BINDIR) + install -D -m0550 bin/isula-builder $(BINDIR) +- @[ ! -d ${CONFIG_DIR}/${CONFIG_FILE} ] && install -dm0640 ${CONFIG_DIR} ++ @[ ! -d ${CONFIG_DIR}/${CONFIG_FILE} ] && install -dm0650 ${CONFIG_DIR} + @( [ -f ${CONFIG_DIR}/${CONFIG_FILE} ] && printf "%-20s %s\n" "${CONFIG_FILE}" "already exist in ${CONFIG_DIR}, please replace it manually." ) || install -D -m0600 ${LOCAL_CONF_PREFIX}/${CONFIG_FILE} ${CONFIG_DIR}/${CONFIG_FILE} + @( [ -f ${CONFIG_DIR}/${POLICY_FILE} ] && printf "%-20s %s\n" "${POLICY_FILE}" "already exist in ${CONFIG_DIR}, please replace it manually." ) || install -D -m0600 ${LOCAL_CONF_PREFIX}/${POLICY_FILE} ${CONFIG_DIR}/${POLICY_FILE} + @( [ -f ${CONFIG_DIR}/${REGIST_FILE} ] && printf "%-20s %s\n" "${REGIST_FILE}" "already exist in ${CONFIG_DIR}, please replace it manually." ) || install -D -m0600 ${LOCAL_CONF_PREFIX}/${REGIST_FILE} ${CONFIG_DIR}/${REGIST_FILE} +diff --git a/builder/dockerfile/builder_test.go b/builder/dockerfile/builder_test.go +index 94842c71..b02768ea 100644 +--- a/builder/dockerfile/builder_test.go ++++ b/builder/dockerfile/builder_test.go +@@ -248,13 +248,13 @@ RUN ls + } + + // check the arg and env taken by the command: RUN ls +- assert.DeepEqual(t, b.stageBuilders[0].commands[0].args, ++ assert.DeepEqual(t, b.stageBuilders[0].commands[1].args, + map[string]string{"no_proxy": "10.0.0.0"}) +- assert.DeepEqual(t, b.stageBuilders[1].commands[1].args, ++ assert.DeepEqual(t, b.stageBuilders[1].commands[2].args, + map[string]string{"testArg": "0.1", "no_proxy": "10.0.0.0"}) +- assert.DeepEqual(t, b.stageBuilders[2].commands[2].args, ++ assert.DeepEqual(t, b.stageBuilders[2].commands[3].args, + map[string]string{"no_proxy": "10.0.0.0"}) +- assert.DeepEqual(t, b.stageBuilders[2].commands[2].envs, ++ assert.DeepEqual(t, b.stageBuilders[2].commands[3].envs, + map[string]string{"testArg": "1.0"}) + } + +@@ -291,13 +291,13 @@ RUN ls + } + + // check the arg and env taken by the command: RUN ls +- assert.DeepEqual(t, b.stageBuilders[0].commands[0].args, ++ assert.DeepEqual(t, b.stageBuilders[0].commands[1].args, + map[string]string{"HTTPS_PROXY": "127.0.0.1"}) +- assert.DeepEqual(t, b.stageBuilders[1].commands[1].args, ++ assert.DeepEqual(t, b.stageBuilders[1].commands[2].args, + map[string]string{"testArg": "0.1", "HTTPS_PROXY": "127.0.0.1"}) +- assert.DeepEqual(t, b.stageBuilders[2].commands[2].args, ++ assert.DeepEqual(t, b.stageBuilders[2].commands[3].args, + map[string]string{"HTTPS_PROXY": "127.0.0.1"}) +- assert.DeepEqual(t, b.stageBuilders[2].commands[2].envs, ++ assert.DeepEqual(t, b.stageBuilders[2].commands[3].envs, + map[string]string{"testArg": "1.0"}) + } + +diff --git a/builder/dockerfile/cmd_builder.go b/builder/dockerfile/cmd_builder.go +index 65ae364d..8b0d5ab9 100644 +--- a/builder/dockerfile/cmd_builder.go ++++ b/builder/dockerfile/cmd_builder.go +@@ -39,6 +39,7 @@ var ( + + func init() { + cmdExecutors = map[string]func(cb *cmdBuilder) error{ ++ dockerfile.From: executeNoop, + dockerfile.Add: executeAdd, + dockerfile.Arg: executeNoop, + dockerfile.Copy: executeCopy, +diff --git a/builder/dockerfile/cmd_builder_test.go b/builder/dockerfile/cmd_builder_test.go +index 471314ba..df1c08f9 100644 +--- a/builder/dockerfile/cmd_builder_test.go ++++ b/builder/dockerfile/cmd_builder_test.go +@@ -113,7 +113,7 @@ func TestExecuteHealthCheck(t *testing.T) { + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); (err != nil) != tt.wantErr { ++ if err := s.commands[1].cmdExecutor(); (err != nil) != tt.wantErr { + t.Errorf("CmdExecutor() error: %v, wantErr: %v", err, tt.wantErr) + } + tt.funcCheck(t, s) +@@ -195,7 +195,7 @@ CMD [""]`, + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); (err != nil) != tt.wantErr { ++ if err := s.commands[1].cmdExecutor(); (err != nil) != tt.wantErr { + t.Errorf("cmdExecutor() error: %v, wantErr: %v", err, tt.wantErr) + } + tt.funcCheck(t, s) +@@ -288,7 +288,7 @@ SHELL ["/bin/bash", "-c"]`, + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); (err != nil) != tt.wantErr { ++ if err := s.commands[1].cmdExecutor(); (err != nil) != tt.wantErr { + t.Errorf("SHELL cmdExecutor() error: %v, wantErr: %v", err, tt.wantErr) + } + tt.funcCheck(t, s) +@@ -316,15 +316,15 @@ CMD ls` + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) + +- if err := s.commands[0].cmdExecutor(); err != nil { ++ if err := s.commands[1].cmdExecutor(); err != nil { + t.Errorf("CMD cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.Cmd, strslice.StrSlice{"/bin/sh", "-c", "ls"}) + +- if err := s.commands[1].cmdExecutor(); err != nil { ++ if err := s.commands[2].cmdExecutor(); err != nil { + t.Errorf("SHELL cmdExecutor() error: %v", err) + } +- if err := s.commands[2].cmdExecutor(); err != nil { ++ if err := s.commands[3].cmdExecutor(); err != nil { + t.Errorf("CMD cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.shellForm, strslice.StrSlice{"/bin/bash", "-c"}) +@@ -360,9 +360,10 @@ func TestExecuteNoop(t *testing.T) { + + // the "STEP 1: FROM alpine" in production is done at stageBuilder.prepare() + // no cmdExecutor for FROM, so no print for FROM here +- expectedString := `STEP 1: ARG testArg +-STEP 2: ENV env1=env2 +-STEP 3: ONBUILD CMD ls ++ expectedString := `STEP 1: FROM alpine ++STEP 2: ARG testArg ++STEP 3: ENV env1=env2 ++STEP 4: ONBUILD CMD ls + ` + assert.Equal(t, stepPrints, expectedString) + } +@@ -441,7 +442,7 @@ ENTRYPOINT [""]`, + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); (err != nil) != tt.wantErr { ++ if err := s.commands[1].cmdExecutor(); (err != nil) != tt.wantErr { + t.Errorf("cmdExecutor() error: %v, wantErr: %v", err, tt.wantErr) + } + tt.funcCheck(t, s) +@@ -903,15 +904,15 @@ WORKDIR /c` + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); err != nil { ++ if err := s.commands[1].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/a") +- if err := s.commands[1].cmdExecutor(); err != nil { ++ if err := s.commands[2].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/b") +- if err := s.commands[2].cmdExecutor(); err != nil { ++ if err := s.commands[3].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/c") +@@ -938,15 +939,15 @@ WORKDIR c` + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); err != nil { ++ if err := s.commands[1].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/a") +- if err := s.commands[1].cmdExecutor(); err != nil { ++ if err := s.commands[2].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/a/b") +- if err := s.commands[2].cmdExecutor(); err != nil { ++ if err := s.commands[3].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.DeepEqual(t, s.docker.Config.WorkingDir, "/a/b/c") +@@ -973,15 +974,15 @@ WORKDIR $DIRPATH/$DIRNAME` + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err = s.commands[0].cmdExecutor(); err != nil { ++ if err = s.commands[1].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.NilError(t, err) +- if err = s.commands[1].cmdExecutor(); err != nil { ++ if err = s.commands[2].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.NilError(t, err) +- if err = s.commands[2].cmdExecutor(); err != nil { ++ if err = s.commands[3].cmdExecutor(); err != nil { + t.Errorf("WORKDIR cmdExecutor() error: %v", err) + } + assert.NilError(t, err) +@@ -1025,7 +1026,7 @@ Maintainer iSula iSula@huawei.com`, + } + err := s.analyzeStage(context.Background()) + assert.NilError(t, err) +- if err := s.commands[0].cmdExecutor(); (err != nil) != tt.wantErr { ++ if err := s.commands[1].cmdExecutor(); (err != nil) != tt.wantErr { + t.Errorf("cmdExecutor() error: %v, wantErr: %v", err, tt.wantErr) + } + tt.funcCheck(t, s) +diff --git a/builder/dockerfile/parser/parser.go b/builder/dockerfile/parser/parser.go +index e8711fe7..82835e67 100644 +--- a/builder/dockerfile/parser/parser.go ++++ b/builder/dockerfile/parser/parser.go +@@ -196,8 +196,6 @@ func constructPages(lines []*parser.Line, onbuild bool) ([]*parser.Page, error) + currentPage *parser.Page + pageNum int + ) +- // a stage should have at least one FROM and one command +- const minLinesPerPage = 2 + + for _, line := range lines { + if line == nil { +@@ -215,9 +213,6 @@ func constructPages(lines []*parser.Line, onbuild bool) ([]*parser.Page, error) + return nil, errors.New("onbuild does not support the from command") + } + if currentPage != nil { +- if !onbuild && len(currentPage.Lines) < minLinesPerPage { +- return nil, errors.Errorf("stage %s should have at least one command", currentPage.Name) +- } + pages = append(pages, currentPage) + } + +@@ -254,9 +249,6 @@ func constructPages(lines []*parser.Line, onbuild bool) ([]*parser.Page, error) + currentPage.End = line.End + currentPage.AddLine(line) + } +- if !onbuild && len(currentPage.Lines) < minLinesPerPage { +- return nil, errors.Errorf("stage %s should have at least one command", currentPage.Name) +- } + // the last stage always need to commit + currentPage.NeedCommit = true + pages = append(pages, currentPage) +diff --git a/builder/dockerfile/parser/parser_test.go b/builder/dockerfile/parser/parser_test.go +index 34b1a61c..fe27dd95 100644 +--- a/builder/dockerfile/parser/parser_test.go ++++ b/builder/dockerfile/parser/parser_test.go +@@ -180,8 +180,6 @@ func TestParse(t *testing.T) { + }, + { + name: "busybox_no_command", +- isErr: true, +- errStr: "stage 1 should have at least one command", + }, + { + name: "env_before_from", +diff --git a/builder/dockerfile/stage_builder.go b/builder/dockerfile/stage_builder.go +index 7c928e34..47f55bf1 100644 +--- a/builder/dockerfile/stage_builder.go ++++ b/builder/dockerfile/stage_builder.go +@@ -172,9 +172,7 @@ func (s *stageBuilder) analyzeStage(ctx context.Context) error { + cb := newCmdBuilder(ctx, line, s, stageArgs, stageEnvs) + + switch line.Command { +- // From cmd is already pre-processed, we just pass it + case dockerfile.From: +- continue + case dockerfile.Arg: + if cb.args, err = analyzeArg(s.builder, line, stageArgs, stageEnvs); err != nil { + return err +-- +2.19.1 + diff --git a/series.conf b/series.conf index 2d907ad..05a1e17 100644 --- a/series.conf +++ b/series.conf @@ -11,3 +11,4 @@ patch/0037-isula-build-fix-goroutine-leak-problem.patch patch/0065-fix-panic-when-user-knock-ctrl-c-when-pull-push-and-.patch patch/0066-bugfix-chown-config-root-path-before-daemon-started.patch patch/0067-bugfix-fix-unsuitable-filemode-for-isula-build-er.patch +patch/0068-isula-build-support-build-Dockerfile-only-have-FROM-.patch