Centos7安装docker-ce docker-compose

安装依赖

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

添加源

 yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

安装

yum install docker-ce

启用&启动

systemctl enable docker
systemctl daemon-reload
systemctl start docker

安装docker-compose

curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

chmod +x /usr/local/bin/docker-compose

添加国内镜像

vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"]
}
systemctl restart docker

Centos6升级7

今天来升级一个centos6.X 到 centos7
先添加源

vim /etc/yum.repos.d/upgrade.repo
[upgrade]  
name=upgrade  
baseurl=http://dev.centos.org/centos/6/upg/x86_64/  
enable=1  
gpgcheck=0 

网上的些文章会直接进行升级,遇到报错如下

Assessment finished (time 05:57s)
I/O warning : failed to load external entity "/usr/share/openscap/xsl/security-guide.xsl"
compilation error: file /usr/share/preupgrade/xsl/preup.xsl line 40 element import
xsl:import : unable to load /usr/share/openscap/xsl/security-guide.xsl
I/O warning : failed to load external entity "/usr/share/openscap/xsl/oval-report.xsl"
compilation error: file /usr/share/preupgrade/xsl/preup.xsl line 41 element import
xsl:import : unable to load /usr/share/openscap/xsl/oval-report.xsl
I/O warning : failed to load external entity "/usr/share/openscap/xsl/sce-report.xsl"
compilation error: file /usr/share/preupgrade/xsl/preup.xsl line 42 element import
xsl:import : unable to load /usr/share/openscap/xsl/sce-report.xsl
OpenSCAP Error:: Could not parse XSLT file '/usr/share/preupgrade/xsl/preup.xsl' [oscapxml.c:416]
Unable to open file /root/preupgrade/result.html
Usage: preupg [options]

preupg: error: [Errno 2] No such file or directory: '/root/preupgrade/result.html'

解决方法,先执行下面命令

yum erase openscap
yum install http://dev.centos.org/centos/6/upg/x86_64/Packages/openscap-1.0.8-1.0.1.el6.centos.x86_64.rpm
yum -y install redhat-upgrade-tool preupgrade-assistant-contents

再进行升级。

yum -y install preupgrade-assistant-contents redhat-upgrade-tool preupgrade-assistant 
preupg -l
preupg -s CentOS6_7

这里官方源7最新版本,好像升级不成功,使用官方备份源的旧版本,然后执行升级!

centos-upgrade-tool-cli --network 7 --instrepo=http://vault.centos.org/centos/7.2.1511/os/x86_64/

接下来就是等着了

Jenkins+Gitlab Webhook触发构建获取参数

可以在Gitlab编辑webhook界面看到test请求的详情和返回输出。
至于在jenkins的shell脚本中也可以取到这些变量。

echo $gitlabSourceRepoURL
echo $gitlabAfter
echo $gitlabTargetBranch
echo $gitlabSourceRepoHttpUrl
echo $gitlabMergeRequestLastCommit
echo $gitlabSourceRepoSshUrl
echo $gitlabSourceRepoHomepage
echo $gitlabBranch
echo $gitlabSourceBranch
echo $gitlabUserEmail
echo $gitlabBefore
echo $gitlabSourceRepoName
echo $gitlabSourceNamespace
echo $gitlabUserName

sync.Pool go对象池

一个sync.Pool对象就是一组临时对象的集合。Pool是协程安全的。
Pool用于存储那些被分配了但是没有被使用,而未来可能会使用的值,以减小垃圾回收的压力。一个比较好的例子是fmt包,fmt包总是需要使用一些[]byte之类的对象,golang建立了一个临时对象池,存放着这些对象,如果需要使用一个[]byte,就去Pool里面拿,如果拿不到就分配一份。
这比起不停生成新的[]byte,用完了再等待gc回收来要高效得多。
继续阅读sync.Pool go对象池

Go Sync包详解


package main;
 
import (
    "fmt"
    "sync"
    "runtime"
    "time"
)
 
