Skip to content

Commit da961f6

Browse files
committed
Remove the system procedure for dolt admin createchunk commit, make it work entirely at the filesystem level. This guarantees that an unauthenticated SQL user can't use the procedure to edit branches (whereas anyone with CLI access is assumed to already have filesystem (and thus admin) access anyway.)
1 parent 25c15cf commit da961f6

File tree

4 files changed

+72
-214
lines changed

4 files changed

+72
-214
lines changed

go/cmd/dolt/commands/admin/createchunk/createcommit.go

+71-15
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ package createchunk
1717
import (
1818
"bytes"
1919
"context"
20-
21-
"github.com/dolthub/go-mysql-server/sql"
22-
"github.com/gocraft/dbr/v2"
23-
"github.com/gocraft/dbr/v2/dialect"
20+
"errors"
2421

2522
"github.com/dolthub/dolt/go/cmd/dolt/cli"
2623
"github.com/dolthub/dolt/go/cmd/dolt/errhand"
24+
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
2725
"github.com/dolthub/dolt/go/libraries/doltcore/env"
26+
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
2827
"github.com/dolthub/dolt/go/libraries/utils/argparser"
28+
"github.com/dolthub/dolt/go/store/datas"
29+
"github.com/dolthub/dolt/go/store/hash"
2930
)
3031

3132
// CreateCommitCmd creates a new commit chunk, printing the new chunk's hash on success.
@@ -121,7 +122,7 @@ func (cmd CreateCommitCmd) ArgParser() *argparser.ArgParser {
121122
return cli.CreateCreateCommitParser()
122123
}
123124

