docker源码修改工作总结

话不多说上干货:

一、安装mysql数据库,并且建立相关表

在本地主机上安装mysql数据库,并且建立一个名为docker的数据库,在数据库中建立两个数据表分别为container_auto和container_user,分别代表自动生成的秘钥和用户自己输入的秘钥,两个表的字段都为id和passphrase,如下

mysql> create table container_auto(
> id char(20) not null primary key,
> passphrase char(40) not null);

 container_user和container_auto结构一样

二、搭建docker编译环境

搭建教程,并在/go/src/github.com/docker/docker下修改源码,最后编译

docker源码修改工作总结_第1张图片

三、修改源码

在/go/src/github.com/docker/docker修改

mkdir crypt

vi crypt/mysql.go

package crypt

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

func InsertUser(id string, passphrase string) {
	db, err := sql.Open("mysql", "root:zhang@tcp(127.0.0.1:3306)/docker?charset=utf8")
	checkErr(err)
	stmt, err := db.Prepare(`INSERT container_user (id,passphrase) values (?,?)`)
	checkErr(err)
	_, err = stmt.Exec(id, passphrase)
	checkErr(err)
}

func InsertAuto(id string, passphrase string) {
	db, err := sql.Open("mysql", "root:zhang@tcp(127.0.0.1:3306)/docker?charset=utf8")
	checkErr(err)
	stmt, err := db.Prepare(`INSERT container_auto (id,passphrase) values (?,?)`)
	checkErr(err)
	_, err = stmt.Exec(id, passphrase)
	checkErr(err)
}

func Remove(id string) {
	db, err := sql.Open("mysql", "root:zhang@tcp(127.0.0.1:3306)/docker?charset=utf8")
	checkErr(err)
	stmt_auto, err := db.Prepare(`DELETE FROM container_auto WHERE id=?`)
	checkErr(err)
	_, err = stmt_auto.Exec(id)
	checkErr(err)
	stmt_user, err := db.Prepare(`DELETE FROM container_user WHERE id=?`)
	checkErr(err)
	_, err = stmt_user.Exec(id)
	checkErr(err)
}

func QueryUser(id string) string {
	db, err := sql.Open("mysql", "root:zhang@tcp(127.0.0.1:3306)/docker?charset=utf8")
	checkErr(err)
	var password string
	rows, err := db.Query(`SELECT passphrase FROM container_user WHERE id=?`, id)
	checkErr(err)
	for rows.Next() {
		err := rows.Scan(&password)
		checkErr(err)
	}
	return password
}

func QueryAuto(id string) string {
	db, err := sql.Open("mysql", "root:zhang@tcp(127.0.0.1:3306)/docker?charset=utf8")
	checkErr(err)
	var password string
	rows, err := db.Query(`SELECT passphrase FROM container_auto WHERE id=?`, id)
	checkErr(err)
	for rows.Next() {
		err := rows.Scan(&password)
		checkErr(err)
	}
	return password
}

func checkErr(err error) {
	if err != nil {
		panic(err)
	}
}

vi crypt/crypt.go

package crypt

import (
	"math/rand"
	"time"
)

func init() {
	rand.Seed(time.Now().UnixNano())
}

func RandStringBytes(n int) string {

	const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}

func SubstrId(str string) string {
	return string([]byte(str)[:12])
}

/*func SetCrypt() string {
	var password, verify_password string

	for {
		fmt.Println("Enter passphrase:")
		fmt.Scanln(&password)
		fmt.Println("Verify passphrase:")
		fmt.Scanln(&verify_password)
		if password == verify_password {
			fmt.Println("Success!")
			return password
		} else {
			fmt.Println("The passwords do not match,please enter angin!")
		}
	}
}*/

/*
func SelectMode(id string) {
	var num string
	for {
		fmt.Println("Please select mode,enter the number:")
		fmt.Println("1.User input mode")
		fmt.Println("2.Automatic generation")
		fmt.Scanln(&num)
		if num == "1" || num == "2" {
			break
		} else {
			fmt.Println("Enter error,please enter the number!")
		}
	}
	switch num {
	case "1":
		fmt.Println("Welcome user input mode!")
		InsertMysql(SubstrId(id), SetCrypt())
	case "2":
		fmt.Println("Welcome automatic generation mode!")
		InsertMysql(SubstrId(id), RandStringBytes(12))
	}
}

func Test() {
	fmt.Println("this is a test")
}
*/

vi cli/command/container/run.go

12
"github.com/docker/docker/crypt"
32
crypt string
61
flags.StringVar(&opts.crypt,"crypt","","Set a password for your docker storage encryption")
146
if opts.crypt != "" {
    crypt.InsertUser(crypt.SubstrId(createResponse.ID), opts.crypt)
}else{
    crypt.InsertAuto(crypt.SubstrId(createResponse.ID), crypt.RandStringBytes(12))
}

vi cli/command/container/rm.go

6
"github.com/docker/docker/crypt"
53 	
for _, container := range opts.containers {
	password_user:=crypt.QueryUser(crypt.SubstrId(container))
	password_auto:=crypt.QueryAuto(crypt.SubstrId(container))
	if password_auto == "" && password_user == ""{
           return errors.New("Please use the container id instead of the container name")
    }
}

vi client/container_remove.go

6 		
"github.com/docker/docker/crypt"
27 		
crypt.Remove(containerID)

vi cli/command/container/start.go

11		
"github.com/docker/docker/crypt"
25		
crypt string
52		
flags.StringVar(&opts.crypt,"crypt","","Start your container need your password")
73		
password_user:=crypt.QueryUser(crypt.SubstrId(container))	
password_auto:=crypt.QueryAuto(crypt.SubstrId(container))
if password_auto == "" && password_user == ""{
    return errors.New("Please use the container id instead of the container name")
        }
if opts.crypt == "" && opts.crypt != password_user{
	return errors.New("You should enter the password you used to set")
}else if opts.crypt != "" && opts.crypt != password_user{
	return errors.New("Your password is wrong")
}
172
for _,container := range opts.containers{
    password_user:=crypt.QueryUser(crypt.SubstrId(container))
    password_auto:=crypt.QueryAuto(crypt.SubstrId(container))
    if password_auto == "" && password_user == ""{
        return errors.New("Please use the container id instead of the container name")
    }
    if opts.crypt == "" && opts.crypt != password_user{
        return errors.New("You should enter the password you used to set")
    }else if opts.crypt != "" && opts.crypt != password_user{
        return errors.New("Your password is wrong")
    }
}

vi cli/command/container/restart.go

9 		
"github.com/docker/docker/crypt"
18 		
crypt string
39			
flags.StringVar(&opts.crypt,"crypt","","Start your container need your password")
53	     
for _,name := range opts.containers {
    password_user:=crypt.QueryUser(crypt.SubstrId(name))
    password_auto:=crypt.QueryAuto(crypt.SubstrId(name))
    if password_auto == "" && password_user == ""{
        return errors.New("Please use the container id instead of the container name")
    }
    if opts.crypt == "" && opts.crypt != password_user{
        return errors.New("You should enter the password you used to set")
    }else if opts.crypt != "" && opts.crypt != password_user{
        return errors.New("Your password is wrong")
    }
}

四、缺陷

增加了对docker run,docker start,docker restart,docker rm的修改,但是所有都是对于容器id操作,缘由是数据库的字段是id,不能对容器name进行操作,观察容器name的代码比较复杂,没有深入修改,望后期能健全

你可能感兴趣的:(云)