//加锁,注意锁要以指针的形式传进来,不然只是拷贝
func total1(num *int, mu *sync.Mutex, ch chan bool) {
    mu.Lock();
    for i := 0; i < 1000; i++ {
        *num += i;
    }
    ch <- true;
    mu.Unlock();
}
 
//不加锁
func total2(num *int, ch chan bool) {
    for i := 0; i < 1000; i++ {
        *num += i;
    }
    ch <- true;
}
 
//Lock、Unlock与RLock、RUnlock不能嵌套使用
func total3(num *int, rwmu *sync.RWMutex, ch chan bool) {
    for i := 0; i < 1000; i++ {
        rwmu.Lock();
        *num += i;
        rwmu.Unlock();
 
        if(i == 500) {
            //读锁定
            rwmu.RLock();
            fmt.Print(*num, " ");
            rwmu.RUnlock();
        }
    }
    ch <- true;
}
 
func printNum(num int, cond *sync.Cond) {
    cond.L.Lock();
    if num < 5 {
        //num小于5时,进入等待状态
        cond.Wait();
    }
    //大于5的正常输出
    fmt.Println(num);
    cond.L.Unlock();
}
 
func main() {
    //Once.Do()保证多次调用只执行一次
    once := sync.Once{};
    ch := make(chan bool, 3);
    for i := 0; i < 3; i++ {
        go func(n int) {
            once.Do(func() {
                //只会执行一次,因为闭包引用了变量n,最后的值为2
                fmt.Println(n)
            });
            //给chan发送true,表示执行完成
            ch <- true;
        }(i);
    }
    for i := 0; i < 3; i++ {
        //读取三次chan,如果上面三次没执行完会一直阻塞
        <-ch;
    }
 
    //互斥锁,保证某一时刻只能有一个访问对象
    mutex := sync.Mutex{};
    ch2 := make(chan bool, 20);
    //使用多核,不然下面的结果会一样
    runtime.GOMAXPROCS(runtime.NumCPU());
    num1 := 0;
    num2 := 0;
    for i := 0; i < 10; i++ {
        go total1(&num1, &mutex, ch2);
    }
    for i := 0; i < 10; i++ {
        go total2(&num2, ch2);
    }
    for i := 0; i < 20; i++ {
        <-ch2;
    }
    //会发现num1与num2计算出的结果不一样
    //而num1的结果才是正确的,因为total2没有加锁,导致多个goroutine操作num时发生数据混乱
    fmt.Println(num1, num2);
 
    //读写锁,多了读锁定,和读解锁,让多个goroutine同时读取对象
    rwmutex := sync.RWMutex{};
    ch3 := make(chan bool, 10);
    num3 := 0;
    for i := 0; i < 10; i++ {
        go total3(&num3, &rwmutex, ch3);
    }
    for i := 0; i < 10; i++ {
        <-ch3;
    }
    fmt.Println(num3);
 
    //组等待,等待一组goroutine的结束
    wg := sync.WaitGroup{};
    //增加计数器
    wg.Add(10);
    for i:= 0; i< 10; i++ {
        go func(n int) {
            fmt.Print(n, " ");
            //这里表示该goroutine执行完成
            wg.Done();
        }(i);
    }
    //等待所有线程执行完成
    wg.Wait();
 
    fmt.Println("");
 
    //条件等待
    mutex2 := sync.Mutex{};
    //使用锁创建一个条件等待
    cond := sync.NewCond(&mutex2);
 
    for i := 0; i < 10; i++ {
        go printNum(i, cond);
    }
 
    time.Sleep(time.Second * 1);
    //等待一秒后,我们先唤醒一个等待,输出一个数字
    cond.L.Lock()
    cond.Signal();
    cond.L.Unlock();
    time.Sleep(time.Second * 1);
    //再次待待一秒后,唤醒所有,输出余下四个数字
    cond.L.Lock()
    cond.Broadcast();
    cond.L.Unlock();
    time.Sleep(time.Second * 1);
}