124-
func (cmd CreateCommitCmd) Exec(ctx context.Context, commandStr string, args []string, _ *env.DoltEnv, cliCtx cli.CliContext) int {
125+
func (cmd CreateCommitCmd) Exec(ctx context.Context, commandStr string, args []string, dEnv *env.DoltEnv, cliCtx cli.CliContext) int {
125126
ap := cmd.ArgParser()
126127
usage, _ := cli.HelpAndUsagePrinters(cli.CommandDocsForCommandString(commandStr, cli.CommandDocumentationContent{}, ap))
127128

@@ -133,39 +134,94 @@ func (cmd CreateCommitCmd) Exec(ctx context.Context, commandStr string, args []s
133134
return 1
134135
}
135136

136-
queryist, sqlCtx, closeFunc, err := cliCtx.QueryEngine(ctx)
137-
if err != nil {
138-
cli.PrintErrln(errhand.VerboseErrorFromError(err))
137+
desc, _ := apr.GetValue("desc")
138+
root, _ := apr.GetValue("root")
139+
parents, _ := apr.GetValueList("parents")
140+
branch, isBranchSet := apr.GetValue(cli.BranchParam)
141+
force := apr.Contains(cli.ForceFlag)
142+
143+
var name, email string
144+
var err error
145+
if authorStr, ok := apr.GetValue(cli.AuthorParam); ok {
146+
name, email, err = cli.ParseAuthor(authorStr)
147+
if err != nil {
148+
cli.PrintErrln(errhand.VerboseErrorFromError(err))
149+
return 1
150+
}
151+
} else {
152+
name, email, err = env.GetNameAndEmail(cliCtx.Config())
153+
if err != nil {
154+
cli.PrintErrln(errhand.VerboseErrorFromError(err))
155+
return 1
156+
}
157+
}
158+
159+
db := dEnv.DbData(ctx).Ddb
160+
commitRootHash, ok := hash.MaybeParse(root)
161+
if !ok {
162+
cli.PrintErrf("invalid root value hash")
139163
return 1
140164
}
141-
if closeFunc != nil {
142-
defer closeFunc()
165+
166+
var parentCommits []hash.Hash
167+
for _, parent := range parents {
168+
commitSpec, err := doltdb.NewCommitSpec(parent)
169+
if err != nil {
170+
cli.PrintErrln(errhand.VerboseErrorFromError(err))
171+
return 1
172+
}
173+
174+
headRef := dEnv.RepoState.CWBHeadRef()
175+
176+
optionalCommit, err := db.Resolve(ctx, commitSpec, headRef)
177+
if err != nil {
178+
cli.PrintErrln(errhand.VerboseErrorFromError(err))
179+
return 1
180+
}
181+
parentCommits = append(parentCommits, optionalCommit.Addr)
143182
}
144183

145-
querySql, params, err := generateCreateCommitSQL(cliCtx, apr)
184+
commitMeta, err := datas.NewCommitMeta(name, email, desc)
146185
if err != nil {
147186
cli.PrintErrln(errhand.VerboseErrorFromError(err))
148187
return 1
149188
}
150-
interpolatedQuery, err := dbr.InterpolateForDialect(querySql, params, dialect.MySQL)
189+
190+
// This isn't technically an amend, but the Amend field controls whether the commit must be a child of the ref's current commit (if any)
191+
commitOpts := datas.CommitOptions{
192+
Parents: parentCommits,
193+
Meta: commitMeta,
194+
Amend: force,
195+
}
196+
197+
rootVal, err := db.ValueReadWriter().ReadValue(ctx, commitRootHash)
151198
if err != nil {
152199
cli.PrintErrln(errhand.VerboseErrorFromError(err))
153200
return 1
154201
}
155202

156-
_, rowIter, _, err := queryist.Query(sqlCtx, interpolatedQuery)
203+
var commit *doltdb.Commit
204+
if isBranchSet {
205+
commit, err = db.CommitValue(ctx, ref.NewBranchRef(branch), rootVal, commitOpts)
206+
if errors.Is(err, datas.ErrMergeNeeded) {
207+
cli.PrintErrf("branch %s already exists. If you wish to overwrite it, add the --force flag", branch)
208+
return 1
209+
}
210+
} else {
211+
commit, err = db.CommitDangling(ctx, rootVal, commitOpts)
212+
}
157213
if err != nil {
158214
cli.PrintErrln(errhand.VerboseErrorFromError(err))
159215
return 1
160216
}
161217

162-
rows, err := sql.RowIterToRows(sqlCtx, rowIter)
218+
commitHash, err := commit.HashOf()
163219
if err != nil {
164220
cli.PrintErrln(errhand.VerboseErrorFromError(err))
165221
return 1
166222
}
167223

168-
cli.Println(rows[0][0])
224+
cli.Println(commitHash.String())
169225

170226
return 0
171227
}

go/libraries/doltcore/sqle/dprocedures/admin/dolt_admin_createchunk_commit.go

-138
This file was deleted.

go/libraries/doltcore/sqle/dprocedures/init.go

-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ var DoltProcedures = []sql.ExternalStoredProcedureDetails{
5959
{Name: "dolt_stats_once", Schema: statsFuncSchema, Function: statsFunc(statsOnce)},
6060
{Name: "dolt_stats_gc", Schema: statsFuncSchema, Function: statsFunc(statsGc)},
6161
{Name: "dolt_stats_timers", Schema: statsFuncSchema, Function: statsFunc(statsTimers)},
62-
63-
{Name: "dolt_admin_createchunk_commit", Schema: stringSchema("hash"), Function: admin.CreateCommit},
6462
}
6563

6664
// stringSchema returns a non-nullable schema with all columns as LONGTEXT.

integration-tests/bats/createchunk.bats

+1-59
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ teardown() {
9898

9999
# but overwriting an existing branch with a different history is an error
100100
run dolt admin createchunk commit --root "$newRootValueHash" --desc "flattened history" --parents "$newCommitHash" --branch existingBranch
101+
echo "$output"
101102
[ "$status" -eq 1 ]
102103
[[ "$output" =~ "branch existingBranch already exists. If you wish to overwrite it, add the --force flag" ]] || false
103104

@@ -120,62 +121,3 @@ teardown() {
120121
[ "$status" -eq 1 ]
121122
[[ "$output" =~ "the --branch flag is required when creating a chunk using the CLI" ]] || false
122123
}
123-
124-
@test "createchunk: create commit in SQL on existing branch" {
125-
dolt branch existingBranch
126-
run dolt sql -q "CALL DOLT_ADMIN_CREATECHUNK_COMMIT('--root', '$newRootValueHash', '--author', 'a <b@c.com>', \
127-
'--desc', 'flattened history', '--parents', 'refs/internal/create', '--branch', 'existingBranch', '--force');" -r csv
128-
echo "$output"
129-
[ "$status" -eq 0 ]
130-
flattenedCommitHash=$(echo "$output" | tail -n 1)
131-
run dolt show existingBranch
132-
echo "$output"
133-
[ "$status" -eq 0 ]
134-
[[ "$output" =~ "Author: a <b@c.com>" ]] || false
135-
[[ "$output" =~ "flattened history" ]] || false
136-
[[ "$output" =~ "added table" ]] || false
137-
[[ "$output" =~ "| + | 1 |" ]] || false
138-
139-
# check that there are only two commits in the history
140-
run dolt log existingBranch
141-
[ "$status" -eq 0 ]
142-
[ "$(echo "$output" | grep -c commit)" -eq 2 ]
143-
[[ "$output" =~ "Initialize data repository" ]] || false
144-
[[ "$output" =~ "flattened history" ]] || false
145-
}
146-
147-
@test "createchunk: create commit in SQL on new branch" {
148-
flattenedCommitHash=$(dolt sql -q "CALL DOLT_ADMIN_CREATECHUNK_COMMIT('--root', '$newRootValueHash', '--author', 'a <b@c.com>', '--desc',\
149-
'flattened history', '--parents', 'refs/internal/create', '--branch', 'newBranch');" -r csv | tail -n 1)
150-
151-
run dolt show newBranch
152-
echo "$output"
153-
[ "$status" -eq 0 ]
154-
[[ "$output" =~ "Author: a <b@c.com>" ]] || false
155-
[[ "$output" =~ "flattened history" ]] || false
156-
[[ "$output" =~ "added table" ]] || false
157-
[[ "$output" =~ "| + | 1 |" ]] || false
158-
159-
# check that there are only two commits in the history
160-
run dolt log newBranch
161-
[ "$status" -eq 0 ]
162-
[ "$(echo "$output" | grep -c commit)" -eq 2 ]
163-
[[ "$output" =~ "Initialize data repository" ]] || false
164-
[[ "$output" =~ "flattened history" ]] || false
165-
}
166-
167-
@test "createchunk: create commit in SQL with no provided branch" {
168-
run dolt sql -r csv <<SQL
169-
CALL DOLT_ADMIN_CREATECHUNK_COMMIT('--root', '$newRootValueHash', '--author', 'a <b@c.com>', '--desc',
170-
'flattened history', '--parents', '$initialCommitHash', '--branch', 'newBranch');
171-
SELECT * from dolt_log;
172-
SQL
173-
[ "$status" -eq 0 ]
174-
# Just capture the last four lines (the select)
175-
run echo "$(echo "$output" | tail -n 4)"
176-
echo "$output"
177-
[[ "${lines[0]}" =~ "commit_hash,committer,email,date,message" ]] || false
178-
[[ "${lines[1]}" =~ "insert into table" ]] || false
179-
[[ "${lines[2]}" =~ "create table" ]] || false
180-
[[ "${lines[3]}" =~ "Initialize data repository" ]] || false
181-
}

0 commit comments

Comments
 (0)